1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2006 by Nicholas Bishop
17 * All rights reserved.
18 * Implements the Sculpt Mode tools
19 */
20
21 /** \file
22 * \ingroup edsculpt
23 */
24
25 #include "MEM_guardedalloc.h"
26
27 #include "BLI_blenlib.h"
28 #include "BLI_dial_2d.h"
29 #include "BLI_ghash.h"
30 #include "BLI_gsqueue.h"
31 #include "BLI_hash.h"
32 #include "BLI_math.h"
33 #include "BLI_math_color_blend.h"
34 #include "BLI_task.h"
35 #include "BLI_utildefines.h"
36
37 #include "BLT_translation.h"
38
39 #include "PIL_time.h"
40
41 #include "DNA_brush_types.h"
42 #include "DNA_customdata_types.h"
43 #include "DNA_mesh_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_node_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_scene_types.h"
48
49 #include "BKE_brush.h"
50 #include "BKE_ccg.h"
51 #include "BKE_colortools.h"
52 #include "BKE_context.h"
53 #include "BKE_image.h"
54 #include "BKE_kelvinlet.h"
55 #include "BKE_key.h"
56 #include "BKE_lib_id.h"
57 #include "BKE_main.h"
58 #include "BKE_mesh.h"
59 #include "BKE_mesh_mapping.h"
60 #include "BKE_mesh_mirror.h"
61 #include "BKE_modifier.h"
62 #include "BKE_multires.h"
63 #include "BKE_node.h"
64 #include "BKE_object.h"
65 #include "BKE_paint.h"
66 #include "BKE_particle.h"
67 #include "BKE_pbvh.h"
68 #include "BKE_pointcache.h"
69 #include "BKE_report.h"
70 #include "BKE_scene.h"
71 #include "BKE_screen.h"
72 #include "BKE_subdiv_ccg.h"
73 #include "BKE_subsurf.h"
74
75 #include "DEG_depsgraph.h"
76
77 #include "IMB_colormanagement.h"
78
79 #include "WM_api.h"
80 #include "WM_message.h"
81 #include "WM_toolsystem.h"
82 #include "WM_types.h"
83
84 #include "ED_object.h"
85 #include "ED_screen.h"
86 #include "ED_sculpt.h"
87 #include "ED_view3d.h"
88 #include "paint_intern.h"
89 #include "sculpt_intern.h"
90
91 #include "RNA_access.h"
92 #include "RNA_define.h"
93
94 #include "UI_interface.h"
95 #include "UI_resources.h"
96
97 #include "bmesh.h"
98 #include "bmesh_tools.h"
99
100 #include <math.h>
101 #include <stdlib.h>
102 #include <string.h>
103
104 /* Sculpt PBVH abstraction API
105 *
106 * This is read-only, for writing use PBVH vertex iterators. There vd.index matches
107 * the indices used here.
108 *
109 * For multi-resolution, the same vertex in multiple grids is counted multiple times, with
110 * different index for each grid. */
111
SCULPT_vertex_random_access_ensure(SculptSession * ss)112 void SCULPT_vertex_random_access_ensure(SculptSession *ss)
113 {
114 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
115 BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
116 BM_mesh_elem_table_ensure(ss->bm, BM_VERT);
117 }
118 }
119
SCULPT_vertex_count_get(SculptSession * ss)120 int SCULPT_vertex_count_get(SculptSession *ss)
121 {
122 switch (BKE_pbvh_type(ss->pbvh)) {
123 case PBVH_FACES:
124 return ss->totvert;
125 case PBVH_BMESH:
126 return BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
127 case PBVH_GRIDS:
128 return BKE_pbvh_get_grid_num_vertices(ss->pbvh);
129 }
130
131 return 0;
132 }
133
SCULPT_vertex_co_get(SculptSession * ss,int index)134 const float *SCULPT_vertex_co_get(SculptSession *ss, int index)
135 {
136 switch (BKE_pbvh_type(ss->pbvh)) {
137 case PBVH_FACES: {
138 if (ss->shapekey_active || ss->deform_modifiers_active) {
139 const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh);
140 return mverts[index].co;
141 }
142 return ss->mvert[index].co;
143 }
144 case PBVH_BMESH:
145 return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co;
146 case PBVH_GRIDS: {
147 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
148 const int grid_index = index / key->grid_area;
149 const int vertex_index = index - grid_index * key->grid_area;
150 CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
151 return CCG_elem_co(key, CCG_elem_offset(key, elem, vertex_index));
152 }
153 }
154 return NULL;
155 }
156
SCULPT_vertex_color_get(SculptSession * ss,int index)157 const float *SCULPT_vertex_color_get(SculptSession *ss, int index)
158 {
159 switch (BKE_pbvh_type(ss->pbvh)) {
160 case PBVH_FACES:
161 if (ss->vcol) {
162 return ss->vcol[index].color;
163 }
164 break;
165 case PBVH_BMESH:
166 case PBVH_GRIDS:
167 break;
168 }
169 return NULL;
170 }
171
SCULPT_vertex_normal_get(SculptSession * ss,int index,float no[3])172 void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
173 {
174 switch (BKE_pbvh_type(ss->pbvh)) {
175 case PBVH_FACES: {
176 if (ss->shapekey_active || ss->deform_modifiers_active) {
177 const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh);
178 normal_short_to_float_v3(no, mverts[index].no);
179 }
180 else {
181 normal_short_to_float_v3(no, ss->mvert[index].no);
182 }
183 break;
184 }
185 case PBVH_BMESH:
186 copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no);
187 break;
188 case PBVH_GRIDS: {
189 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
190 const int grid_index = index / key->grid_area;
191 const int vertex_index = index - grid_index * key->grid_area;
192 CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
193 copy_v3_v3(no, CCG_elem_no(key, CCG_elem_offset(key, elem, vertex_index)));
194 break;
195 }
196 }
197 }
198
SCULPT_vertex_persistent_co_get(SculptSession * ss,int index)199 const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index)
200 {
201 if (ss->persistent_base) {
202 return ss->persistent_base[index].co;
203 }
204 return SCULPT_vertex_co_get(ss, index);
205 }
206
SCULPT_vertex_co_for_grab_active_get(SculptSession * ss,int index)207 const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index)
208 {
209 /* Always grab active shape key if the sculpt happens on shapekey. */
210 if (ss->shapekey_active) {
211 const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh);
212 return mverts[index].co;
213 }
214
215 /* Sculpting on the base mesh. */
216 if (ss->mvert) {
217 return ss->mvert[index].co;
218 }
219
220 /* Everything else, such as sculpting on multires. */
221 return SCULPT_vertex_co_get(ss, index);
222 }
223
SCULPT_vertex_limit_surface_get(SculptSession * ss,int index,float r_co[3])224 void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3])
225 {
226 switch (BKE_pbvh_type(ss->pbvh)) {
227 case PBVH_FACES:
228 case PBVH_BMESH:
229 copy_v3_v3(r_co, SCULPT_vertex_co_get(ss, index));
230 break;
231 case PBVH_GRIDS: {
232 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
233 const int grid_index = index / key->grid_area;
234 const int vertex_index = index - grid_index * key->grid_area;
235
236 SubdivCCGCoord coord = {.grid_index = grid_index,
237 .x = vertex_index % key->grid_size,
238 .y = vertex_index / key->grid_size};
239 BKE_subdiv_ccg_eval_limit_point(ss->subdiv_ccg, &coord, r_co);
240 break;
241 }
242 }
243 }
244
SCULPT_vertex_persistent_normal_get(SculptSession * ss,int index,float no[3])245 void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3])
246 {
247 if (ss->persistent_base) {
248 copy_v3_v3(no, ss->persistent_base[index].no);
249 return;
250 }
251 SCULPT_vertex_normal_get(ss, index, no);
252 }
253
SCULPT_vertex_mask_get(SculptSession * ss,int index)254 float SCULPT_vertex_mask_get(SculptSession *ss, int index)
255 {
256 BMVert *v;
257 float *mask;
258 switch (BKE_pbvh_type(ss->pbvh)) {
259 case PBVH_FACES:
260 return ss->vmask[index];
261 case PBVH_BMESH:
262 v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index);
263 mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK));
264 return *mask;
265 case PBVH_GRIDS: {
266 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
267 const int grid_index = index / key->grid_area;
268 const int vertex_index = index - grid_index * key->grid_area;
269 CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index];
270 return *CCG_elem_mask(key, CCG_elem_offset(key, elem, vertex_index));
271 }
272 }
273
274 return 0.0f;
275 }
276
SCULPT_active_vertex_get(SculptSession * ss)277 int SCULPT_active_vertex_get(SculptSession *ss)
278 {
279 if (ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) {
280 return ss->active_vertex_index;
281 }
282 return 0;
283 }
284
SCULPT_active_vertex_co_get(SculptSession * ss)285 const float *SCULPT_active_vertex_co_get(SculptSession *ss)
286 {
287 return SCULPT_vertex_co_get(ss, SCULPT_active_vertex_get(ss));
288 }
289
SCULPT_active_vertex_normal_get(SculptSession * ss,float normal[3])290 void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3])
291 {
292 SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal);
293 }
294
SCULPT_mesh_deformed_mverts_get(SculptSession * ss)295 MVert *SCULPT_mesh_deformed_mverts_get(SculptSession *ss)
296 {
297 switch (BKE_pbvh_type(ss->pbvh)) {
298 case PBVH_FACES:
299 if (ss->shapekey_active || ss->deform_modifiers_active) {
300 return BKE_pbvh_get_verts(ss->pbvh);
301 }
302 return ss->mvert;
303 case PBVH_BMESH:
304 case PBVH_GRIDS:
305 return NULL;
306 }
307 return NULL;
308 }
309
SCULPT_brush_deform_target_vertex_co_get(SculptSession * ss,const int deform_target,PBVHVertexIter * iter)310 float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
311 const int deform_target,
312 PBVHVertexIter *iter)
313 {
314 switch (deform_target) {
315 case BRUSH_DEFORM_TARGET_GEOMETRY:
316 return iter->co;
317 case BRUSH_DEFORM_TARGET_CLOTH_SIM:
318 return ss->cache->cloth_sim->deformation_pos[iter->index];
319 }
320 return iter->co;
321 }
322
SCULPT_mesh_symmetry_xyz_get(Object * object)323 char SCULPT_mesh_symmetry_xyz_get(Object *object)
324 {
325 const Mesh *mesh = BKE_mesh_from_object(object);
326 return mesh->symmetry;
327 }
328
329 /* Sculpt Face Sets and Visibility. */
330
SCULPT_active_face_set_get(SculptSession * ss)331 int SCULPT_active_face_set_get(SculptSession *ss)
332 {
333 switch (BKE_pbvh_type(ss->pbvh)) {
334 case PBVH_FACES:
335 return ss->face_sets[ss->active_face_index];
336 case PBVH_GRIDS: {
337 const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg,
338 ss->active_grid_index);
339 return ss->face_sets[face_index];
340 }
341 case PBVH_BMESH:
342 return SCULPT_FACE_SET_NONE;
343 }
344 return SCULPT_FACE_SET_NONE;
345 }
346
SCULPT_vertex_visible_set(SculptSession * ss,int index,bool visible)347 void SCULPT_vertex_visible_set(SculptSession *ss, int index, bool visible)
348 {
349 switch (BKE_pbvh_type(ss->pbvh)) {
350 case PBVH_FACES:
351 SET_FLAG_FROM_TEST(ss->mvert[index].flag, !visible, ME_HIDE);
352 ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE;
353 break;
354 case PBVH_BMESH:
355 BM_elem_flag_set(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN, !visible);
356 break;
357 case PBVH_GRIDS:
358 break;
359 }
360 }
361
SCULPT_vertex_visible_get(SculptSession * ss,int index)362 bool SCULPT_vertex_visible_get(SculptSession *ss, int index)
363 {
364 switch (BKE_pbvh_type(ss->pbvh)) {
365 case PBVH_FACES:
366 return !(ss->mvert[index].flag & ME_HIDE);
367 case PBVH_BMESH:
368 return !BM_elem_flag_test(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN);
369 case PBVH_GRIDS: {
370 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
371 const int grid_index = index / key->grid_area;
372 const int vertex_index = index - grid_index * key->grid_area;
373 BLI_bitmap **grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh);
374 if (grid_hidden && grid_hidden[grid_index]) {
375 return !BLI_BITMAP_TEST(grid_hidden[grid_index], vertex_index);
376 }
377 }
378 }
379 return true;
380 }
381
SCULPT_face_set_visibility_set(SculptSession * ss,int face_set,bool visible)382 void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible)
383 {
384 switch (BKE_pbvh_type(ss->pbvh)) {
385 case PBVH_FACES:
386 case PBVH_GRIDS:
387 for (int i = 0; i < ss->totfaces; i++) {
388 if (abs(ss->face_sets[i]) == face_set) {
389 if (visible) {
390 ss->face_sets[i] = abs(ss->face_sets[i]);
391 }
392 else {
393 ss->face_sets[i] = -abs(ss->face_sets[i]);
394 }
395 }
396 }
397 break;
398 case PBVH_BMESH:
399 break;
400 }
401 }
402
SCULPT_face_sets_visibility_invert(SculptSession * ss)403 void SCULPT_face_sets_visibility_invert(SculptSession *ss)
404 {
405 switch (BKE_pbvh_type(ss->pbvh)) {
406 case PBVH_FACES:
407 case PBVH_GRIDS:
408 for (int i = 0; i < ss->totfaces; i++) {
409 ss->face_sets[i] *= -1;
410 }
411 break;
412 case PBVH_BMESH:
413 break;
414 }
415 }
416
SCULPT_face_sets_visibility_all_set(SculptSession * ss,bool visible)417 void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
418 {
419 switch (BKE_pbvh_type(ss->pbvh)) {
420 case PBVH_FACES:
421 case PBVH_GRIDS:
422 for (int i = 0; i < ss->totfaces; i++) {
423
424 /* This can run on geometry without a face set assigned, so its ID sign can't be changed to
425 * modify the visibility. Force that geometry to the ID 1 to enable changing the visibility
426 * here. */
427 if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
428 ss->face_sets[i] = 1;
429 }
430
431 if (visible) {
432 ss->face_sets[i] = abs(ss->face_sets[i]);
433 }
434 else {
435 ss->face_sets[i] = -abs(ss->face_sets[i]);
436 }
437 }
438 break;
439 case PBVH_BMESH:
440 break;
441 }
442 }
443
SCULPT_vertex_any_face_set_visible_get(SculptSession * ss,int index)444 bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index)
445 {
446 switch (BKE_pbvh_type(ss->pbvh)) {
447 case PBVH_FACES: {
448 MeshElemMap *vert_map = &ss->pmap[index];
449 for (int j = 0; j < ss->pmap[index].count; j++) {
450 if (ss->face_sets[vert_map->indices[j]] > 0) {
451 return true;
452 }
453 }
454 return false;
455 }
456 case PBVH_BMESH:
457 return true;
458 case PBVH_GRIDS:
459 return true;
460 }
461 return true;
462 }
463
SCULPT_vertex_all_face_sets_visible_get(const SculptSession * ss,int index)464 bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index)
465 {
466 switch (BKE_pbvh_type(ss->pbvh)) {
467 case PBVH_FACES: {
468 MeshElemMap *vert_map = &ss->pmap[index];
469 for (int j = 0; j < ss->pmap[index].count; j++) {
470 if (ss->face_sets[vert_map->indices[j]] < 0) {
471 return false;
472 }
473 }
474 return true;
475 }
476 case PBVH_BMESH:
477 return true;
478 case PBVH_GRIDS: {
479 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
480 const int grid_index = index / key->grid_area;
481 const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
482 return ss->face_sets[face_index] > 0;
483 }
484 }
485 return true;
486 }
487
SCULPT_vertex_face_set_set(SculptSession * ss,int index,int face_set)488 void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
489 {
490 switch (BKE_pbvh_type(ss->pbvh)) {
491 case PBVH_FACES: {
492 MeshElemMap *vert_map = &ss->pmap[index];
493 for (int j = 0; j < ss->pmap[index].count; j++) {
494 if (ss->face_sets[vert_map->indices[j]] > 0) {
495 ss->face_sets[vert_map->indices[j]] = abs(face_set);
496 }
497 }
498 } break;
499 case PBVH_BMESH:
500 break;
501 case PBVH_GRIDS: {
502 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
503 const int grid_index = index / key->grid_area;
504 const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
505 if (ss->face_sets[face_index] > 0) {
506 ss->face_sets[face_index] = abs(face_set);
507 }
508
509 } break;
510 }
511 }
512
SCULPT_vertex_face_set_get(SculptSession * ss,int index)513 int SCULPT_vertex_face_set_get(SculptSession *ss, int index)
514 {
515 switch (BKE_pbvh_type(ss->pbvh)) {
516 case PBVH_FACES: {
517 MeshElemMap *vert_map = &ss->pmap[index];
518 int face_set = 0;
519 for (int i = 0; i < ss->pmap[index].count; i++) {
520 if (ss->face_sets[vert_map->indices[i]] > face_set) {
521 face_set = abs(ss->face_sets[vert_map->indices[i]]);
522 }
523 }
524 return face_set;
525 }
526 case PBVH_BMESH:
527 return 0;
528 case PBVH_GRIDS: {
529 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
530 const int grid_index = index / key->grid_area;
531 const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
532 return ss->face_sets[face_index];
533 }
534 }
535 return 0;
536 }
537
SCULPT_vertex_has_face_set(SculptSession * ss,int index,int face_set)538 bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
539 {
540 switch (BKE_pbvh_type(ss->pbvh)) {
541 case PBVH_FACES: {
542 MeshElemMap *vert_map = &ss->pmap[index];
543 for (int i = 0; i < ss->pmap[index].count; i++) {
544 if (ss->face_sets[vert_map->indices[i]] == face_set) {
545 return true;
546 }
547 }
548 return false;
549 }
550 case PBVH_BMESH:
551 return true;
552 case PBVH_GRIDS: {
553 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
554 const int grid_index = index / key->grid_area;
555 const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index);
556 return ss->face_sets[face_index] == face_set;
557 }
558 }
559 return true;
560 }
561
SCULPT_visibility_sync_all_face_sets_to_vertices(Object * ob)562 void SCULPT_visibility_sync_all_face_sets_to_vertices(Object *ob)
563 {
564 SculptSession *ss = ob->sculpt;
565 Mesh *mesh = BKE_object_get_original_mesh(ob);
566 switch (BKE_pbvh_type(ss->pbvh)) {
567 case PBVH_FACES: {
568 BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
569 break;
570 }
571 case PBVH_GRIDS: {
572 BKE_sculpt_sync_face_sets_visibility_to_base_mesh(mesh);
573 BKE_sculpt_sync_face_sets_visibility_to_grids(mesh, ss->subdiv_ccg);
574 break;
575 }
576 case PBVH_BMESH:
577 break;
578 }
579 }
580
UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)581 static void UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)(SculptSession *ss,
582 int index)
583 {
584 MeshElemMap *vert_map = &ss->pmap[index];
585 const bool visible = SCULPT_vertex_visible_get(ss, index);
586 for (int i = 0; i < ss->pmap[index].count; i++) {
587 if (visible) {
588 ss->face_sets[vert_map->indices[i]] = abs(ss->face_sets[vert_map->indices[i]]);
589 }
590 else {
591 ss->face_sets[vert_map->indices[i]] = -abs(ss->face_sets[vert_map->indices[i]]);
592 }
593 }
594 ss->mvert[index].flag |= ME_VERT_PBVH_UPDATE;
595 }
596
SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession * ss)597 void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
598 {
599 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
600 for (int i = 0; i < ss->totfaces; i++) {
601 MPoly *poly = &ss->mpoly[i];
602 bool poly_visible = true;
603 for (int l = 0; l < poly->totloop; l++) {
604 MLoop *loop = &ss->mloop[poly->loopstart + l];
605 if (!SCULPT_vertex_visible_get(ss, (int)loop->v)) {
606 poly_visible = false;
607 }
608 }
609 if (poly_visible) {
610 ss->face_sets[i] = abs(ss->face_sets[i]);
611 }
612 else {
613 ss->face_sets[i] = -abs(ss->face_sets[i]);
614 }
615 }
616 }
617 }
618
sculpt_check_unique_face_set_in_base_mesh(SculptSession * ss,int index)619 static bool sculpt_check_unique_face_set_in_base_mesh(SculptSession *ss, int index)
620 {
621 MeshElemMap *vert_map = &ss->pmap[index];
622 int face_set = -1;
623 for (int i = 0; i < ss->pmap[index].count; i++) {
624 if (face_set == -1) {
625 face_set = abs(ss->face_sets[vert_map->indices[i]]);
626 }
627 else {
628 if (abs(ss->face_sets[vert_map->indices[i]]) != face_set) {
629 return false;
630 }
631 }
632 }
633 return true;
634 }
635
636 /**
637 * Checks if the face sets of the adjacent faces to the edge between \a v1 and \a v2
638 * in the base mesh are equal.
639 */
sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession * ss,int v1,int v2)640 static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss, int v1, int v2)
641 {
642 MeshElemMap *vert_map = &ss->pmap[v1];
643 int p1 = -1, p2 = -1;
644 for (int i = 0; i < ss->pmap[v1].count; i++) {
645 MPoly *p = &ss->mpoly[vert_map->indices[i]];
646 for (int l = 0; l < p->totloop; l++) {
647 MLoop *loop = &ss->mloop[p->loopstart + l];
648 if (loop->v == v2) {
649 if (p1 == -1) {
650 p1 = vert_map->indices[i];
651 break;
652 }
653
654 if (p2 == -1) {
655 p2 = vert_map->indices[i];
656 break;
657 }
658 }
659 }
660 }
661
662 if (p1 != -1 && p2 != -1) {
663 return abs(ss->face_sets[p1]) == (ss->face_sets[p2]);
664 }
665 return true;
666 }
667
SCULPT_vertex_has_unique_face_set(SculptSession * ss,int index)668 bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
669 {
670 switch (BKE_pbvh_type(ss->pbvh)) {
671 case PBVH_FACES: {
672 return sculpt_check_unique_face_set_in_base_mesh(ss, index);
673 }
674 case PBVH_BMESH:
675 return false;
676 case PBVH_GRIDS: {
677 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
678 const int grid_index = index / key->grid_area;
679 const int vertex_index = index - grid_index * key->grid_area;
680 const SubdivCCGCoord coord = {.grid_index = grid_index,
681 .x = vertex_index % key->grid_size,
682 .y = vertex_index / key->grid_size};
683 int v1, v2;
684 const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
685 ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2);
686 switch (adjacency) {
687 case SUBDIV_CCG_ADJACENT_VERTEX:
688 return sculpt_check_unique_face_set_in_base_mesh(ss, v1);
689 case SUBDIV_CCG_ADJACENT_EDGE:
690 return sculpt_check_unique_face_set_for_edge_in_base_mesh(ss, v1, v2);
691 case SUBDIV_CCG_ADJACENT_NONE:
692 return true;
693 }
694 }
695 }
696 return false;
697 }
698
SCULPT_face_set_next_available_get(SculptSession * ss)699 int SCULPT_face_set_next_available_get(SculptSession *ss)
700 {
701 switch (BKE_pbvh_type(ss->pbvh)) {
702 case PBVH_FACES:
703 case PBVH_GRIDS: {
704 int next_face_set = 0;
705 for (int i = 0; i < ss->totfaces; i++) {
706 if (abs(ss->face_sets[i]) > next_face_set) {
707 next_face_set = abs(ss->face_sets[i]);
708 }
709 }
710 next_face_set++;
711 return next_face_set;
712 }
713 case PBVH_BMESH:
714 return 0;
715 }
716 return 0;
717 }
718
719 /* Sculpt Neighbor Iterators */
720
721 #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
722
sculpt_vertex_neighbor_add(SculptVertexNeighborIter * iter,int neighbor_index)723 static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, int neighbor_index)
724 {
725 for (int i = 0; i < iter->size; i++) {
726 if (iter->neighbors[i] == neighbor_index) {
727 return;
728 }
729 }
730
731 if (iter->size >= iter->capacity) {
732 iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
733
734 if (iter->neighbors == iter->neighbors_fixed) {
735 iter->neighbors = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array");
736 memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(int) * iter->size);
737 }
738 else {
739 iter->neighbors = MEM_reallocN_id(
740 iter->neighbors, iter->capacity * sizeof(int), "neighbor array");
741 }
742 }
743
744 iter->neighbors[iter->size] = neighbor_index;
745 iter->size++;
746 }
747
sculpt_vertex_neighbors_get_bmesh(SculptSession * ss,int index,SculptVertexNeighborIter * iter)748 static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss,
749 int index,
750 SculptVertexNeighborIter *iter)
751 {
752 BMVert *v = BM_vert_at_index(ss->bm, index);
753 BMIter liter;
754 BMLoop *l;
755 iter->size = 0;
756 iter->num_duplicates = 0;
757 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
758 iter->neighbors = iter->neighbors_fixed;
759
760 BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
761 const BMVert *adj_v[2] = {l->prev->v, l->next->v};
762 for (int i = 0; i < ARRAY_SIZE(adj_v); i++) {
763 const BMVert *v_other = adj_v[i];
764 if (BM_elem_index_get(v_other) != (int)index) {
765 sculpt_vertex_neighbor_add(iter, BM_elem_index_get(v_other));
766 }
767 }
768 }
769 }
770
sculpt_vertex_neighbors_get_faces(SculptSession * ss,int index,SculptVertexNeighborIter * iter)771 static void sculpt_vertex_neighbors_get_faces(SculptSession *ss,
772 int index,
773 SculptVertexNeighborIter *iter)
774 {
775 MeshElemMap *vert_map = &ss->pmap[index];
776 iter->size = 0;
777 iter->num_duplicates = 0;
778 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
779 iter->neighbors = iter->neighbors_fixed;
780
781 for (int i = 0; i < ss->pmap[index].count; i++) {
782 const MPoly *p = &ss->mpoly[vert_map->indices[i]];
783 uint f_adj_v[2];
784 if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) {
785 for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
786 if (f_adj_v[j] != index) {
787 sculpt_vertex_neighbor_add(iter, f_adj_v[j]);
788 }
789 }
790 }
791 }
792
793 if (ss->fake_neighbors.use_fake_neighbors) {
794 BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
795 if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) {
796 sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]);
797 }
798 }
799 }
800
sculpt_vertex_neighbors_get_grids(SculptSession * ss,const int index,const bool include_duplicates,SculptVertexNeighborIter * iter)801 static void sculpt_vertex_neighbors_get_grids(SculptSession *ss,
802 const int index,
803 const bool include_duplicates,
804 SculptVertexNeighborIter *iter)
805 {
806 /* TODO: optimize this. We could fill #SculptVertexNeighborIter directly,
807 * maybe provide coordinate and mask pointers directly rather than converting
808 * back and forth between #CCGElem and global index. */
809 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
810 const int grid_index = index / key->grid_area;
811 const int vertex_index = index - grid_index * key->grid_area;
812
813 SubdivCCGCoord coord = {.grid_index = grid_index,
814 .x = vertex_index % key->grid_size,
815 .y = vertex_index / key->grid_size};
816
817 SubdivCCGNeighbors neighbors;
818 BKE_subdiv_ccg_neighbor_coords_get(ss->subdiv_ccg, &coord, include_duplicates, &neighbors);
819
820 iter->size = 0;
821 iter->num_duplicates = neighbors.num_duplicates;
822 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
823 iter->neighbors = iter->neighbors_fixed;
824
825 for (int i = 0; i < neighbors.size; i++) {
826 sculpt_vertex_neighbor_add(iter,
827 neighbors.coords[i].grid_index * key->grid_area +
828 neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x);
829 }
830
831 if (ss->fake_neighbors.use_fake_neighbors) {
832 BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
833 if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) {
834 sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]);
835 }
836 }
837
838 if (neighbors.coords != neighbors.coords_fixed) {
839 MEM_freeN(neighbors.coords);
840 }
841 }
842
SCULPT_vertex_neighbors_get(SculptSession * ss,const int index,const bool include_duplicates,SculptVertexNeighborIter * iter)843 void SCULPT_vertex_neighbors_get(SculptSession *ss,
844 const int index,
845 const bool include_duplicates,
846 SculptVertexNeighborIter *iter)
847 {
848 switch (BKE_pbvh_type(ss->pbvh)) {
849 case PBVH_FACES:
850 sculpt_vertex_neighbors_get_faces(ss, index, iter);
851 return;
852 case PBVH_BMESH:
853 sculpt_vertex_neighbors_get_bmesh(ss, index, iter);
854 return;
855 case PBVH_GRIDS:
856 sculpt_vertex_neighbors_get_grids(ss, index, include_duplicates, iter);
857 return;
858 }
859 }
860
sculpt_check_boundary_vertex_in_base_mesh(const SculptSession * ss,const int index)861 static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss, const int index)
862 {
863 BLI_assert(ss->vertex_info.boundary);
864 return BLI_BITMAP_TEST(ss->vertex_info.boundary, index);
865 }
866
SCULPT_vertex_is_boundary(const SculptSession * ss,const int index)867 bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index)
868 {
869 switch (BKE_pbvh_type(ss->pbvh)) {
870 case PBVH_FACES: {
871 if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) {
872 return true;
873 }
874 return sculpt_check_boundary_vertex_in_base_mesh(ss, index);
875 }
876 case PBVH_BMESH: {
877 BMVert *v = BM_vert_at_index(ss->bm, index);
878 return BM_vert_is_boundary(v);
879 }
880
881 case PBVH_GRIDS: {
882 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
883 const int grid_index = index / key->grid_area;
884 const int vertex_index = index - grid_index * key->grid_area;
885 const SubdivCCGCoord coord = {.grid_index = grid_index,
886 .x = vertex_index % key->grid_size,
887 .y = vertex_index / key->grid_size};
888 int v1, v2;
889 const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
890 ss->subdiv_ccg, &coord, ss->mloop, ss->mpoly, &v1, &v2);
891 switch (adjacency) {
892 case SUBDIV_CCG_ADJACENT_VERTEX:
893 return sculpt_check_boundary_vertex_in_base_mesh(ss, v1);
894 case SUBDIV_CCG_ADJACENT_EDGE:
895 return sculpt_check_boundary_vertex_in_base_mesh(ss, v1) &&
896 sculpt_check_boundary_vertex_in_base_mesh(ss, v2);
897 case SUBDIV_CCG_ADJACENT_NONE:
898 return false;
899 }
900 }
901 }
902
903 return false;
904 }
905
906 /* Utilities */
907
908 /**
909 * Returns true when the step belongs to the stroke that is directly performed by the brush and
910 * not by one of the symmetry passes.
911 */
SCULPT_stroke_is_main_symmetry_pass(StrokeCache * cache)912 bool SCULPT_stroke_is_main_symmetry_pass(StrokeCache *cache)
913 {
914 return cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
915 cache->tile_pass == 0;
916 }
917
918 /**
919 * Return true only once per stroke on the first symmetry pass, regardless of the symmetry passes
920 * enabled.
921 *
922 * This should be used for functionality that needs to be computed once per stroke of a particular
923 * tool (allocating memory, updating random seeds...).
924 */
SCULPT_stroke_is_first_brush_step(StrokeCache * cache)925 bool SCULPT_stroke_is_first_brush_step(StrokeCache *cache)
926 {
927 return cache->first_time && cache->mirror_symmetry_pass == 0 &&
928 cache->radial_symmetry_pass == 0 && cache->tile_pass == 0;
929 }
930
931 /**
932 * Returns true on the first brush step of each symmetry pass.
933 */
SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache * cache)934 bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
935 {
936 return cache->first_time;
937 }
938
SCULPT_check_vertex_pivot_symmetry(const float vco[3],const float pco[3],const char symm)939 bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
940 {
941 bool is_in_symmetry_area = true;
942 for (int i = 0; i < 3; i++) {
943 char symm_it = 1 << i;
944 if (symm & symm_it) {
945 if (pco[i] == 0.0f) {
946 if (vco[i] > 0.0f) {
947 is_in_symmetry_area = false;
948 }
949 }
950 if (vco[i] * pco[i] < 0.0f) {
951 is_in_symmetry_area = false;
952 }
953 }
954 }
955 return is_in_symmetry_area;
956 }
957
958 typedef struct NearestVertexTLSData {
959 int nearest_vertex_index;
960 float nearest_vertex_distance_squared;
961 } NearestVertexTLSData;
962
do_nearest_vertex_get_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)963 static void do_nearest_vertex_get_task_cb(void *__restrict userdata,
964 const int n,
965 const TaskParallelTLS *__restrict tls)
966 {
967 SculptThreadedTaskData *data = userdata;
968 SculptSession *ss = data->ob->sculpt;
969 NearestVertexTLSData *nvtd = tls->userdata_chunk;
970 PBVHVertexIter vd;
971
972 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
973 {
974 float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co);
975 if (distance_squared < nvtd->nearest_vertex_distance_squared &&
976 distance_squared < data->max_distance_squared) {
977 nvtd->nearest_vertex_index = vd.index;
978 nvtd->nearest_vertex_distance_squared = distance_squared;
979 }
980 }
981 BKE_pbvh_vertex_iter_end;
982 }
983
nearest_vertex_get_reduce(const void * __restrict UNUSED (userdata),void * __restrict chunk_join,void * __restrict chunk)984 static void nearest_vertex_get_reduce(const void *__restrict UNUSED(userdata),
985 void *__restrict chunk_join,
986 void *__restrict chunk)
987 {
988 NearestVertexTLSData *join = chunk_join;
989 NearestVertexTLSData *nvtd = chunk;
990 if (join->nearest_vertex_index == -1) {
991 join->nearest_vertex_index = nvtd->nearest_vertex_index;
992 join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
993 }
994 else if (nvtd->nearest_vertex_distance_squared < join->nearest_vertex_distance_squared) {
995 join->nearest_vertex_index = nvtd->nearest_vertex_index;
996 join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
997 }
998 }
999
SCULPT_nearest_vertex_get(Sculpt * sd,Object * ob,const float co[3],float max_distance,bool use_original)1000 int SCULPT_nearest_vertex_get(
1001 Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original)
1002 {
1003 SculptSession *ss = ob->sculpt;
1004 PBVHNode **nodes = NULL;
1005 int totnode;
1006 SculptSearchSphereData data = {
1007 .ss = ss,
1008 .sd = sd,
1009 .radius_squared = max_distance * max_distance,
1010 .original = use_original,
1011 .center = co,
1012 };
1013 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
1014 if (totnode == 0) {
1015 return -1;
1016 }
1017
1018 SculptThreadedTaskData task_data = {
1019 .sd = sd,
1020 .ob = ob,
1021 .nodes = nodes,
1022 .max_distance_squared = max_distance * max_distance,
1023 };
1024
1025 copy_v3_v3(task_data.nearest_vertex_search_co, co);
1026 NearestVertexTLSData nvtd;
1027 nvtd.nearest_vertex_index = -1;
1028 nvtd.nearest_vertex_distance_squared = FLT_MAX;
1029
1030 TaskParallelSettings settings;
1031 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
1032 settings.func_reduce = nearest_vertex_get_reduce;
1033 settings.userdata_chunk = &nvtd;
1034 settings.userdata_chunk_size = sizeof(NearestVertexTLSData);
1035 BLI_task_parallel_range(0, totnode, &task_data, do_nearest_vertex_get_task_cb, &settings);
1036
1037 MEM_SAFE_FREE(nodes);
1038
1039 return nvtd.nearest_vertex_index;
1040 }
1041
SCULPT_is_symmetry_iteration_valid(char i,char symm)1042 bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
1043 {
1044 return i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)));
1045 }
1046
1047 /* Checks if a vertex is inside the brush radius from any of its mirrored axis. */
SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],const float br_co[3],float radius,char symm)1048 bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
1049 const float br_co[3],
1050 float radius,
1051 char symm)
1052 {
1053 for (char i = 0; i <= symm; ++i) {
1054 if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
1055 float location[3];
1056 flip_v3_v3(location, br_co, (char)i);
1057 if (len_squared_v3v3(location, vertex) < radius * radius) {
1058 return true;
1059 }
1060 }
1061 }
1062 return false;
1063 }
1064
SCULPT_tag_update_overlays(bContext * C)1065 void SCULPT_tag_update_overlays(bContext *C)
1066 {
1067 ARegion *region = CTX_wm_region(C);
1068 ED_region_tag_redraw(region);
1069
1070 Object *ob = CTX_data_active_object(C);
1071 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
1072
1073 DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
1074 View3D *v3d = CTX_wm_view3d(C);
1075 if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
1076 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1077 }
1078 }
1079
1080 /* Sculpt Flood Fill API
1081 *
1082 * Iterate over connected vertices, starting from one or more initial vertices. */
1083
SCULPT_floodfill_init(SculptSession * ss,SculptFloodFill * flood)1084 void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
1085 {
1086 int vertex_count = SCULPT_vertex_count_get(ss);
1087 SCULPT_vertex_random_access_ensure(ss);
1088
1089 flood->queue = BLI_gsqueue_new(sizeof(int));
1090 flood->visited_vertices = BLI_BITMAP_NEW(vertex_count, "visited vertices");
1091 }
1092
SCULPT_floodfill_add_initial(SculptFloodFill * flood,int index)1093 void SCULPT_floodfill_add_initial(SculptFloodFill *flood, int index)
1094 {
1095 BLI_gsqueue_push(flood->queue, &index);
1096 }
1097
SCULPT_floodfill_add_initial_with_symmetry(Sculpt * sd,Object * ob,SculptSession * ss,SculptFloodFill * flood,int index,float radius)1098 void SCULPT_floodfill_add_initial_with_symmetry(
1099 Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, int index, float radius)
1100 {
1101 /* Add active vertex and symmetric vertices to the queue. */
1102 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1103 for (char i = 0; i <= symm; ++i) {
1104 if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
1105 int v = -1;
1106 if (i == 0) {
1107 v = index;
1108 }
1109 else if (radius > 0.0f) {
1110 float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
1111 float location[3];
1112 flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i);
1113 v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
1114 }
1115 if (v != -1) {
1116 SCULPT_floodfill_add_initial(flood, v);
1117 }
1118 }
1119 }
1120 }
1121
SCULPT_floodfill_add_active(Sculpt * sd,Object * ob,SculptSession * ss,SculptFloodFill * flood,float radius)1122 void SCULPT_floodfill_add_active(
1123 Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
1124 {
1125 /* Add active vertex and symmetric vertices to the queue. */
1126 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1127 for (char i = 0; i <= symm; ++i) {
1128 if (SCULPT_is_symmetry_iteration_valid(i, symm)) {
1129 int v = -1;
1130 if (i == 0) {
1131 v = SCULPT_active_vertex_get(ss);
1132 }
1133 else if (radius > 0.0f) {
1134 float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
1135 float location[3];
1136 flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), i);
1137 v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false);
1138 }
1139 if (v != -1) {
1140 SCULPT_floodfill_add_initial(flood, v);
1141 }
1142 }
1143 }
1144 }
1145
SCULPT_floodfill_execute(SculptSession * ss,SculptFloodFill * flood,bool (* func)(SculptSession * ss,int from_v,int to_v,bool is_duplicate,void * userdata),void * userdata)1146 void SCULPT_floodfill_execute(
1147 SculptSession *ss,
1148 SculptFloodFill *flood,
1149 bool (*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata),
1150 void *userdata)
1151 {
1152 while (!BLI_gsqueue_is_empty(flood->queue)) {
1153 int from_v;
1154 BLI_gsqueue_pop(flood->queue, &from_v);
1155 SculptVertexNeighborIter ni;
1156 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
1157 const int to_v = ni.index;
1158 if (!BLI_BITMAP_TEST(flood->visited_vertices, to_v) && SCULPT_vertex_visible_get(ss, to_v)) {
1159 BLI_BITMAP_ENABLE(flood->visited_vertices, to_v);
1160
1161 if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) {
1162 BLI_gsqueue_push(flood->queue, &to_v);
1163 }
1164 }
1165 }
1166 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
1167 }
1168 }
1169
SCULPT_floodfill_free(SculptFloodFill * flood)1170 void SCULPT_floodfill_free(SculptFloodFill *flood)
1171 {
1172 MEM_SAFE_FREE(flood->visited_vertices);
1173 BLI_gsqueue_free(flood->queue);
1174 flood->queue = NULL;
1175 }
1176
1177 /** \name Tool Capabilities
1178 *
1179 * Avoid duplicate checks, internal logic only,
1180 * share logic with #rna_def_sculpt_capabilities where possible.
1181 *
1182 * \{ */
1183
1184 /* Check if there are any active modifiers in stack.
1185 * Used for flushing updates at enter/exit sculpt mode. */
sculpt_has_active_modifiers(Scene * scene,Object * ob)1186 static bool sculpt_has_active_modifiers(Scene *scene, Object *ob)
1187 {
1188 ModifierData *md;
1189 VirtualModifierData virtualModifierData;
1190
1191 md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
1192
1193 /* Exception for shape keys because we can edit those. */
1194 for (; md; md = md->next) {
1195 if (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) {
1196 return true;
1197 }
1198 }
1199
1200 return false;
1201 }
1202
sculpt_tool_needs_original(const char sculpt_tool)1203 static bool sculpt_tool_needs_original(const char sculpt_tool)
1204 {
1205 return ELEM(sculpt_tool,
1206 SCULPT_TOOL_GRAB,
1207 SCULPT_TOOL_ROTATE,
1208 SCULPT_TOOL_THUMB,
1209 SCULPT_TOOL_LAYER,
1210 SCULPT_TOOL_DRAW_SHARP,
1211 SCULPT_TOOL_ELASTIC_DEFORM,
1212 SCULPT_TOOL_SMOOTH,
1213 SCULPT_TOOL_BOUNDARY,
1214 SCULPT_TOOL_POSE);
1215 }
1216
sculpt_tool_is_proxy_used(const char sculpt_tool)1217 static bool sculpt_tool_is_proxy_used(const char sculpt_tool)
1218 {
1219 return ELEM(sculpt_tool,
1220 SCULPT_TOOL_SMOOTH,
1221 SCULPT_TOOL_LAYER,
1222 SCULPT_TOOL_POSE,
1223 SCULPT_TOOL_BOUNDARY,
1224 SCULPT_TOOL_CLOTH,
1225 SCULPT_TOOL_PAINT,
1226 SCULPT_TOOL_SMEAR,
1227 SCULPT_TOOL_DRAW_FACE_SETS);
1228 }
1229
sculpt_brush_use_topology_rake(const SculptSession * ss,const Brush * brush)1230 static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush *brush)
1231 {
1232 return SCULPT_TOOL_HAS_TOPOLOGY_RAKE(brush->sculpt_tool) &&
1233 (brush->topology_rake_factor > 0.0f) && (ss->bm != NULL);
1234 }
1235
1236 /**
1237 * Test whether the #StrokeCache.sculpt_normal needs update in #do_brush_action
1238 */
sculpt_brush_needs_normal(const SculptSession * ss,const Brush * brush)1239 static int sculpt_brush_needs_normal(const SculptSession *ss, const Brush *brush)
1240 {
1241 return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) &&
1242 (ss->cache->normal_weight > 0.0f)) ||
1243
1244 ELEM(brush->sculpt_tool,
1245 SCULPT_TOOL_BLOB,
1246 SCULPT_TOOL_CREASE,
1247 SCULPT_TOOL_DRAW,
1248 SCULPT_TOOL_DRAW_SHARP,
1249 SCULPT_TOOL_CLOTH,
1250 SCULPT_TOOL_LAYER,
1251 SCULPT_TOOL_NUDGE,
1252 SCULPT_TOOL_ROTATE,
1253 SCULPT_TOOL_ELASTIC_DEFORM,
1254 SCULPT_TOOL_THUMB) ||
1255
1256 (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) ||
1257 sculpt_brush_use_topology_rake(ss, brush);
1258 }
1259 /** \} */
1260
sculpt_brush_needs_rake_rotation(const Brush * brush)1261 static bool sculpt_brush_needs_rake_rotation(const Brush *brush)
1262 {
1263 return SCULPT_TOOL_HAS_RAKE(brush->sculpt_tool) && (brush->rake_factor != 0.0f);
1264 }
1265
1266 typedef enum StrokeFlags {
1267 CLIP_X = 1,
1268 CLIP_Y = 2,
1269 CLIP_Z = 4,
1270 } StrokeFlags;
1271
1272 /**
1273 * Initialize a #SculptOrigVertData for accessing original vertex data;
1274 * handles #BMesh, #Mesh, and multi-resolution.
1275 */
SCULPT_orig_vert_data_unode_init(SculptOrigVertData * data,Object * ob,SculptUndoNode * unode)1276 void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data, Object *ob, SculptUndoNode *unode)
1277 {
1278 SculptSession *ss = ob->sculpt;
1279 BMesh *bm = ss->bm;
1280
1281 memset(data, 0, sizeof(*data));
1282 data->unode = unode;
1283
1284 if (bm) {
1285 data->bm_log = ss->bm_log;
1286 }
1287 else {
1288 data->coords = data->unode->co;
1289 data->normals = data->unode->no;
1290 data->vmasks = data->unode->mask;
1291 data->colors = data->unode->col;
1292 }
1293 }
1294
1295 /**
1296 * Initialize a #SculptOrigVertData for accessing original vertex data;
1297 * handles #BMesh, #Mesh, and multi-resolution.
1298 */
SCULPT_orig_vert_data_init(SculptOrigVertData * data,Object * ob,PBVHNode * node)1299 void SCULPT_orig_vert_data_init(SculptOrigVertData *data, Object *ob, PBVHNode *node)
1300 {
1301 SculptUndoNode *unode;
1302 unode = SCULPT_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
1303 SCULPT_orig_vert_data_unode_init(data, ob, unode);
1304 }
1305
1306 /**
1307 * Update a #SculptOrigVertData for a particular vertex from the PBVH iterator.
1308 */
SCULPT_orig_vert_data_update(SculptOrigVertData * orig_data,PBVHVertexIter * iter)1309 void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
1310 {
1311 if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
1312 if (orig_data->bm_log) {
1313 BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co, &orig_data->no);
1314 }
1315 else {
1316 orig_data->co = orig_data->coords[iter->i];
1317 orig_data->no = orig_data->normals[iter->i];
1318 }
1319 }
1320 else if (orig_data->unode->type == SCULPT_UNDO_COLOR) {
1321 orig_data->col = orig_data->colors[iter->i];
1322 }
1323 else if (orig_data->unode->type == SCULPT_UNDO_MASK) {
1324 if (orig_data->bm_log) {
1325 orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert);
1326 }
1327 else {
1328 orig_data->mask = orig_data->vmasks[iter->i];
1329 }
1330 }
1331 }
1332
sculpt_rake_data_update(struct SculptRakeData * srd,const float co[3])1333 static void sculpt_rake_data_update(struct SculptRakeData *srd, const float co[3])
1334 {
1335 float rake_dist = len_v3v3(srd->follow_co, co);
1336 if (rake_dist > srd->follow_dist) {
1337 interp_v3_v3v3(srd->follow_co, srd->follow_co, co, rake_dist - srd->follow_dist);
1338 }
1339 }
1340
sculpt_rake_rotate(const SculptSession * ss,const float sculpt_co[3],const float v_co[3],float factor,float r_delta[3])1341 static void sculpt_rake_rotate(const SculptSession *ss,
1342 const float sculpt_co[3],
1343 const float v_co[3],
1344 float factor,
1345 float r_delta[3])
1346 {
1347 float vec_rot[3];
1348
1349 #if 0
1350 /* lerp */
1351 sub_v3_v3v3(vec_rot, v_co, sculpt_co);
1352 mul_qt_v3(ss->cache->rake_rotation_symmetry, vec_rot);
1353 add_v3_v3(vec_rot, sculpt_co);
1354 sub_v3_v3v3(r_delta, vec_rot, v_co);
1355 mul_v3_fl(r_delta, factor);
1356 #else
1357 /* slerp */
1358 float q_interp[4];
1359 sub_v3_v3v3(vec_rot, v_co, sculpt_co);
1360
1361 copy_qt_qt(q_interp, ss->cache->rake_rotation_symmetry);
1362 pow_qt_fl_normalized(q_interp, factor);
1363 mul_qt_v3(q_interp, vec_rot);
1364
1365 add_v3_v3(vec_rot, sculpt_co);
1366 sub_v3_v3v3(r_delta, vec_rot, v_co);
1367 #endif
1368 }
1369
1370 /**
1371 * Align the grab delta to the brush normal.
1372 *
1373 * \param grab_delta: Typically from `ss->cache->grab_delta_symmetry`.
1374 */
sculpt_project_v3_normal_align(SculptSession * ss,const float normal_weight,float grab_delta[3])1375 static void sculpt_project_v3_normal_align(SculptSession *ss,
1376 const float normal_weight,
1377 float grab_delta[3])
1378 {
1379 /* Signed to support grabbing in (to make a hole) as well as out. */
1380 const float len_signed = dot_v3v3(ss->cache->sculpt_normal_symm, grab_delta);
1381
1382 /* This scale effectively projects the offset so dragging follows the cursor,
1383 * as the normal points towards the view, the scale increases. */
1384 float len_view_scale;
1385 {
1386 float view_aligned_normal[3];
1387 project_plane_v3_v3v3(
1388 view_aligned_normal, ss->cache->sculpt_normal_symm, ss->cache->view_normal);
1389 len_view_scale = fabsf(dot_v3v3(view_aligned_normal, ss->cache->sculpt_normal_symm));
1390 len_view_scale = (len_view_scale > FLT_EPSILON) ? 1.0f / len_view_scale : 1.0f;
1391 }
1392
1393 mul_v3_fl(grab_delta, 1.0f - normal_weight);
1394 madd_v3_v3fl(
1395 grab_delta, ss->cache->sculpt_normal_symm, (len_signed * normal_weight) * len_view_scale);
1396 }
1397
1398 /** \name SculptProjectVector
1399 *
1400 * Fast-path for #project_plane_v3_v3v3
1401 *
1402 * \{ */
1403
1404 typedef struct SculptProjectVector {
1405 float plane[3];
1406 float len_sq;
1407 float len_sq_inv_neg;
1408 bool is_valid;
1409
1410 } SculptProjectVector;
1411
1412 /**
1413 * \param plane: Direction, can be any length.
1414 */
sculpt_project_v3_cache_init(SculptProjectVector * spvc,const float plane[3])1415 static void sculpt_project_v3_cache_init(SculptProjectVector *spvc, const float plane[3])
1416 {
1417 copy_v3_v3(spvc->plane, plane);
1418 spvc->len_sq = len_squared_v3(spvc->plane);
1419 spvc->is_valid = (spvc->len_sq > FLT_EPSILON);
1420 spvc->len_sq_inv_neg = (spvc->is_valid) ? -1.0f / spvc->len_sq : 0.0f;
1421 }
1422
1423 /**
1424 * Calculate the projection.
1425 */
sculpt_project_v3(const SculptProjectVector * spvc,const float vec[3],float r_vec[3])1426 static void sculpt_project_v3(const SculptProjectVector *spvc, const float vec[3], float r_vec[3])
1427 {
1428 #if 0
1429 project_plane_v3_v3v3(r_vec, vec, spvc->plane);
1430 #else
1431 /* inline the projection, cache `-1.0 / dot_v3_v3(v_proj, v_proj)` */
1432 madd_v3_v3fl(r_vec, spvc->plane, dot_v3v3(vec, spvc->plane) * spvc->len_sq_inv_neg);
1433 #endif
1434 }
1435
1436 /** \} */
1437
1438 /**********************************************************************/
1439
1440 /* Returns true if the stroke will use dynamic topology, false
1441 * otherwise.
1442 *
1443 * Factors: some brushes like grab cannot do dynamic topology.
1444 * Others, like smooth, are better without.
1445 * Same goes for alt-key smoothing. */
SCULPT_stroke_is_dynamic_topology(const SculptSession * ss,const Brush * brush)1446 bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *brush)
1447 {
1448 return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
1449
1450 (!ss->cache || (!ss->cache->alt_smooth)) &&
1451
1452 /* Requires mesh restore, which doesn't work with
1453 * dynamic-topology. */
1454 !(brush->flag & BRUSH_ANCHORED) && !(brush->flag & BRUSH_DRAG_DOT) &&
1455
1456 SCULPT_TOOL_HAS_DYNTOPO(brush->sculpt_tool));
1457 }
1458
1459 /*** paint mesh ***/
1460
paint_mesh_restore_co_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))1461 static void paint_mesh_restore_co_task_cb(void *__restrict userdata,
1462 const int n,
1463 const TaskParallelTLS *__restrict UNUSED(tls))
1464 {
1465 SculptThreadedTaskData *data = userdata;
1466 SculptSession *ss = data->ob->sculpt;
1467
1468 SculptUndoNode *unode;
1469 SculptUndoType type = (data->brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
1470 SCULPT_UNDO_COORDS);
1471
1472 if (ss->bm) {
1473 unode = SCULPT_undo_push_node(data->ob, data->nodes[n], type);
1474 }
1475 else {
1476 unode = SCULPT_undo_get_node(data->nodes[n]);
1477 }
1478
1479 if (unode) {
1480 PBVHVertexIter vd;
1481 SculptOrigVertData orig_data;
1482
1483 SCULPT_orig_vert_data_unode_init(&orig_data, data->ob, unode);
1484
1485 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
1486 {
1487 SCULPT_orig_vert_data_update(&orig_data, &vd);
1488
1489 if (orig_data.unode->type == SCULPT_UNDO_COORDS) {
1490 copy_v3_v3(vd.co, orig_data.co);
1491 if (vd.no) {
1492 copy_v3_v3_short(vd.no, orig_data.no);
1493 }
1494 else {
1495 normal_short_to_float_v3(vd.fno, orig_data.no);
1496 }
1497 }
1498 else if (orig_data.unode->type == SCULPT_UNDO_MASK) {
1499 *vd.mask = orig_data.mask;
1500 }
1501 else if (orig_data.unode->type == SCULPT_UNDO_COLOR) {
1502 copy_v4_v4(vd.col, orig_data.col);
1503 }
1504
1505 if (vd.mvert) {
1506 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
1507 }
1508 }
1509 BKE_pbvh_vertex_iter_end;
1510
1511 BKE_pbvh_node_mark_update(data->nodes[n]);
1512 }
1513 }
1514
paint_mesh_restore_co(Sculpt * sd,Object * ob)1515 static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
1516 {
1517 SculptSession *ss = ob->sculpt;
1518 Brush *brush = BKE_paint_brush(&sd->paint);
1519
1520 PBVHNode **nodes;
1521 int totnode;
1522
1523 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
1524
1525 /**
1526 * Disable multi-threading when dynamic-topology is enabled. Otherwise,
1527 * new entries might be inserted by #SCULPT_undo_push_node() into the #GHash
1528 * used internally by #BM_log_original_vert_co() by a different thread. See T33787.
1529 */
1530 SculptThreadedTaskData data = {
1531 .sd = sd,
1532 .ob = ob,
1533 .brush = brush,
1534 .nodes = nodes,
1535 };
1536
1537 TaskParallelSettings settings;
1538 BKE_pbvh_parallel_range_settings(&settings, true && !ss->bm, totnode);
1539 BLI_task_parallel_range(0, totnode, &data, paint_mesh_restore_co_task_cb, &settings);
1540
1541 BKE_pbvh_node_color_buffer_free(ss->pbvh);
1542
1543 MEM_SAFE_FREE(nodes);
1544 }
1545
1546 /*** BVH Tree ***/
1547
sculpt_extend_redraw_rect_previous(Object * ob,rcti * rect)1548 static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
1549 {
1550 /* Expand redraw \a rect with redraw \a rect from previous step to
1551 * prevent partial-redraw issues caused by fast strokes. This is
1552 * needed here (not in sculpt_flush_update) as it was before
1553 * because redraw rectangle should be the same in both of
1554 * optimized PBVH draw function and 3d view redraw, if not -- some
1555 * mesh parts could disappear from screen (sergey). */
1556 SculptSession *ss = ob->sculpt;
1557
1558 if (ss->cache) {
1559 if (!BLI_rcti_is_empty(&ss->cache->previous_r)) {
1560 BLI_rcti_union(rect, &ss->cache->previous_r);
1561 }
1562 }
1563 }
1564
1565 /* Get a screen-space rectangle of the modified area. */
SCULPT_get_redraw_rect(ARegion * region,RegionView3D * rv3d,Object * ob,rcti * rect)1566 bool SCULPT_get_redraw_rect(ARegion *region, RegionView3D *rv3d, Object *ob, rcti *rect)
1567 {
1568 PBVH *pbvh = ob->sculpt->pbvh;
1569 float bb_min[3], bb_max[3];
1570
1571 if (!pbvh) {
1572 return false;
1573 }
1574
1575 BKE_pbvh_redraw_BB(pbvh, bb_min, bb_max);
1576
1577 /* Convert 3D bounding box to screen space. */
1578 if (!paint_convert_bb_to_rect(rect, bb_min, bb_max, region, rv3d, ob)) {
1579 return false;
1580 }
1581
1582 return true;
1583 }
1584
ED_sculpt_redraw_planes_get(float planes[4][4],ARegion * region,Object * ob)1585 void ED_sculpt_redraw_planes_get(float planes[4][4], ARegion *region, Object *ob)
1586 {
1587 PBVH *pbvh = ob->sculpt->pbvh;
1588 /* Copy here, original will be used below. */
1589 rcti rect = ob->sculpt->cache->current_r;
1590
1591 sculpt_extend_redraw_rect_previous(ob, &rect);
1592
1593 paint_calc_redraw_planes(planes, region, ob, &rect);
1594
1595 /* We will draw this \a rect, so now we can set it as the previous partial \a rect.
1596 * Note that we don't update with the union of previous/current (\a rect), only with
1597 * the current. Thus we avoid the rectangle needlessly growing to include
1598 * all the stroke area. */
1599 ob->sculpt->cache->previous_r = ob->sculpt->cache->current_r;
1600
1601 /* Clear redraw flag from nodes. */
1602 if (pbvh) {
1603 BKE_pbvh_update_bounds(pbvh, PBVH_UpdateRedraw);
1604 }
1605 }
1606
1607 /************************ Brush Testing *******************/
1608
SCULPT_brush_test_init(SculptSession * ss,SculptBrushTest * test)1609 void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test)
1610 {
1611 RegionView3D *rv3d = ss->cache ? ss->cache->vc->rv3d : ss->rv3d;
1612 View3D *v3d = ss->cache ? ss->cache->vc->v3d : ss->v3d;
1613
1614 test->radius_squared = ss->cache ? ss->cache->radius_squared :
1615 ss->cursor_radius * ss->cursor_radius;
1616 test->radius = sqrtf(test->radius_squared);
1617
1618 if (ss->cache) {
1619 copy_v3_v3(test->location, ss->cache->location);
1620 test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass;
1621 test->radial_symmetry_pass = ss->cache->radial_symmetry_pass;
1622 copy_m4_m4(test->symm_rot_mat_inv, ss->cache->symm_rot_mat_inv);
1623 }
1624 else {
1625 copy_v3_v3(test->location, ss->cursor_location);
1626 test->mirror_symmetry_pass = 0;
1627 test->radial_symmetry_pass = 0;
1628 unit_m4(test->symm_rot_mat_inv);
1629 }
1630
1631 /* Just for initialize. */
1632 test->dist = 0.0f;
1633
1634 /* Only for 2D projection. */
1635 zero_v4(test->plane_view);
1636 zero_v4(test->plane_tool);
1637
1638 if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
1639 test->clip_rv3d = rv3d;
1640 }
1641 else {
1642 test->clip_rv3d = NULL;
1643 }
1644 }
1645
sculpt_brush_test_clipping(const SculptBrushTest * test,const float co[3])1646 BLI_INLINE bool sculpt_brush_test_clipping(const SculptBrushTest *test, const float co[3])
1647 {
1648 RegionView3D *rv3d = test->clip_rv3d;
1649 if (!rv3d) {
1650 return false;
1651 }
1652 float symm_co[3];
1653 flip_v3_v3(symm_co, co, test->mirror_symmetry_pass);
1654 if (test->radial_symmetry_pass) {
1655 mul_m4_v3(test->symm_rot_mat_inv, symm_co);
1656 }
1657 return ED_view3d_clipping_test(rv3d, symm_co, true);
1658 }
1659
SCULPT_brush_test_sphere(SculptBrushTest * test,const float co[3])1660 bool SCULPT_brush_test_sphere(SculptBrushTest *test, const float co[3])
1661 {
1662 float distsq = len_squared_v3v3(co, test->location);
1663
1664 if (distsq <= test->radius_squared) {
1665 if (sculpt_brush_test_clipping(test, co)) {
1666 return false;
1667 }
1668 test->dist = sqrtf(distsq);
1669 return true;
1670 }
1671 return false;
1672 }
1673
SCULPT_brush_test_sphere_sq(SculptBrushTest * test,const float co[3])1674 bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
1675 {
1676 float distsq = len_squared_v3v3(co, test->location);
1677
1678 if (distsq <= test->radius_squared) {
1679 if (sculpt_brush_test_clipping(test, co)) {
1680 return false;
1681 }
1682 test->dist = distsq;
1683 return true;
1684 }
1685 return false;
1686 }
1687
SCULPT_brush_test_sphere_fast(const SculptBrushTest * test,const float co[3])1688 bool SCULPT_brush_test_sphere_fast(const SculptBrushTest *test, const float co[3])
1689 {
1690 if (sculpt_brush_test_clipping(test, co)) {
1691 return false;
1692 }
1693 return len_squared_v3v3(co, test->location) <= test->radius_squared;
1694 }
1695
SCULPT_brush_test_circle_sq(SculptBrushTest * test,const float co[3])1696 bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
1697 {
1698 float co_proj[3];
1699 closest_to_plane_normalized_v3(co_proj, test->plane_view, co);
1700 float distsq = len_squared_v3v3(co_proj, test->location);
1701
1702 if (distsq <= test->radius_squared) {
1703 if (sculpt_brush_test_clipping(test, co)) {
1704 return false;
1705 }
1706 test->dist = distsq;
1707 return true;
1708 }
1709 return false;
1710 }
1711
SCULPT_brush_test_cube(SculptBrushTest * test,const float co[3],const float local[4][4],const float roundness)1712 bool SCULPT_brush_test_cube(SculptBrushTest *test,
1713 const float co[3],
1714 const float local[4][4],
1715 const float roundness)
1716 {
1717 float side = M_SQRT1_2;
1718 float local_co[3];
1719
1720 if (sculpt_brush_test_clipping(test, co)) {
1721 return false;
1722 }
1723
1724 mul_v3_m4v3(local_co, local, co);
1725
1726 local_co[0] = fabsf(local_co[0]);
1727 local_co[1] = fabsf(local_co[1]);
1728 local_co[2] = fabsf(local_co[2]);
1729
1730 /* Keep the square and circular brush tips the same size. */
1731 side += (1.0f - side) * roundness;
1732
1733 const float hardness = 1.0f - roundness;
1734 const float constant_side = hardness * side;
1735 const float falloff_side = roundness * side;
1736
1737 if (local_co[0] <= side && local_co[1] <= side && local_co[2] <= side) {
1738 /* Corner, distance to the center of the corner circle. */
1739 if (min_ff(local_co[0], local_co[1]) > constant_side) {
1740 float r_point[3];
1741 copy_v3_fl(r_point, constant_side);
1742 test->dist = len_v2v2(r_point, local_co) / falloff_side;
1743 return true;
1744 }
1745 /* Side, distance to the square XY axis. */
1746 if (max_ff(local_co[0], local_co[1]) > constant_side) {
1747 test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
1748 return true;
1749 }
1750 /* Inside the square, constant distance. */
1751 test->dist = 0.0f;
1752 return true;
1753 }
1754 /* Outside the square. */
1755 return false;
1756 }
1757
SCULPT_brush_test_init_with_falloff_shape(SculptSession * ss,SculptBrushTest * test,char falloff_shape)1758 SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
1759 SculptBrushTest *test,
1760 char falloff_shape)
1761 {
1762 SCULPT_brush_test_init(ss, test);
1763 SculptBrushTestFn sculpt_brush_test_sq_fn;
1764 if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
1765 sculpt_brush_test_sq_fn = SCULPT_brush_test_sphere_sq;
1766 }
1767 else {
1768 /* PAINT_FALLOFF_SHAPE_TUBE */
1769 plane_from_point_normal_v3(test->plane_view, test->location, ss->cache->view_normal);
1770 sculpt_brush_test_sq_fn = SCULPT_brush_test_circle_sq;
1771 }
1772 return sculpt_brush_test_sq_fn;
1773 }
1774
SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession * ss,char falloff_shape)1775 const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss,
1776 char falloff_shape)
1777 {
1778 if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
1779 return ss->cache->sculpt_normal_symm;
1780 }
1781 /* PAINT_FALLOFF_SHAPE_TUBE */
1782 return ss->cache->view_normal;
1783 }
1784
frontface(const Brush * br,const float sculpt_normal[3],const short no[3],const float fno[3])1785 static float frontface(const Brush *br,
1786 const float sculpt_normal[3],
1787 const short no[3],
1788 const float fno[3])
1789 {
1790 if (br->flag & BRUSH_FRONTFACE) {
1791 float dot;
1792
1793 if (no) {
1794 float tmp[3];
1795
1796 normal_short_to_float_v3(tmp, no);
1797 dot = dot_v3v3(tmp, sculpt_normal);
1798 }
1799 else {
1800 dot = dot_v3v3(fno, sculpt_normal);
1801 }
1802 return dot > 0.0f ? dot : 0.0f;
1803 }
1804 return 1.0f;
1805 }
1806
1807 #if 0
1808
1809 static bool sculpt_brush_test_cyl(SculptBrushTest *test,
1810 float co[3],
1811 float location[3],
1812 const float area_no[3])
1813 {
1814 if (sculpt_brush_test_sphere_fast(test, co)) {
1815 float t1[3], t2[3], t3[3], dist;
1816
1817 sub_v3_v3v3(t1, location, co);
1818 sub_v3_v3v3(t2, x2, location);
1819
1820 cross_v3_v3v3(t3, area_no, t1);
1821
1822 dist = len_v3(t3) / len_v3(t2);
1823
1824 test->dist = dist;
1825
1826 return true;
1827 }
1828
1829 return false;
1830 }
1831
1832 #endif
1833
1834 /* ===== Sculpting =====
1835 */
flip_v3(float v[3],const ePaintSymmetryFlags symm)1836 static void flip_v3(float v[3], const ePaintSymmetryFlags symm)
1837 {
1838 flip_v3_v3(v, v, symm);
1839 }
1840
flip_qt(float quat[3],const ePaintSymmetryFlags symm)1841 static void flip_qt(float quat[3], const ePaintSymmetryFlags symm)
1842 {
1843 flip_qt_qt(quat, quat, symm);
1844 }
1845
calc_overlap(StrokeCache * cache,const char symm,const char axis,const float angle)1846 static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle)
1847 {
1848 float mirror[3];
1849 float distsq;
1850
1851 flip_v3_v3(mirror, cache->true_location, symm);
1852
1853 if (axis != 0) {
1854 float mat[3][3];
1855 axis_angle_to_mat3_single(mat, axis, angle);
1856 mul_m3_v3(mat, mirror);
1857 }
1858
1859 distsq = len_squared_v3v3(mirror, cache->true_location);
1860
1861 if (distsq <= 4.0f * (cache->radius_squared)) {
1862 return (2.0f * (cache->radius) - sqrtf(distsq)) / (2.0f * (cache->radius));
1863 }
1864 return 0.0f;
1865 }
1866
calc_radial_symmetry_feather(Sculpt * sd,StrokeCache * cache,const char symm,const char axis)1867 static float calc_radial_symmetry_feather(Sculpt *sd,
1868 StrokeCache *cache,
1869 const char symm,
1870 const char axis)
1871 {
1872 float overlap = 0.0f;
1873
1874 for (int i = 1; i < sd->radial_symm[axis - 'X']; i++) {
1875 const float angle = 2.0f * M_PI * i / sd->radial_symm[axis - 'X'];
1876 overlap += calc_overlap(cache, symm, axis, angle);
1877 }
1878
1879 return overlap;
1880 }
1881
calc_symmetry_feather(Sculpt * sd,StrokeCache * cache)1882 static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache)
1883 {
1884 if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
1885 float overlap;
1886 const int symm = cache->symmetry;
1887
1888 overlap = 0.0f;
1889 for (int i = 0; i <= symm; i++) {
1890 if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
1891
1892 overlap += calc_overlap(cache, i, 0, 0);
1893
1894 overlap += calc_radial_symmetry_feather(sd, cache, i, 'X');
1895 overlap += calc_radial_symmetry_feather(sd, cache, i, 'Y');
1896 overlap += calc_radial_symmetry_feather(sd, cache, i, 'Z');
1897 }
1898 }
1899
1900 return 1.0f / overlap;
1901 }
1902 return 1.0f;
1903 }
1904
1905 /** \name Calculate Normal and Center
1906 *
1907 * Calculate geometry surrounding the brush center.
1908 * (optionally using original coordinates).
1909 *
1910 * Functions are:
1911 * - #calc_area_center
1912 * - #calc_area_normal
1913 * - #calc_area_normal_and_center
1914 *
1915 * \note These are all _very_ similar, when changing one, check others.
1916 * \{ */
1917
1918 typedef struct AreaNormalCenterTLSData {
1919 /* 0 = towards view, 1 = flipped */
1920 float area_cos[2][3];
1921 float area_nos[2][3];
1922 int count_no[2];
1923 int count_co[2];
1924 } AreaNormalCenterTLSData;
1925
calc_area_normal_and_center_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)1926 static void calc_area_normal_and_center_task_cb(void *__restrict userdata,
1927 const int n,
1928 const TaskParallelTLS *__restrict tls)
1929 {
1930 SculptThreadedTaskData *data = userdata;
1931 SculptSession *ss = data->ob->sculpt;
1932 AreaNormalCenterTLSData *anctd = tls->userdata_chunk;
1933 const bool use_area_nos = data->use_area_nos;
1934 const bool use_area_cos = data->use_area_cos;
1935
1936 PBVHVertexIter vd;
1937 SculptUndoNode *unode = NULL;
1938
1939 bool use_original = false;
1940 bool normal_test_r, area_test_r;
1941
1942 if (ss->cache && ss->cache->original) {
1943 unode = SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
1944 use_original = (unode->co || unode->bm_entry);
1945 }
1946
1947 SculptBrushTest normal_test;
1948 SculptBrushTestFn sculpt_brush_normal_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
1949 ss, &normal_test, data->brush->falloff_shape);
1950
1951 /* Update the test radius to sample the normal using the normal radius of the brush. */
1952 if (data->brush->ob_mode == OB_MODE_SCULPT) {
1953 float test_radius = sqrtf(normal_test.radius_squared);
1954 test_radius *= data->brush->normal_radius_factor;
1955 normal_test.radius = test_radius;
1956 normal_test.radius_squared = test_radius * test_radius;
1957 }
1958
1959 SculptBrushTest area_test;
1960 SculptBrushTestFn sculpt_brush_area_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
1961 ss, &area_test, data->brush->falloff_shape);
1962
1963 if (data->brush->ob_mode == OB_MODE_SCULPT) {
1964 float test_radius = sqrtf(area_test.radius_squared);
1965 /* Layer brush produces artifacts with normal and area radius */
1966 /* Enable area radius control only on Scrape for now */
1967 if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
1968 data->brush->area_radius_factor > 0.0f) {
1969 test_radius *= data->brush->area_radius_factor;
1970 if (ss->cache && data->brush->flag2 & BRUSH_AREA_RADIUS_PRESSURE) {
1971 test_radius *= ss->cache->pressure;
1972 }
1973 }
1974 else {
1975 test_radius *= data->brush->normal_radius_factor;
1976 }
1977 area_test.radius = test_radius;
1978 area_test.radius_squared = test_radius * test_radius;
1979 }
1980
1981 /* When the mesh is edited we can't rely on original coords
1982 * (original mesh may not even have verts in brush radius). */
1983 if (use_original && data->has_bm_orco) {
1984 float(*orco_coords)[3];
1985 int(*orco_tris)[3];
1986 int orco_tris_num;
1987
1988 BKE_pbvh_node_get_bm_orco_data(data->nodes[n], &orco_tris, &orco_tris_num, &orco_coords);
1989
1990 for (int i = 0; i < orco_tris_num; i++) {
1991 const float *co_tri[3] = {
1992 orco_coords[orco_tris[i][0]],
1993 orco_coords[orco_tris[i][1]],
1994 orco_coords[orco_tris[i][2]],
1995 };
1996 float co[3];
1997
1998 closest_on_tri_to_point_v3(co, normal_test.location, UNPACK3(co_tri));
1999
2000 normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
2001 area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
2002
2003 if (normal_test_r || area_test_r) {
2004 float no[3];
2005 int flip_index;
2006
2007 normal_tri_v3(no, UNPACK3(co_tri));
2008
2009 flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f);
2010 if (use_area_cos && area_test_r) {
2011 /* Weight the coordinates towards the center. */
2012 float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
2013 const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2014
2015 float disp[3];
2016 sub_v3_v3v3(disp, co, area_test.location);
2017 mul_v3_fl(disp, 1.0f - afactor);
2018 add_v3_v3v3(co, area_test.location, disp);
2019 add_v3_v3(anctd->area_cos[flip_index], co);
2020
2021 anctd->count_co[flip_index] += 1;
2022 }
2023 if (use_area_nos && normal_test_r) {
2024 /* Weight the normals towards the center. */
2025 float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
2026 const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2027 mul_v3_fl(no, nfactor);
2028
2029 add_v3_v3(anctd->area_nos[flip_index], no);
2030 anctd->count_no[flip_index] += 1;
2031 }
2032 }
2033 }
2034 }
2035 else {
2036 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2037 {
2038 float co[3];
2039
2040 /* For bm_vert only. */
2041 short no_s[3];
2042
2043 if (use_original) {
2044 if (unode->bm_entry) {
2045 const float *temp_co;
2046 const short *temp_no_s;
2047 BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &temp_co, &temp_no_s);
2048 copy_v3_v3(co, temp_co);
2049 copy_v3_v3_short(no_s, temp_no_s);
2050 }
2051 else {
2052 copy_v3_v3(co, unode->co[vd.i]);
2053 copy_v3_v3_short(no_s, unode->no[vd.i]);
2054 }
2055 }
2056 else {
2057 copy_v3_v3(co, vd.co);
2058 }
2059
2060 normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
2061 area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
2062
2063 if (normal_test_r || area_test_r) {
2064 float no[3];
2065 int flip_index;
2066
2067 data->any_vertex_sampled = true;
2068
2069 if (use_original) {
2070 normal_short_to_float_v3(no, no_s);
2071 }
2072 else {
2073 if (vd.no) {
2074 normal_short_to_float_v3(no, vd.no);
2075 }
2076 else {
2077 copy_v3_v3(no, vd.fno);
2078 }
2079 }
2080
2081 flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
2082 0.0f);
2083
2084 if (use_area_cos && area_test_r) {
2085 /* Weight the coordinates towards the center. */
2086 float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
2087 const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2088
2089 float disp[3];
2090 sub_v3_v3v3(disp, co, area_test.location);
2091 mul_v3_fl(disp, 1.0f - afactor);
2092 add_v3_v3v3(co, area_test.location, disp);
2093
2094 add_v3_v3(anctd->area_cos[flip_index], co);
2095 anctd->count_co[flip_index] += 1;
2096 }
2097 if (use_area_nos && normal_test_r) {
2098 /* Weight the normals towards the center. */
2099 float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
2100 const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2101 mul_v3_fl(no, nfactor);
2102
2103 add_v3_v3(anctd->area_nos[flip_index], no);
2104 anctd->count_no[flip_index] += 1;
2105 }
2106 }
2107 }
2108 BKE_pbvh_vertex_iter_end;
2109 }
2110 }
2111
calc_area_normal_and_center_reduce(const void * __restrict UNUSED (userdata),void * __restrict chunk_join,void * __restrict chunk)2112 static void calc_area_normal_and_center_reduce(const void *__restrict UNUSED(userdata),
2113 void *__restrict chunk_join,
2114 void *__restrict chunk)
2115 {
2116 AreaNormalCenterTLSData *join = chunk_join;
2117 AreaNormalCenterTLSData *anctd = chunk;
2118
2119 /* For flatten center. */
2120 add_v3_v3(join->area_cos[0], anctd->area_cos[0]);
2121 add_v3_v3(join->area_cos[1], anctd->area_cos[1]);
2122
2123 /* For area normal. */
2124 add_v3_v3(join->area_nos[0], anctd->area_nos[0]);
2125 add_v3_v3(join->area_nos[1], anctd->area_nos[1]);
2126
2127 /* Weights. */
2128 add_v2_v2_int(join->count_no, anctd->count_no);
2129 add_v2_v2_int(join->count_co, anctd->count_co);
2130 }
2131
calc_area_center(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_co[3])2132 static void calc_area_center(
2133 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3])
2134 {
2135 const Brush *brush = BKE_paint_brush(&sd->paint);
2136 SculptSession *ss = ob->sculpt;
2137 const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush);
2138 int n;
2139
2140 /* Intentionally set 'sd' to NULL since we share logic with vertex paint. */
2141 SculptThreadedTaskData data = {
2142 .sd = NULL,
2143 .ob = ob,
2144 .brush = brush,
2145 .nodes = nodes,
2146 .totnode = totnode,
2147 .has_bm_orco = has_bm_orco,
2148 .use_area_cos = true,
2149 };
2150
2151 AreaNormalCenterTLSData anctd = {{{0}}};
2152
2153 TaskParallelSettings settings;
2154 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2155 settings.func_reduce = calc_area_normal_and_center_reduce;
2156 settings.userdata_chunk = &anctd;
2157 settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
2158 BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
2159
2160 /* For flatten center. */
2161 for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
2162 if (anctd.count_co[n] != 0) {
2163 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
2164 break;
2165 }
2166 }
2167
2168 if (n == 2) {
2169 zero_v3(r_area_co);
2170 }
2171
2172 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
2173 if (ss->cache) {
2174 copy_v3_v3(r_area_co, ss->cache->location);
2175 }
2176 }
2177 }
2178
SCULPT_calc_area_normal(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_no[3])2179 void SCULPT_calc_area_normal(
2180 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
2181 {
2182 const Brush *brush = BKE_paint_brush(&sd->paint);
2183 SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, r_area_no);
2184 }
2185
2186 /* Expose 'calc_area_normal' externally. */
SCULPT_pbvh_calc_area_normal(const Brush * brush,Object * ob,PBVHNode ** nodes,int totnode,bool use_threading,float r_area_no[3])2187 bool SCULPT_pbvh_calc_area_normal(const Brush *brush,
2188 Object *ob,
2189 PBVHNode **nodes,
2190 int totnode,
2191 bool use_threading,
2192 float r_area_no[3])
2193 {
2194 SculptSession *ss = ob->sculpt;
2195 const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush);
2196
2197 /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */
2198 SculptThreadedTaskData data = {
2199 .sd = NULL,
2200 .ob = ob,
2201 .brush = brush,
2202 .nodes = nodes,
2203 .totnode = totnode,
2204 .has_bm_orco = has_bm_orco,
2205 .use_area_nos = true,
2206 .any_vertex_sampled = false,
2207 };
2208
2209 AreaNormalCenterTLSData anctd = {{{0}}};
2210
2211 TaskParallelSettings settings;
2212 BKE_pbvh_parallel_range_settings(&settings, use_threading, totnode);
2213 settings.func_reduce = calc_area_normal_and_center_reduce;
2214 settings.userdata_chunk = &anctd;
2215 settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
2216 BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
2217
2218 /* For area normal. */
2219 for (int i = 0; i < ARRAY_SIZE(anctd.area_nos); i++) {
2220 if (normalize_v3_v3(r_area_no, anctd.area_nos[i]) != 0.0f) {
2221 break;
2222 }
2223 }
2224
2225 return data.any_vertex_sampled;
2226 }
2227
2228 /* This calculates flatten center and area normal together,
2229 * amortizing the memory bandwidth and loop overhead to calculate both at the same time. */
calc_area_normal_and_center(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_no[3],float r_area_co[3])2230 static void calc_area_normal_and_center(
2231 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
2232 {
2233 const Brush *brush = BKE_paint_brush(&sd->paint);
2234 SculptSession *ss = ob->sculpt;
2235 const bool has_bm_orco = ss->bm && SCULPT_stroke_is_dynamic_topology(ss, brush);
2236 int n;
2237
2238 /* Intentionally set 'sd' to NULL since this is used for vertex paint too. */
2239 SculptThreadedTaskData data = {
2240 .sd = NULL,
2241 .ob = ob,
2242 .brush = brush,
2243 .nodes = nodes,
2244 .totnode = totnode,
2245 .has_bm_orco = has_bm_orco,
2246 .use_area_cos = true,
2247 .use_area_nos = true,
2248 };
2249
2250 AreaNormalCenterTLSData anctd = {{{0}}};
2251
2252 TaskParallelSettings settings;
2253 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2254 settings.func_reduce = calc_area_normal_and_center_reduce;
2255 settings.userdata_chunk = &anctd;
2256 settings.userdata_chunk_size = sizeof(AreaNormalCenterTLSData);
2257 BLI_task_parallel_range(0, totnode, &data, calc_area_normal_and_center_task_cb, &settings);
2258
2259 /* For flatten center. */
2260 for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
2261 if (anctd.count_co[n] != 0) {
2262 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
2263 break;
2264 }
2265 }
2266
2267 if (n == 2) {
2268 zero_v3(r_area_co);
2269 }
2270
2271 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
2272 if (ss->cache) {
2273 copy_v3_v3(r_area_co, ss->cache->location);
2274 }
2275 }
2276
2277 /* For area normal. */
2278 for (n = 0; n < ARRAY_SIZE(anctd.area_nos); n++) {
2279 if (normalize_v3_v3(r_area_no, anctd.area_nos[n]) != 0.0f) {
2280 break;
2281 }
2282 }
2283 }
2284
2285 /** \} */
2286
2287 /**
2288 * Return modified brush strength. Includes the direction of the brush, positive
2289 * values pull vertices, negative values push. Uses tablet pressure and a
2290 * special multiplier found experimentally to scale the strength factor.
2291 */
brush_strength(const Sculpt * sd,const StrokeCache * cache,const float feather,const UnifiedPaintSettings * ups)2292 static float brush_strength(const Sculpt *sd,
2293 const StrokeCache *cache,
2294 const float feather,
2295 const UnifiedPaintSettings *ups)
2296 {
2297 const Scene *scene = cache->vc->scene;
2298 const Brush *brush = BKE_paint_brush((Paint *)&sd->paint);
2299
2300 /* Primary strength input; square it to make lower values more sensitive. */
2301 const float root_alpha = BKE_brush_alpha_get(scene, brush);
2302 const float alpha = root_alpha * root_alpha;
2303 const float dir = (brush->flag & BRUSH_DIR_IN) ? -1.0f : 1.0f;
2304 const float pressure = BKE_brush_use_alpha_pressure(brush) ? cache->pressure : 1.0f;
2305 const float pen_flip = cache->pen_flip ? -1.0f : 1.0f;
2306 const float invert = cache->invert ? -1.0f : 1.0f;
2307 float overlap = ups->overlap_factor;
2308 /* Spacing is integer percentage of radius, divide by 50 to get
2309 * normalized diameter. */
2310
2311 float flip = dir * invert * pen_flip;
2312 if (brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
2313 flip = 1.0f;
2314 }
2315
2316 /* Pressure final value after being tweaked depending on the brush. */
2317 float final_pressure;
2318
2319 switch (brush->sculpt_tool) {
2320 case SCULPT_TOOL_CLAY:
2321 final_pressure = pow4f(pressure);
2322 overlap = (1.0f + overlap) / 2.0f;
2323 return 0.25f * alpha * flip * final_pressure * overlap * feather;
2324 case SCULPT_TOOL_DRAW:
2325 case SCULPT_TOOL_DRAW_SHARP:
2326 case SCULPT_TOOL_LAYER:
2327 return alpha * flip * pressure * overlap * feather;
2328 case SCULPT_TOOL_DISPLACEMENT_ERASER:
2329 return alpha * pressure * overlap * feather;
2330 case SCULPT_TOOL_CLOTH:
2331 if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
2332 /* Grab deform uses the same falloff as a regular grab brush. */
2333 return root_alpha * feather;
2334 }
2335 else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
2336 return root_alpha * feather * pressure * overlap;
2337 }
2338 else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_EXPAND) {
2339 /* Expand is more sensible to strength as it keeps expanding the cloth when sculpting over
2340 * the same vertices. */
2341 return 0.1f * alpha * flip * pressure * overlap * feather;
2342 }
2343 else {
2344 /* Multiply by 10 by default to get a larger range of strength depending on the size of the
2345 * brush and object. */
2346 return 10.0f * alpha * flip * pressure * overlap * feather;
2347 }
2348 case SCULPT_TOOL_DRAW_FACE_SETS:
2349 return alpha * pressure * overlap * feather;
2350 case SCULPT_TOOL_SLIDE_RELAX:
2351 return alpha * pressure * overlap * feather * 2.0f;
2352 case SCULPT_TOOL_PAINT:
2353 final_pressure = pressure * pressure;
2354 return final_pressure * overlap * feather;
2355 case SCULPT_TOOL_SMEAR:
2356 return pressure * overlap * feather;
2357 case SCULPT_TOOL_CLAY_STRIPS:
2358 /* Clay Strips needs less strength to compensate the curve. */
2359 final_pressure = powf(pressure, 1.5f);
2360 return alpha * flip * final_pressure * overlap * feather * 0.3f;
2361 case SCULPT_TOOL_CLAY_THUMB:
2362 final_pressure = pressure * pressure;
2363 return alpha * flip * final_pressure * overlap * feather * 1.3f;
2364
2365 case SCULPT_TOOL_MASK:
2366 overlap = (1.0f + overlap) / 2.0f;
2367 switch ((BrushMaskTool)brush->mask_tool) {
2368 case BRUSH_MASK_DRAW:
2369 return alpha * flip * pressure * overlap * feather;
2370 case BRUSH_MASK_SMOOTH:
2371 return alpha * pressure * feather;
2372 }
2373 BLI_assert(!"Not supposed to happen");
2374 return 0.0f;
2375
2376 case SCULPT_TOOL_CREASE:
2377 case SCULPT_TOOL_BLOB:
2378 return alpha * flip * pressure * overlap * feather;
2379
2380 case SCULPT_TOOL_INFLATE:
2381 if (flip > 0.0f) {
2382 return 0.250f * alpha * flip * pressure * overlap * feather;
2383 }
2384 else {
2385 return 0.125f * alpha * flip * pressure * overlap * feather;
2386 }
2387
2388 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
2389 overlap = (1.0f + overlap) / 2.0f;
2390 return alpha * flip * pressure * overlap * feather;
2391
2392 case SCULPT_TOOL_FILL:
2393 case SCULPT_TOOL_SCRAPE:
2394 case SCULPT_TOOL_FLATTEN:
2395 if (flip > 0.0f) {
2396 overlap = (1.0f + overlap) / 2.0f;
2397 return alpha * flip * pressure * overlap * feather;
2398 }
2399 else {
2400 /* Reduce strength for DEEPEN, PEAKS, and CONTRAST. */
2401 return 0.5f * alpha * flip * pressure * overlap * feather;
2402 }
2403
2404 case SCULPT_TOOL_SMOOTH:
2405 return flip * alpha * pressure * feather;
2406
2407 case SCULPT_TOOL_PINCH:
2408 if (flip > 0.0f) {
2409 return alpha * flip * pressure * overlap * feather;
2410 }
2411 else {
2412 return 0.25f * alpha * flip * pressure * overlap * feather;
2413 }
2414
2415 case SCULPT_TOOL_NUDGE:
2416 overlap = (1.0f + overlap) / 2.0f;
2417 return alpha * pressure * overlap * feather;
2418
2419 case SCULPT_TOOL_THUMB:
2420 return alpha * pressure * feather;
2421
2422 case SCULPT_TOOL_SNAKE_HOOK:
2423 return root_alpha * feather;
2424
2425 case SCULPT_TOOL_GRAB:
2426 return root_alpha * feather;
2427
2428 case SCULPT_TOOL_ROTATE:
2429 return alpha * pressure * feather;
2430
2431 case SCULPT_TOOL_ELASTIC_DEFORM:
2432 case SCULPT_TOOL_POSE:
2433 case SCULPT_TOOL_BOUNDARY:
2434 return root_alpha * feather;
2435
2436 default:
2437 return 0.0f;
2438 }
2439 }
2440
2441 /* Return a multiplier for brush strength on a particular vertex. */
SCULPT_brush_strength_factor(SculptSession * ss,const Brush * br,const float brush_point[3],const float len,const short vno[3],const float fno[3],const float mask,const int vertex_index,const int thread_id)2442 float SCULPT_brush_strength_factor(SculptSession *ss,
2443 const Brush *br,
2444 const float brush_point[3],
2445 const float len,
2446 const short vno[3],
2447 const float fno[3],
2448 const float mask,
2449 const int vertex_index,
2450 const int thread_id)
2451 {
2452 StrokeCache *cache = ss->cache;
2453 const Scene *scene = cache->vc->scene;
2454 const MTex *mtex = &br->mtex;
2455 float avg = 1.0f;
2456 float rgba[4];
2457 float point[3];
2458
2459 sub_v3_v3v3(point, brush_point, cache->plane_offset);
2460
2461 if (!mtex->tex) {
2462 avg = 1.0f;
2463 }
2464 else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
2465 /* Get strength by feeding the vertex location directly into a texture. */
2466 avg = BKE_brush_sample_tex_3d(scene, br, point, rgba, 0, ss->tex_pool);
2467 }
2468 else if (ss->texcache) {
2469 float symm_point[3], point_2d[2];
2470 /* Quite warnings. */
2471 float x = 0.0f, y = 0.0f;
2472
2473 /* If the active area is being applied for symmetry, flip it
2474 * across the symmetry axis and rotate it back to the original
2475 * position in order to project it. This insures that the
2476 * brush texture will be oriented correctly. */
2477
2478 flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass);
2479
2480 if (cache->radial_symmetry_pass) {
2481 mul_m4_v3(cache->symm_rot_mat_inv, symm_point);
2482 }
2483
2484 ED_view3d_project_float_v2_m4(cache->vc->region, symm_point, point_2d, cache->projection_mat);
2485
2486 /* Still no symmetry supported for other paint modes.
2487 * Sculpt does it DIY. */
2488 if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
2489 /* Similar to fixed mode, but projects from brush angle
2490 * rather than view direction. */
2491
2492 mul_m4_v3(cache->brush_local_mat, symm_point);
2493
2494 x = symm_point[0];
2495 y = symm_point[1];
2496
2497 x *= br->mtex.size[0];
2498 y *= br->mtex.size[1];
2499
2500 x += br->mtex.ofs[0];
2501 y += br->mtex.ofs[1];
2502
2503 avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool, thread_id);
2504
2505 avg += br->texture_sample_bias;
2506 }
2507 else {
2508 const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
2509 avg = BKE_brush_sample_tex_3d(scene, br, point_3d, rgba, 0, ss->tex_pool);
2510 }
2511 }
2512
2513 /* Hardness. */
2514 float final_len = len;
2515 const float hardness = cache->paint_brush.hardness;
2516 float p = len / cache->radius;
2517 if (p < hardness) {
2518 final_len = 0.0f;
2519 }
2520 else if (hardness == 1.0f) {
2521 final_len = cache->radius;
2522 }
2523 else {
2524 p = (p - hardness) / (1.0f - hardness);
2525 final_len = p * cache->radius;
2526 }
2527
2528 /* Falloff curve. */
2529 avg *= BKE_brush_curve_strength(br, final_len, cache->radius);
2530 avg *= frontface(br, cache->view_normal, vno, fno);
2531
2532 /* Paint mask. */
2533 avg *= 1.0f - mask;
2534
2535 /* Auto-masking. */
2536 avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex_index);
2537
2538 return avg;
2539 }
2540
2541 /* Test AABB against sphere. */
SCULPT_search_sphere_cb(PBVHNode * node,void * data_v)2542 bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v)
2543 {
2544 SculptSearchSphereData *data = data_v;
2545 const float *center;
2546 float nearest[3];
2547 if (data->center) {
2548 center = data->center;
2549 }
2550 else {
2551 center = data->ss->cache ? data->ss->cache->location : data->ss->cursor_location;
2552 }
2553 float t[3], bb_min[3], bb_max[3];
2554
2555 if (data->ignore_fully_ineffective) {
2556 if (BKE_pbvh_node_fully_hidden_get(node)) {
2557 return false;
2558 }
2559 if (BKE_pbvh_node_fully_masked_get(node)) {
2560 return false;
2561 }
2562 }
2563
2564 if (data->original) {
2565 BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
2566 }
2567 else {
2568 BKE_pbvh_node_get_BB(node, bb_min, bb_max);
2569 }
2570
2571 for (int i = 0; i < 3; i++) {
2572 if (bb_min[i] > center[i]) {
2573 nearest[i] = bb_min[i];
2574 }
2575 else if (bb_max[i] < center[i]) {
2576 nearest[i] = bb_max[i];
2577 }
2578 else {
2579 nearest[i] = center[i];
2580 }
2581 }
2582
2583 sub_v3_v3v3(t, center, nearest);
2584
2585 return len_squared_v3(t) < data->radius_squared;
2586 }
2587
2588 /* 2D projection (distance to line). */
SCULPT_search_circle_cb(PBVHNode * node,void * data_v)2589 bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v)
2590 {
2591 SculptSearchCircleData *data = data_v;
2592 float bb_min[3], bb_max[3];
2593
2594 if (data->ignore_fully_ineffective) {
2595 if (BKE_pbvh_node_fully_masked_get(node)) {
2596 return false;
2597 }
2598 }
2599
2600 if (data->original) {
2601 BKE_pbvh_node_get_original_BB(node, bb_min, bb_max);
2602 }
2603 else {
2604 BKE_pbvh_node_get_BB(node, bb_min, bb_min);
2605 }
2606
2607 float dummy_co[3], dummy_depth;
2608 const float dist_sq = dist_squared_ray_to_aabb_v3(
2609 data->dist_ray_to_aabb_precalc, bb_min, bb_max, dummy_co, &dummy_depth);
2610
2611 /* Seems like debug code.
2612 * Maybe this function can just return true if the node is not fully masked. */
2613 return dist_sq < data->radius_squared || true;
2614 }
2615
2616 /**
2617 * Handles clipping against a mirror modifier and #SCULPT_LOCK_X/Y/Z axis flags.
2618 */
SCULPT_clip(Sculpt * sd,SculptSession * ss,float co[3],const float val[3])2619 void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
2620 {
2621 for (int i = 0; i < 3; i++) {
2622 if (sd->flags & (SCULPT_LOCK_X << i)) {
2623 continue;
2624 }
2625
2626 if ((ss->cache->flag & (CLIP_X << i)) && (fabsf(co[i]) <= ss->cache->clip_tolerance[i])) {
2627 co[i] = 0.0f;
2628 }
2629 else {
2630 co[i] = val[i];
2631 }
2632 }
2633 }
2634
sculpt_pbvh_gather_cursor_update(Object * ob,Sculpt * sd,bool use_original,int * r_totnode)2635 static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob,
2636 Sculpt *sd,
2637 bool use_original,
2638 int *r_totnode)
2639 {
2640 SculptSession *ss = ob->sculpt;
2641 PBVHNode **nodes = NULL;
2642 SculptSearchSphereData data = {
2643 .ss = ss,
2644 .sd = sd,
2645 .radius_squared = ss->cursor_radius,
2646 .original = use_original,
2647 .ignore_fully_ineffective = false,
2648 .center = NULL,
2649 };
2650 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
2651 return nodes;
2652 }
2653
sculpt_pbvh_gather_generic(Object * ob,Sculpt * sd,const Brush * brush,bool use_original,float radius_scale,int * r_totnode)2654 static PBVHNode **sculpt_pbvh_gather_generic(Object *ob,
2655 Sculpt *sd,
2656 const Brush *brush,
2657 bool use_original,
2658 float radius_scale,
2659 int *r_totnode)
2660 {
2661 SculptSession *ss = ob->sculpt;
2662 PBVHNode **nodes = NULL;
2663
2664 /* Build a list of all nodes that are potentially within the cursor or brush's area of influence.
2665 */
2666 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
2667 SculptSearchSphereData data = {
2668 .ss = ss,
2669 .sd = sd,
2670 .radius_squared = square_f(ss->cache->radius * radius_scale),
2671 .original = use_original,
2672 .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK,
2673 .center = NULL,
2674 };
2675 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode);
2676 }
2677 else {
2678 struct DistRayAABB_Precalc dist_ray_to_aabb_precalc;
2679 dist_squared_ray_to_aabb_v3_precalc(
2680 &dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal);
2681 SculptSearchCircleData data = {
2682 .ss = ss,
2683 .sd = sd,
2684 .radius_squared = ss->cache ? square_f(ss->cache->radius * radius_scale) :
2685 ss->cursor_radius,
2686 .original = use_original,
2687 .dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc,
2688 .ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK,
2689 };
2690 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode);
2691 }
2692 return nodes;
2693 }
2694
2695 /* Calculate primary direction of movement for many brushes. */
calc_sculpt_normal(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_no[3])2696 static void calc_sculpt_normal(
2697 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3])
2698 {
2699 const Brush *brush = BKE_paint_brush(&sd->paint);
2700 const SculptSession *ss = ob->sculpt;
2701
2702 switch (brush->sculpt_plane) {
2703 case SCULPT_DISP_DIR_VIEW:
2704 copy_v3_v3(r_area_no, ss->cache->true_view_normal);
2705 break;
2706
2707 case SCULPT_DISP_DIR_X:
2708 ARRAY_SET_ITEMS(r_area_no, 1.0f, 0.0f, 0.0f);
2709 break;
2710
2711 case SCULPT_DISP_DIR_Y:
2712 ARRAY_SET_ITEMS(r_area_no, 0.0f, 1.0f, 0.0f);
2713 break;
2714
2715 case SCULPT_DISP_DIR_Z:
2716 ARRAY_SET_ITEMS(r_area_no, 0.0f, 0.0f, 1.0f);
2717 break;
2718
2719 case SCULPT_DISP_DIR_AREA:
2720 SCULPT_calc_area_normal(sd, ob, nodes, totnode, r_area_no);
2721 break;
2722
2723 default:
2724 break;
2725 }
2726 }
2727
update_sculpt_normal(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)2728 static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2729 {
2730 const Brush *brush = BKE_paint_brush(&sd->paint);
2731 StrokeCache *cache = ob->sculpt->cache;
2732 /* Grab brush does not update the sculpt normal during a stroke. */
2733 const bool update_normal = !(brush->flag & BRUSH_ORIGINAL_NORMAL) &&
2734 !(brush->sculpt_tool == SCULPT_TOOL_GRAB) &&
2735 !(brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) &&
2736 !(brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
2737 cache->normal_weight > 0.0f);
2738
2739 if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
2740 (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal)) {
2741 calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal);
2742 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
2743 project_plane_v3_v3v3(cache->sculpt_normal, cache->sculpt_normal, cache->view_normal);
2744 normalize_v3(cache->sculpt_normal);
2745 }
2746 copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
2747 }
2748 else {
2749 copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
2750 flip_v3(cache->sculpt_normal_symm, cache->mirror_symmetry_pass);
2751 mul_m4_v3(cache->symm_rot_mat, cache->sculpt_normal_symm);
2752 }
2753 }
2754
calc_local_y(ViewContext * vc,const float center[3],float y[3])2755 static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
2756 {
2757 Object *ob = vc->obact;
2758 float loc[3], mval_f[2] = {0.0f, 1.0f};
2759 float zfac;
2760
2761 mul_v3_m4v3(loc, ob->imat, center);
2762 zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
2763
2764 ED_view3d_win_to_delta(vc->region, mval_f, y, zfac);
2765 normalize_v3(y);
2766
2767 add_v3_v3(y, ob->loc);
2768 mul_m4_v3(ob->imat, y);
2769 }
2770
calc_brush_local_mat(const Brush * brush,Object * ob,float local_mat[4][4])2771 static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat[4][4])
2772 {
2773 const StrokeCache *cache = ob->sculpt->cache;
2774 float tmat[4][4];
2775 float mat[4][4];
2776 float scale[4][4];
2777 float angle, v[3];
2778 float up[3];
2779
2780 /* Ensure `ob->imat` is up to date. */
2781 invert_m4_m4(ob->imat, ob->obmat);
2782
2783 /* Initialize last column of matrix. */
2784 mat[0][3] = 0.0f;
2785 mat[1][3] = 0.0f;
2786 mat[2][3] = 0.0f;
2787 mat[3][3] = 1.0f;
2788
2789 /* Get view's up vector in object-space. */
2790 calc_local_y(cache->vc, cache->location, up);
2791
2792 /* Calculate the X axis of the local matrix. */
2793 cross_v3_v3v3(v, up, cache->sculpt_normal);
2794 /* Apply rotation (user angle, rake, etc.) to X axis. */
2795 angle = brush->mtex.rot - cache->special_rotation;
2796 rotate_v3_v3v3fl(mat[0], v, cache->sculpt_normal, angle);
2797
2798 /* Get other axes. */
2799 cross_v3_v3v3(mat[1], cache->sculpt_normal, mat[0]);
2800 copy_v3_v3(mat[2], cache->sculpt_normal);
2801
2802 /* Set location. */
2803 copy_v3_v3(mat[3], cache->location);
2804
2805 /* Scale by brush radius. */
2806 normalize_m4(mat);
2807 scale_m4_fl(scale, cache->radius);
2808 mul_m4_m4m4(tmat, mat, scale);
2809
2810 /* Return inverse (for converting from model-space coords to local area coords). */
2811 invert_m4_m4(local_mat, tmat);
2812 }
2813
2814 #define SCULPT_TILT_SENSITIVITY 0.7f
SCULPT_tilt_apply_to_normal(float r_normal[3],StrokeCache * cache,const float tilt_strength)2815 void SCULPT_tilt_apply_to_normal(float r_normal[3], StrokeCache *cache, const float tilt_strength)
2816 {
2817 if (!U.experimental.use_sculpt_tools_tilt) {
2818 return;
2819 }
2820 const float rot_max = M_PI_2 * tilt_strength * SCULPT_TILT_SENSITIVITY;
2821 mul_v3_mat3_m4v3(r_normal, cache->vc->obact->obmat, r_normal);
2822 float normal_tilt_y[3];
2823 rotate_v3_v3v3fl(normal_tilt_y, r_normal, cache->vc->rv3d->viewinv[0], cache->y_tilt * rot_max);
2824 float normal_tilt_xy[3];
2825 rotate_v3_v3v3fl(
2826 normal_tilt_xy, normal_tilt_y, cache->vc->rv3d->viewinv[1], cache->x_tilt * rot_max);
2827 mul_v3_mat3_m4v3(r_normal, cache->vc->obact->imat, normal_tilt_xy);
2828 normalize_v3(r_normal);
2829 }
2830
SCULPT_tilt_effective_normal_get(const SculptSession * ss,const Brush * brush,float r_no[3])2831 void SCULPT_tilt_effective_normal_get(const SculptSession *ss, const Brush *brush, float r_no[3])
2832 {
2833 copy_v3_v3(r_no, ss->cache->sculpt_normal_symm);
2834 SCULPT_tilt_apply_to_normal(r_no, ss->cache, brush->tilt_strength_factor);
2835 }
2836
update_brush_local_mat(Sculpt * sd,Object * ob)2837 static void update_brush_local_mat(Sculpt *sd, Object *ob)
2838 {
2839 StrokeCache *cache = ob->sculpt->cache;
2840
2841 if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) {
2842 calc_brush_local_mat(BKE_paint_brush(&sd->paint), ob, cache->brush_local_mat);
2843 }
2844 }
2845
2846 typedef struct {
2847 SculptSession *ss;
2848 const float *ray_start;
2849 const float *ray_normal;
2850 bool hit;
2851 float depth;
2852 bool original;
2853
2854 int active_vertex_index;
2855 float *face_normal;
2856
2857 int active_face_grid_index;
2858
2859 struct IsectRayPrecalc isect_precalc;
2860 } SculptRaycastData;
2861
2862 typedef struct {
2863 SculptSession *ss;
2864 const float *ray_start, *ray_normal;
2865 bool hit;
2866 float depth;
2867 float dist_sq_to_ray;
2868 bool original;
2869 } SculptFindNearestToRayData;
2870
do_topology_rake_bmesh_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)2871 static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
2872 const int n,
2873 const TaskParallelTLS *__restrict tls)
2874 {
2875 SculptThreadedTaskData *data = userdata;
2876 SculptSession *ss = data->ob->sculpt;
2877 Sculpt *sd = data->sd;
2878 const Brush *brush = data->brush;
2879
2880 float direction[3];
2881 copy_v3_v3(direction, ss->cache->grab_delta_symmetry);
2882
2883 float tmp[3];
2884 mul_v3_v3fl(
2885 tmp, ss->cache->sculpt_normal_symm, dot_v3v3(ss->cache->sculpt_normal_symm, direction));
2886 sub_v3_v3(direction, tmp);
2887 normalize_v3(direction);
2888
2889 /* Cancel if there's no grab data. */
2890 if (is_zero_v3(direction)) {
2891 return;
2892 }
2893
2894 const float bstrength = clamp_f(data->strength, 0.0f, 1.0f);
2895
2896 SculptBrushTest test;
2897 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
2898 ss, &test, data->brush->falloff_shape);
2899 const int thread_id = BLI_task_parallel_thread_id(tls);
2900
2901 PBVHVertexIter vd;
2902 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2903 {
2904 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2905 const float fade =
2906 bstrength *
2907 SCULPT_brush_strength_factor(
2908 ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) *
2909 ss->cache->pressure;
2910
2911 float avg[3], val[3];
2912
2913 SCULPT_bmesh_four_neighbor_average(avg, direction, vd.bm_vert);
2914
2915 sub_v3_v3v3(val, avg, vd.co);
2916
2917 madd_v3_v3v3fl(val, vd.co, val, fade);
2918
2919 SCULPT_clip(sd, ss, vd.co, val);
2920
2921 if (vd.mvert) {
2922 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
2923 }
2924 }
2925 }
2926 BKE_pbvh_vertex_iter_end;
2927 }
2928
bmesh_topology_rake(Sculpt * sd,Object * ob,PBVHNode ** nodes,const int totnode,float bstrength)2929 static void bmesh_topology_rake(
2930 Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength)
2931 {
2932 Brush *brush = BKE_paint_brush(&sd->paint);
2933 const float strength = clamp_f(bstrength, 0.0f, 1.0f);
2934
2935 /* Interactions increase both strength and quality. */
2936 const int iterations = 3;
2937
2938 int iteration;
2939 const int count = iterations * strength + 1;
2940 const float factor = iterations * strength / count;
2941
2942 for (iteration = 0; iteration <= count; iteration++) {
2943
2944 SculptThreadedTaskData data = {
2945 .sd = sd,
2946 .ob = ob,
2947 .brush = brush,
2948 .nodes = nodes,
2949 .strength = factor,
2950 };
2951 TaskParallelSettings settings;
2952 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
2953
2954 BLI_task_parallel_range(0, totnode, &data, do_topology_rake_bmesh_task_cb_ex, &settings);
2955 }
2956 }
2957
do_mask_brush_draw_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)2958 static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata,
2959 const int n,
2960 const TaskParallelTLS *__restrict tls)
2961 {
2962 SculptThreadedTaskData *data = userdata;
2963 SculptSession *ss = data->ob->sculpt;
2964 const Brush *brush = data->brush;
2965 const float bstrength = ss->cache->bstrength;
2966
2967 PBVHVertexIter vd;
2968
2969 SculptBrushTest test;
2970 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
2971 ss, &test, data->brush->falloff_shape);
2972 const int thread_id = BLI_task_parallel_thread_id(tls);
2973
2974 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2975 {
2976 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2977 const float fade = SCULPT_brush_strength_factor(
2978 ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id);
2979
2980 if (bstrength > 0.0f) {
2981 (*vd.mask) += fade * bstrength * (1.0f - *vd.mask);
2982 }
2983 else {
2984 (*vd.mask) += fade * bstrength * (*vd.mask);
2985 }
2986 *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f);
2987
2988 if (vd.mvert) {
2989 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
2990 }
2991 }
2992 BKE_pbvh_vertex_iter_end;
2993 }
2994 }
2995
do_mask_brush_draw(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)2996 static void do_mask_brush_draw(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
2997 {
2998 Brush *brush = BKE_paint_brush(&sd->paint);
2999
3000 /* Threaded loop over nodes. */
3001 SculptThreadedTaskData data = {
3002 .sd = sd,
3003 .ob = ob,
3004 .brush = brush,
3005 .nodes = nodes,
3006 };
3007
3008 TaskParallelSettings settings;
3009 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3010 BLI_task_parallel_range(0, totnode, &data, do_mask_brush_draw_task_cb_ex, &settings);
3011 }
3012
do_mask_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3013 static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3014 {
3015 SculptSession *ss = ob->sculpt;
3016 Brush *brush = BKE_paint_brush(&sd->paint);
3017
3018 switch ((BrushMaskTool)brush->mask_tool) {
3019 case BRUSH_MASK_DRAW:
3020 do_mask_brush_draw(sd, ob, nodes, totnode);
3021 break;
3022 case BRUSH_MASK_SMOOTH:
3023 SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, true);
3024 break;
3025 }
3026 }
3027
3028 /** \name Sculpt Multires Displacement Eraser Brush
3029 * \{ */
3030
do_displacement_eraser_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3031 static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata,
3032 const int n,
3033 const TaskParallelTLS *__restrict tls)
3034 {
3035 SculptThreadedTaskData *data = userdata;
3036 SculptSession *ss = data->ob->sculpt;
3037 const Brush *brush = data->brush;
3038 const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f);
3039
3040 float(*proxy)[3] = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3041
3042 SculptBrushTest test;
3043 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3044 ss, &test, data->brush->falloff_shape);
3045 const int thread_id = BLI_task_parallel_thread_id(tls);
3046
3047 PBVHVertexIter vd;
3048 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3049 {
3050 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
3051 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
3052 brush,
3053 vd.co,
3054 sqrtf(test.dist),
3055 vd.no,
3056 vd.fno,
3057 vd.mask ? *vd.mask : 0.0f,
3058 vd.index,
3059 thread_id);
3060
3061 float limit_co[3];
3062 float disp[3];
3063 SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co);
3064 sub_v3_v3v3(disp, limit_co, vd.co);
3065 mul_v3_v3fl(proxy[vd.i], disp, fade);
3066
3067 if (vd.mvert) {
3068 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3069 }
3070 }
3071 }
3072 BKE_pbvh_vertex_iter_end;
3073 }
3074
do_displacement_eraser_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3075 static void do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3076 {
3077 Brush *brush = BKE_paint_brush(&sd->paint);
3078 BKE_curvemapping_init(brush->curve);
3079
3080 /* Threaded loop over nodes. */
3081 SculptThreadedTaskData data = {
3082 .sd = sd,
3083 .ob = ob,
3084 .brush = brush,
3085 .nodes = nodes,
3086 };
3087
3088 TaskParallelSettings settings;
3089 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3090 BLI_task_parallel_range(0, totnode, &data, do_displacement_eraser_brush_task_cb_ex, &settings);
3091 }
3092
3093 /** \} */
3094
do_draw_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3095 static void do_draw_brush_task_cb_ex(void *__restrict userdata,
3096 const int n,
3097 const TaskParallelTLS *__restrict tls)
3098 {
3099 SculptThreadedTaskData *data = userdata;
3100 SculptSession *ss = data->ob->sculpt;
3101 const Brush *brush = data->brush;
3102 const float *offset = data->offset;
3103
3104 PBVHVertexIter vd;
3105 float(*proxy)[3];
3106
3107 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3108
3109 SculptBrushTest test;
3110 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3111 ss, &test, data->brush->falloff_shape);
3112 const int thread_id = BLI_task_parallel_thread_id(tls);
3113
3114 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3115 {
3116 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
3117 /* Offset vertex. */
3118 const float fade = SCULPT_brush_strength_factor(ss,
3119 brush,
3120 vd.co,
3121 sqrtf(test.dist),
3122 vd.no,
3123 vd.fno,
3124 vd.mask ? *vd.mask : 0.0f,
3125 vd.index,
3126 thread_id);
3127
3128 mul_v3_v3fl(proxy[vd.i], offset, fade);
3129
3130 if (vd.mvert) {
3131 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3132 }
3133 }
3134 }
3135 BKE_pbvh_vertex_iter_end;
3136 }
3137
do_draw_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3138 static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3139 {
3140 SculptSession *ss = ob->sculpt;
3141 Brush *brush = BKE_paint_brush(&sd->paint);
3142 float offset[3];
3143 const float bstrength = ss->cache->bstrength;
3144
3145 /* Offset with as much as possible factored in already. */
3146 float effective_normal[3];
3147 SCULPT_tilt_effective_normal_get(ss, brush, effective_normal);
3148 mul_v3_v3fl(offset, effective_normal, ss->cache->radius);
3149 mul_v3_v3(offset, ss->cache->scale);
3150 mul_v3_fl(offset, bstrength);
3151
3152 /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
3153 * initialize before threads so they can do curve mapping. */
3154 BKE_curvemapping_init(brush->curve);
3155
3156 /* Threaded loop over nodes. */
3157 SculptThreadedTaskData data = {
3158 .sd = sd,
3159 .ob = ob,
3160 .brush = brush,
3161 .nodes = nodes,
3162 .offset = offset,
3163 };
3164
3165 TaskParallelSettings settings;
3166 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3167 BLI_task_parallel_range(0, totnode, &data, do_draw_brush_task_cb_ex, &settings);
3168 }
3169
do_draw_sharp_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3170 static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata,
3171 const int n,
3172 const TaskParallelTLS *__restrict tls)
3173 {
3174 SculptThreadedTaskData *data = userdata;
3175 SculptSession *ss = data->ob->sculpt;
3176 const Brush *brush = data->brush;
3177 const float *offset = data->offset;
3178
3179 PBVHVertexIter vd;
3180 SculptOrigVertData orig_data;
3181 float(*proxy)[3];
3182
3183 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
3184
3185 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3186
3187 SculptBrushTest test;
3188 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3189 ss, &test, data->brush->falloff_shape);
3190 const int thread_id = BLI_task_parallel_thread_id(tls);
3191
3192 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3193 {
3194 SCULPT_orig_vert_data_update(&orig_data, &vd);
3195 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
3196 /* Offset vertex. */
3197 const float fade = SCULPT_brush_strength_factor(ss,
3198 brush,
3199 orig_data.co,
3200 sqrtf(test.dist),
3201 orig_data.no,
3202 NULL,
3203 vd.mask ? *vd.mask : 0.0f,
3204 vd.index,
3205 thread_id);
3206
3207 mul_v3_v3fl(proxy[vd.i], offset, fade);
3208
3209 if (vd.mvert) {
3210 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3211 }
3212 }
3213 }
3214 BKE_pbvh_vertex_iter_end;
3215 }
3216
do_draw_sharp_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3217 static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3218 {
3219 SculptSession *ss = ob->sculpt;
3220 Brush *brush = BKE_paint_brush(&sd->paint);
3221 float offset[3];
3222 const float bstrength = ss->cache->bstrength;
3223
3224 /* Offset with as much as possible factored in already. */
3225 float effective_normal[3];
3226 SCULPT_tilt_effective_normal_get(ss, brush, effective_normal);
3227 mul_v3_v3fl(offset, effective_normal, ss->cache->radius);
3228 mul_v3_v3(offset, ss->cache->scale);
3229 mul_v3_fl(offset, bstrength);
3230
3231 /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
3232 * initialize before threads so they can do curve mapping. */
3233 BKE_curvemapping_init(brush->curve);
3234
3235 /* Threaded loop over nodes. */
3236 SculptThreadedTaskData data = {
3237 .sd = sd,
3238 .ob = ob,
3239 .brush = brush,
3240 .nodes = nodes,
3241 .offset = offset,
3242 };
3243
3244 TaskParallelSettings settings;
3245 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3246 BLI_task_parallel_range(0, totnode, &data, do_draw_sharp_brush_task_cb_ex, &settings);
3247 }
3248
3249 /* -------------------------------------------------------------------- */
3250
3251 /** \name Sculpt Topology Brush
3252 * \{ */
3253
do_topology_slide_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3254 static void do_topology_slide_task_cb_ex(void *__restrict userdata,
3255 const int n,
3256 const TaskParallelTLS *__restrict tls)
3257 {
3258 SculptThreadedTaskData *data = userdata;
3259 SculptSession *ss = data->ob->sculpt;
3260 const Brush *brush = data->brush;
3261
3262 PBVHVertexIter vd;
3263 SculptOrigVertData orig_data;
3264 float(*proxy)[3];
3265
3266 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
3267
3268 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3269
3270 SculptBrushTest test;
3271 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3272 ss, &test, data->brush->falloff_shape);
3273 const int thread_id = BLI_task_parallel_thread_id(tls);
3274
3275 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3276 {
3277 SCULPT_orig_vert_data_update(&orig_data, &vd);
3278 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
3279 const float fade = SCULPT_brush_strength_factor(ss,
3280 brush,
3281 orig_data.co,
3282 sqrtf(test.dist),
3283 orig_data.no,
3284 NULL,
3285 vd.mask ? *vd.mask : 0.0f,
3286 vd.index,
3287 thread_id);
3288 float current_disp[3];
3289 float current_disp_norm[3];
3290 float final_disp[3] = {0.0f, 0.0f, 0.0f};
3291
3292 switch (brush->slide_deform_type) {
3293 case BRUSH_SLIDE_DEFORM_DRAG:
3294 sub_v3_v3v3(current_disp, ss->cache->location, ss->cache->last_location);
3295 break;
3296 case BRUSH_SLIDE_DEFORM_PINCH:
3297 sub_v3_v3v3(current_disp, ss->cache->location, vd.co);
3298 break;
3299 case BRUSH_SLIDE_DEFORM_EXPAND:
3300 sub_v3_v3v3(current_disp, vd.co, ss->cache->location);
3301 break;
3302 }
3303
3304 normalize_v3_v3(current_disp_norm, current_disp);
3305 mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength);
3306
3307 SculptVertexNeighborIter ni;
3308 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
3309 float vertex_disp[3];
3310 float vertex_disp_norm[3];
3311 sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co);
3312 normalize_v3_v3(vertex_disp_norm, vertex_disp);
3313 if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) {
3314 madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp));
3315 }
3316 }
3317 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
3318
3319 mul_v3_v3fl(proxy[vd.i], final_disp, fade);
3320
3321 if (vd.mvert) {
3322 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3323 }
3324 }
3325 }
3326 BKE_pbvh_vertex_iter_end;
3327 }
3328
SCULPT_relax_vertex(SculptSession * ss,PBVHVertexIter * vd,float factor,bool filter_boundary_face_sets,float * r_final_pos)3329 void SCULPT_relax_vertex(SculptSession *ss,
3330 PBVHVertexIter *vd,
3331 float factor,
3332 bool filter_boundary_face_sets,
3333 float *r_final_pos)
3334 {
3335 float smooth_pos[3];
3336 float final_disp[3];
3337 float boundary_normal[3];
3338 int avg_count = 0;
3339 int neighbor_count = 0;
3340 zero_v3(smooth_pos);
3341 zero_v3(boundary_normal);
3342 const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->index);
3343
3344 SculptVertexNeighborIter ni;
3345 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) {
3346 neighbor_count++;
3347 if (!filter_boundary_face_sets ||
3348 (filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.index))) {
3349
3350 /* When the vertex to relax is boundary, use only connected boundary vertices for the average
3351 * position. */
3352 if (is_boundary) {
3353 if (SCULPT_vertex_is_boundary(ss, ni.index)) {
3354 add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
3355 avg_count++;
3356
3357 /* Calculate a normal for the constraint plane using the edges of the boundary. */
3358 float to_neighbor[3];
3359 sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co);
3360 normalize_v3(to_neighbor);
3361 add_v3_v3(boundary_normal, to_neighbor);
3362 }
3363 }
3364 else {
3365 add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index));
3366 avg_count++;
3367 }
3368 }
3369 }
3370 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
3371
3372 /* Don't modify corner vertices. */
3373 if (neighbor_count <= 2) {
3374 copy_v3_v3(r_final_pos, vd->co);
3375 return;
3376 }
3377
3378 if (avg_count > 0) {
3379 mul_v3_fl(smooth_pos, 1.0f / avg_count);
3380 }
3381 else {
3382 copy_v3_v3(r_final_pos, vd->co);
3383 return;
3384 }
3385
3386 float plane[4];
3387 float smooth_closest_plane[3];
3388 float vno[3];
3389
3390 if (is_boundary && avg_count == 2) {
3391 normalize_v3_v3(vno, boundary_normal);
3392 }
3393 else {
3394 SCULPT_vertex_normal_get(ss, vd->index, vno);
3395 }
3396
3397 if (is_zero_v3(vno)) {
3398 copy_v3_v3(r_final_pos, vd->co);
3399 return;
3400 }
3401
3402 plane_from_point_normal_v3(plane, vd->co, vno);
3403 closest_to_plane_v3(smooth_closest_plane, plane, smooth_pos);
3404 sub_v3_v3v3(final_disp, smooth_closest_plane, vd->co);
3405
3406 mul_v3_fl(final_disp, factor);
3407 add_v3_v3v3(r_final_pos, vd->co, final_disp);
3408 }
3409
do_topology_relax_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3410 static void do_topology_relax_task_cb_ex(void *__restrict userdata,
3411 const int n,
3412 const TaskParallelTLS *__restrict tls)
3413 {
3414 SculptThreadedTaskData *data = userdata;
3415 SculptSession *ss = data->ob->sculpt;
3416 const Brush *brush = data->brush;
3417 const float bstrength = ss->cache->bstrength;
3418
3419 PBVHVertexIter vd;
3420 SculptOrigVertData orig_data;
3421
3422 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
3423
3424 BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n]);
3425
3426 SculptBrushTest test;
3427 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3428 ss, &test, data->brush->falloff_shape);
3429 const int thread_id = BLI_task_parallel_thread_id(tls);
3430
3431 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3432 {
3433 SCULPT_orig_vert_data_update(&orig_data, &vd);
3434 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
3435 const float fade = SCULPT_brush_strength_factor(ss,
3436 brush,
3437 orig_data.co,
3438 sqrtf(test.dist),
3439 orig_data.no,
3440 NULL,
3441 vd.mask ? *vd.mask : 0.0f,
3442 vd.index,
3443 thread_id);
3444
3445 SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co);
3446 if (vd.mvert) {
3447 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3448 }
3449 }
3450 }
3451 BKE_pbvh_vertex_iter_end;
3452 }
3453
do_slide_relax_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3454 static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3455 {
3456 SculptSession *ss = ob->sculpt;
3457 Brush *brush = BKE_paint_brush(&sd->paint);
3458
3459 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
3460 return;
3461 }
3462
3463 BKE_curvemapping_init(brush->curve);
3464
3465 SculptThreadedTaskData data = {
3466 .sd = sd,
3467 .ob = ob,
3468 .brush = brush,
3469 .nodes = nodes,
3470 };
3471
3472 TaskParallelSettings settings;
3473 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3474 if (ss->cache->alt_smooth) {
3475 SCULPT_boundary_info_ensure(ob);
3476 for (int i = 0; i < 4; i++) {
3477 BLI_task_parallel_range(0, totnode, &data, do_topology_relax_task_cb_ex, &settings);
3478 }
3479 }
3480 else {
3481 BLI_task_parallel_range(0, totnode, &data, do_topology_slide_task_cb_ex, &settings);
3482 }
3483 }
3484
calc_sculpt_plane(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_no[3],float r_area_co[3])3485 static void calc_sculpt_plane(
3486 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
3487 {
3488 SculptSession *ss = ob->sculpt;
3489 Brush *brush = BKE_paint_brush(&sd->paint);
3490
3491 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache) &&
3492 (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
3493 !(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
3494 switch (brush->sculpt_plane) {
3495 case SCULPT_DISP_DIR_VIEW:
3496 copy_v3_v3(r_area_no, ss->cache->true_view_normal);
3497 break;
3498
3499 case SCULPT_DISP_DIR_X:
3500 ARRAY_SET_ITEMS(r_area_no, 1.0f, 0.0f, 0.0f);
3501 break;
3502
3503 case SCULPT_DISP_DIR_Y:
3504 ARRAY_SET_ITEMS(r_area_no, 0.0f, 1.0f, 0.0f);
3505 break;
3506
3507 case SCULPT_DISP_DIR_Z:
3508 ARRAY_SET_ITEMS(r_area_no, 0.0f, 0.0f, 1.0f);
3509 break;
3510
3511 case SCULPT_DISP_DIR_AREA:
3512 calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co);
3513 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
3514 project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
3515 normalize_v3(r_area_no);
3516 }
3517 break;
3518
3519 default:
3520 break;
3521 }
3522
3523 /* For flatten center. */
3524 /* Flatten center has not been calculated yet if we are not using the area normal. */
3525 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
3526 calc_area_center(sd, ob, nodes, totnode, r_area_co);
3527 }
3528
3529 /* For area normal. */
3530 if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
3531 (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
3532 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
3533 }
3534 else {
3535 copy_v3_v3(ss->cache->sculpt_normal, r_area_no);
3536 }
3537
3538 /* For flatten center. */
3539 if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
3540 (brush->flag & BRUSH_ORIGINAL_PLANE)) {
3541 copy_v3_v3(r_area_co, ss->cache->last_center);
3542 }
3543 else {
3544 copy_v3_v3(ss->cache->last_center, r_area_co);
3545 }
3546 }
3547 else {
3548 /* For area normal. */
3549 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
3550
3551 /* For flatten center. */
3552 copy_v3_v3(r_area_co, ss->cache->last_center);
3553
3554 /* For area normal. */
3555 flip_v3(r_area_no, ss->cache->mirror_symmetry_pass);
3556
3557 /* For flatten center. */
3558 flip_v3(r_area_co, ss->cache->mirror_symmetry_pass);
3559
3560 /* For area normal. */
3561 mul_m4_v3(ss->cache->symm_rot_mat, r_area_no);
3562
3563 /* For flatten center. */
3564 mul_m4_v3(ss->cache->symm_rot_mat, r_area_co);
3565
3566 /* Shift the plane for the current tile. */
3567 add_v3_v3(r_area_co, ss->cache->plane_offset);
3568 }
3569 }
3570
3571 /** \} */
3572
3573 /**
3574 * Used for 'SCULPT_TOOL_CREASE' and 'SCULPT_TOOL_BLOB'
3575 */
do_crease_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3576 static void do_crease_brush_task_cb_ex(void *__restrict userdata,
3577 const int n,
3578 const TaskParallelTLS *__restrict tls)
3579 {
3580 SculptThreadedTaskData *data = userdata;
3581 SculptSession *ss = data->ob->sculpt;
3582 const Brush *brush = data->brush;
3583 SculptProjectVector *spvc = data->spvc;
3584 const float flippedbstrength = data->flippedbstrength;
3585 const float *offset = data->offset;
3586
3587 PBVHVertexIter vd;
3588 float(*proxy)[3];
3589
3590 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3591
3592 SculptBrushTest test;
3593 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3594 ss, &test, data->brush->falloff_shape);
3595 const int thread_id = BLI_task_parallel_thread_id(tls);
3596
3597 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3598 {
3599 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
3600 /* Offset vertex. */
3601 const float fade = SCULPT_brush_strength_factor(ss,
3602 brush,
3603 vd.co,
3604 sqrtf(test.dist),
3605 vd.no,
3606 vd.fno,
3607 vd.mask ? *vd.mask : 0.0f,
3608 vd.index,
3609 thread_id);
3610 float val1[3];
3611 float val2[3];
3612
3613 /* First we pinch. */
3614 sub_v3_v3v3(val1, test.location, vd.co);
3615 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
3616 project_plane_v3_v3v3(val1, val1, ss->cache->view_normal);
3617 }
3618
3619 mul_v3_fl(val1, fade * flippedbstrength);
3620
3621 sculpt_project_v3(spvc, val1, val1);
3622
3623 /* Then we draw. */
3624 mul_v3_v3fl(val2, offset, fade);
3625
3626 add_v3_v3v3(proxy[vd.i], val1, val2);
3627
3628 if (vd.mvert) {
3629 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3630 }
3631 }
3632 }
3633 BKE_pbvh_vertex_iter_end;
3634 }
3635
do_crease_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3636 static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3637 {
3638 SculptSession *ss = ob->sculpt;
3639 const Scene *scene = ss->cache->vc->scene;
3640 Brush *brush = BKE_paint_brush(&sd->paint);
3641 float offset[3];
3642 float bstrength = ss->cache->bstrength;
3643 float flippedbstrength, crease_correction;
3644 float brush_alpha;
3645
3646 SculptProjectVector spvc;
3647
3648 /* Offset with as much as possible factored in already. */
3649 mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
3650 mul_v3_v3(offset, ss->cache->scale);
3651 mul_v3_fl(offset, bstrength);
3652
3653 /* We divide out the squared alpha and multiply by the squared crease
3654 * to give us the pinch strength. */
3655 crease_correction = brush->crease_pinch_factor * brush->crease_pinch_factor;
3656 brush_alpha = BKE_brush_alpha_get(scene, brush);
3657 if (brush_alpha > 0.0f) {
3658 crease_correction /= brush_alpha * brush_alpha;
3659 }
3660
3661 /* We always want crease to pinch or blob to relax even when draw is negative. */
3662 flippedbstrength = (bstrength < 0.0f) ? -crease_correction * bstrength :
3663 crease_correction * bstrength;
3664
3665 if (brush->sculpt_tool == SCULPT_TOOL_BLOB) {
3666 flippedbstrength *= -1.0f;
3667 }
3668
3669 /* Use surface normal for 'spvc', so the vertices are pinched towards a line instead of a single
3670 * point. Without this we get a 'flat' surface surrounding the pinch. */
3671 sculpt_project_v3_cache_init(&spvc, ss->cache->sculpt_normal_symm);
3672
3673 /* Threaded loop over nodes. */
3674 SculptThreadedTaskData data = {
3675 .sd = sd,
3676 .ob = ob,
3677 .brush = brush,
3678 .nodes = nodes,
3679 .spvc = &spvc,
3680 .offset = offset,
3681 .flippedbstrength = flippedbstrength,
3682 };
3683
3684 TaskParallelSettings settings;
3685 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3686 BLI_task_parallel_range(0, totnode, &data, do_crease_brush_task_cb_ex, &settings);
3687 }
3688
do_pinch_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3689 static void do_pinch_brush_task_cb_ex(void *__restrict userdata,
3690 const int n,
3691 const TaskParallelTLS *__restrict tls)
3692 {
3693 SculptThreadedTaskData *data = userdata;
3694 SculptSession *ss = data->ob->sculpt;
3695 const Brush *brush = data->brush;
3696 float(*stroke_xz)[3] = data->stroke_xz;
3697
3698 PBVHVertexIter vd;
3699 float(*proxy)[3];
3700 const float bstrength = ss->cache->bstrength;
3701
3702 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3703
3704 SculptBrushTest test;
3705 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3706 ss, &test, data->brush->falloff_shape);
3707 const int thread_id = BLI_task_parallel_thread_id(tls);
3708
3709 float x_object_space[3];
3710 float z_object_space[3];
3711 copy_v3_v3(x_object_space, stroke_xz[0]);
3712 copy_v3_v3(z_object_space, stroke_xz[1]);
3713
3714 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3715 {
3716 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
3717 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
3718 brush,
3719 vd.co,
3720 sqrtf(test.dist),
3721 vd.no,
3722 vd.fno,
3723 vd.mask ? *vd.mask : 0.0f,
3724 vd.index,
3725 thread_id);
3726 float disp_center[3];
3727 float x_disp[3];
3728 float z_disp[3];
3729 /* Calculate displacement from the vertex to the brush center. */
3730 sub_v3_v3v3(disp_center, test.location, vd.co);
3731
3732 /* Project the displacement into the X vector (aligned to the stroke). */
3733 mul_v3_v3fl(x_disp, x_object_space, dot_v3v3(disp_center, x_object_space));
3734
3735 /* Project the displacement into the Z vector (aligned to the surface normal). */
3736 mul_v3_v3fl(z_disp, z_object_space, dot_v3v3(disp_center, z_object_space));
3737
3738 /* Add the two projected vectors to calculate the final displacement.
3739 * The Y component is removed. */
3740 add_v3_v3v3(disp_center, x_disp, z_disp);
3741
3742 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
3743 project_plane_v3_v3v3(disp_center, disp_center, ss->cache->view_normal);
3744 }
3745 mul_v3_v3fl(proxy[vd.i], disp_center, fade);
3746
3747 if (vd.mvert) {
3748 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3749 }
3750 }
3751 }
3752 BKE_pbvh_vertex_iter_end;
3753 }
3754
do_pinch_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3755 static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3756 {
3757 SculptSession *ss = ob->sculpt;
3758 Brush *brush = BKE_paint_brush(&sd->paint);
3759
3760 float area_no[3];
3761 float area_co[3];
3762
3763 float mat[4][4];
3764 calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co);
3765
3766 /* delay the first daub because grab delta is not setup */
3767 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
3768 return;
3769 }
3770
3771 if (is_zero_v3(ss->cache->grab_delta_symmetry)) {
3772 return;
3773 }
3774
3775 /* Initialize `mat`. */
3776 cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
3777 mat[0][3] = 0.0f;
3778 cross_v3_v3v3(mat[1], area_no, mat[0]);
3779 mat[1][3] = 0.0f;
3780 copy_v3_v3(mat[2], area_no);
3781 mat[2][3] = 0.0f;
3782 copy_v3_v3(mat[3], ss->cache->location);
3783 mat[3][3] = 1.0f;
3784 normalize_m4(mat);
3785
3786 float stroke_xz[2][3];
3787 normalize_v3_v3(stroke_xz[0], mat[0]);
3788 normalize_v3_v3(stroke_xz[1], mat[2]);
3789
3790 SculptThreadedTaskData data = {
3791 .sd = sd,
3792 .ob = ob,
3793 .brush = brush,
3794 .nodes = nodes,
3795 .stroke_xz = stroke_xz,
3796 };
3797
3798 TaskParallelSettings settings;
3799 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3800 BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
3801 }
3802
do_grab_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)3803 static void do_grab_brush_task_cb_ex(void *__restrict userdata,
3804 const int n,
3805 const TaskParallelTLS *__restrict tls)
3806 {
3807 SculptThreadedTaskData *data = userdata;
3808 SculptSession *ss = data->ob->sculpt;
3809 const Brush *brush = data->brush;
3810 const float *grab_delta = data->grab_delta;
3811
3812 PBVHVertexIter vd;
3813 SculptOrigVertData orig_data;
3814 float(*proxy)[3];
3815 const float bstrength = ss->cache->bstrength;
3816
3817 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
3818
3819 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3820
3821 SculptBrushTest test;
3822 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3823 ss, &test, data->brush->falloff_shape);
3824 const int thread_id = BLI_task_parallel_thread_id(tls);
3825
3826 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3827 {
3828 SCULPT_orig_vert_data_update(&orig_data, &vd);
3829
3830 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
3831 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
3832 brush,
3833 orig_data.co,
3834 sqrtf(test.dist),
3835 orig_data.no,
3836 NULL,
3837 vd.mask ? *vd.mask : 0.0f,
3838 vd.index,
3839 thread_id);
3840
3841 mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
3842
3843 if (vd.mvert) {
3844 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3845 }
3846 }
3847 }
3848 BKE_pbvh_vertex_iter_end;
3849 }
3850
do_grab_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3851 static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3852 {
3853 SculptSession *ss = ob->sculpt;
3854 Brush *brush = BKE_paint_brush(&sd->paint);
3855 float grab_delta[3];
3856
3857 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
3858
3859 if (ss->cache->normal_weight > 0.0f) {
3860 sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
3861 }
3862
3863 SculptThreadedTaskData data = {
3864 .sd = sd,
3865 .ob = ob,
3866 .brush = brush,
3867 .nodes = nodes,
3868 .grab_delta = grab_delta,
3869 };
3870
3871 TaskParallelSettings settings;
3872 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3873 BLI_task_parallel_range(0, totnode, &data, do_grab_brush_task_cb_ex, &settings);
3874 }
3875
do_elastic_deform_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))3876 static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata,
3877 const int n,
3878 const TaskParallelTLS *__restrict UNUSED(tls))
3879 {
3880 SculptThreadedTaskData *data = userdata;
3881 SculptSession *ss = data->ob->sculpt;
3882 const Brush *brush = data->brush;
3883 const float *grab_delta = data->grab_delta;
3884 const float *location = ss->cache->location;
3885
3886 PBVHVertexIter vd;
3887 SculptOrigVertData orig_data;
3888 float(*proxy)[3];
3889
3890 const float bstrength = ss->cache->bstrength;
3891
3892 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
3893
3894 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
3895
3896 float dir;
3897 if (ss->cache->mouse[0] > ss->cache->initial_mouse[0]) {
3898 dir = 1.0f;
3899 }
3900 else {
3901 dir = -1.0f;
3902 }
3903
3904 if (brush->elastic_deform_type == BRUSH_ELASTIC_DEFORM_TWIST) {
3905 int symm = ss->cache->mirror_symmetry_pass;
3906 if (symm == 1 || symm == 2 || symm == 4 || symm == 7) {
3907 dir = -dir;
3908 }
3909 }
3910
3911 KelvinletParams params;
3912 float force = len_v3(grab_delta) * dir * bstrength;
3913 BKE_kelvinlet_init_params(
3914 ¶ms, ss->cache->radius, force, 1.0f, brush->elastic_deform_volume_preservation);
3915
3916 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
3917 {
3918 SCULPT_orig_vert_data_update(&orig_data, &vd);
3919 float final_disp[3];
3920 switch (brush->elastic_deform_type) {
3921 case BRUSH_ELASTIC_DEFORM_GRAB:
3922 BKE_kelvinlet_grab(final_disp, ¶ms, orig_data.co, location, grab_delta);
3923 mul_v3_fl(final_disp, bstrength * 20.0f);
3924 break;
3925 case BRUSH_ELASTIC_DEFORM_GRAB_BISCALE: {
3926 BKE_kelvinlet_grab_biscale(final_disp, ¶ms, orig_data.co, location, grab_delta);
3927 mul_v3_fl(final_disp, bstrength * 20.0f);
3928 break;
3929 }
3930 case BRUSH_ELASTIC_DEFORM_GRAB_TRISCALE: {
3931 BKE_kelvinlet_grab_triscale(final_disp, ¶ms, orig_data.co, location, grab_delta);
3932 mul_v3_fl(final_disp, bstrength * 20.0f);
3933 break;
3934 }
3935 case BRUSH_ELASTIC_DEFORM_SCALE:
3936 BKE_kelvinlet_scale(
3937 final_disp, ¶ms, orig_data.co, location, ss->cache->sculpt_normal_symm);
3938 break;
3939 case BRUSH_ELASTIC_DEFORM_TWIST:
3940 BKE_kelvinlet_twist(
3941 final_disp, ¶ms, orig_data.co, location, ss->cache->sculpt_normal_symm);
3942 break;
3943 }
3944
3945 if (vd.mask) {
3946 mul_v3_fl(final_disp, 1.0f - *vd.mask);
3947 }
3948
3949 mul_v3_fl(final_disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
3950
3951 copy_v3_v3(proxy[vd.i], final_disp);
3952
3953 if (vd.mvert) {
3954 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
3955 }
3956 }
3957 BKE_pbvh_vertex_iter_end;
3958 }
3959
do_elastic_deform_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)3960 static void do_elastic_deform_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
3961 {
3962 SculptSession *ss = ob->sculpt;
3963 Brush *brush = BKE_paint_brush(&sd->paint);
3964 float grab_delta[3];
3965
3966 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
3967
3968 if (ss->cache->normal_weight > 0.0f) {
3969 sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
3970 }
3971
3972 SculptThreadedTaskData data = {
3973 .sd = sd,
3974 .ob = ob,
3975 .brush = brush,
3976 .nodes = nodes,
3977 .grab_delta = grab_delta,
3978 };
3979
3980 TaskParallelSettings settings;
3981 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
3982 BLI_task_parallel_range(0, totnode, &data, do_elastic_deform_brush_task_cb_ex, &settings);
3983 }
3984
SCULPT_get_vertex_symm_area(const float co[3])3985 ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
3986 {
3987 ePaintSymmetryAreas symm_area = PAINT_SYMM_AREA_DEFAULT;
3988 if (co[0] < 0.0f) {
3989 symm_area |= PAINT_SYMM_AREA_X;
3990 }
3991 if (co[1] < 0.0f) {
3992 symm_area |= PAINT_SYMM_AREA_Y;
3993 }
3994 if (co[2] < 0.0f) {
3995 symm_area |= PAINT_SYMM_AREA_Z;
3996 }
3997 return symm_area;
3998 }
3999
SCULPT_flip_v3_by_symm_area(float v[3],const ePaintSymmetryFlags symm,const ePaintSymmetryAreas symmarea,const float pivot[3])4000 void SCULPT_flip_v3_by_symm_area(float v[3],
4001 const ePaintSymmetryFlags symm,
4002 const ePaintSymmetryAreas symmarea,
4003 const float pivot[3])
4004 {
4005 for (char i = 0; i < 3; i++) {
4006 ePaintSymmetryFlags symm_it = 1 << i;
4007 if (symm & symm_it) {
4008 if (symmarea & symm_it) {
4009 flip_v3(v, symm_it);
4010 }
4011 if (pivot[0] < 0) {
4012 flip_v3(v, symm_it);
4013 }
4014 }
4015 }
4016 }
4017
SCULPT_flip_quat_by_symm_area(float quat[3],const ePaintSymmetryFlags symm,const ePaintSymmetryAreas symmarea,const float pivot[3])4018 void SCULPT_flip_quat_by_symm_area(float quat[3],
4019 const ePaintSymmetryFlags symm,
4020 const ePaintSymmetryAreas symmarea,
4021 const float pivot[3])
4022 {
4023 for (char i = 0; i < 3; i++) {
4024 ePaintSymmetryFlags symm_it = 1 << i;
4025 if (symm & symm_it) {
4026 if (symmarea & symm_it) {
4027 flip_qt(quat, symm_it);
4028 }
4029 if (pivot[0] < 0) {
4030 flip_qt(quat, symm_it);
4031 }
4032 }
4033 }
4034 }
4035
SCULPT_calc_brush_plane(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float r_area_no[3],float r_area_co[3])4036 void SCULPT_calc_brush_plane(
4037 Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3], float r_area_co[3])
4038 {
4039 SculptSession *ss = ob->sculpt;
4040 Brush *brush = BKE_paint_brush(&sd->paint);
4041
4042 zero_v3(r_area_co);
4043 zero_v3(r_area_no);
4044
4045 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache) &&
4046 (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
4047 !(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
4048 switch (brush->sculpt_plane) {
4049 case SCULPT_DISP_DIR_VIEW:
4050 copy_v3_v3(r_area_no, ss->cache->true_view_normal);
4051 break;
4052
4053 case SCULPT_DISP_DIR_X:
4054 ARRAY_SET_ITEMS(r_area_no, 1.0f, 0.0f, 0.0f);
4055 break;
4056
4057 case SCULPT_DISP_DIR_Y:
4058 ARRAY_SET_ITEMS(r_area_no, 0.0f, 1.0f, 0.0f);
4059 break;
4060
4061 case SCULPT_DISP_DIR_Z:
4062 ARRAY_SET_ITEMS(r_area_no, 0.0f, 0.0f, 1.0f);
4063 break;
4064
4065 case SCULPT_DISP_DIR_AREA:
4066 calc_area_normal_and_center(sd, ob, nodes, totnode, r_area_no, r_area_co);
4067 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
4068 project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
4069 normalize_v3(r_area_no);
4070 }
4071 break;
4072
4073 default:
4074 break;
4075 }
4076
4077 /* For flatten center. */
4078 /* Flatten center has not been calculated yet if we are not using the area normal. */
4079 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
4080 calc_area_center(sd, ob, nodes, totnode, r_area_co);
4081 }
4082
4083 /* For area normal. */
4084 if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
4085 (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
4086 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
4087 }
4088 else {
4089 copy_v3_v3(ss->cache->sculpt_normal, r_area_no);
4090 }
4091
4092 /* For flatten center. */
4093 if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
4094 (brush->flag & BRUSH_ORIGINAL_PLANE)) {
4095 copy_v3_v3(r_area_co, ss->cache->last_center);
4096 }
4097 else {
4098 copy_v3_v3(ss->cache->last_center, r_area_co);
4099 }
4100 }
4101 else {
4102 /* For area normal. */
4103 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
4104
4105 /* For flatten center. */
4106 copy_v3_v3(r_area_co, ss->cache->last_center);
4107
4108 /* For area normal. */
4109 flip_v3(r_area_no, ss->cache->mirror_symmetry_pass);
4110
4111 /* For flatten center. */
4112 flip_v3(r_area_co, ss->cache->mirror_symmetry_pass);
4113
4114 /* For area normal. */
4115 mul_m4_v3(ss->cache->symm_rot_mat, r_area_no);
4116
4117 /* For flatten center. */
4118 mul_m4_v3(ss->cache->symm_rot_mat, r_area_co);
4119
4120 /* Shift the plane for the current tile. */
4121 add_v3_v3(r_area_co, ss->cache->plane_offset);
4122 }
4123 }
4124
do_nudge_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4125 static void do_nudge_brush_task_cb_ex(void *__restrict userdata,
4126 const int n,
4127 const TaskParallelTLS *__restrict tls)
4128 {
4129 SculptThreadedTaskData *data = userdata;
4130 SculptSession *ss = data->ob->sculpt;
4131 const Brush *brush = data->brush;
4132 const float *cono = data->cono;
4133
4134 PBVHVertexIter vd;
4135 float(*proxy)[3];
4136 const float bstrength = ss->cache->bstrength;
4137
4138 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4139
4140 SculptBrushTest test;
4141 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4142 ss, &test, data->brush->falloff_shape);
4143 const int thread_id = BLI_task_parallel_thread_id(tls);
4144
4145 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4146 {
4147 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4148 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4149 brush,
4150 vd.co,
4151 sqrtf(test.dist),
4152 vd.no,
4153 vd.fno,
4154 vd.mask ? *vd.mask : 0.0f,
4155 vd.index,
4156 thread_id);
4157
4158 mul_v3_v3fl(proxy[vd.i], cono, fade);
4159
4160 if (vd.mvert) {
4161 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4162 }
4163 }
4164 }
4165 BKE_pbvh_vertex_iter_end;
4166 }
4167
do_nudge_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4168 static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4169 {
4170 SculptSession *ss = ob->sculpt;
4171 Brush *brush = BKE_paint_brush(&sd->paint);
4172 float grab_delta[3];
4173 float tmp[3], cono[3];
4174
4175 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
4176
4177 cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
4178 cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
4179
4180 SculptThreadedTaskData data = {
4181 .sd = sd,
4182 .ob = ob,
4183 .brush = brush,
4184 .nodes = nodes,
4185 .cono = cono,
4186 };
4187
4188 TaskParallelSettings settings;
4189 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4190 BLI_task_parallel_range(0, totnode, &data, do_nudge_brush_task_cb_ex, &settings);
4191 }
4192
do_snake_hook_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4193 static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
4194 const int n,
4195 const TaskParallelTLS *__restrict tls)
4196 {
4197 SculptThreadedTaskData *data = userdata;
4198 SculptSession *ss = data->ob->sculpt;
4199 const Brush *brush = data->brush;
4200 SculptProjectVector *spvc = data->spvc;
4201 const float *grab_delta = data->grab_delta;
4202
4203 PBVHVertexIter vd;
4204 float(*proxy)[3];
4205 const float bstrength = ss->cache->bstrength;
4206 const bool do_rake_rotation = ss->cache->is_rake_rotation_valid;
4207 const bool do_pinch = (brush->crease_pinch_factor != 0.5f);
4208 const float pinch = do_pinch ? (2.0f * (0.5f - brush->crease_pinch_factor) *
4209 (len_v3(grab_delta) / ss->cache->radius)) :
4210 0.0f;
4211
4212 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4213
4214 SculptBrushTest test;
4215 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4216 ss, &test, data->brush->falloff_shape);
4217 const int thread_id = BLI_task_parallel_thread_id(tls);
4218
4219 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4220 {
4221 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4222 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4223 brush,
4224 vd.co,
4225 sqrtf(test.dist),
4226 vd.no,
4227 vd.fno,
4228 vd.mask ? *vd.mask : 0.0f,
4229 vd.index,
4230 thread_id);
4231
4232 mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
4233
4234 /* Negative pinch will inflate, helps maintain volume. */
4235 if (do_pinch) {
4236 float delta_pinch_init[3], delta_pinch[3];
4237
4238 sub_v3_v3v3(delta_pinch, vd.co, test.location);
4239 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
4240 project_plane_v3_v3v3(delta_pinch, delta_pinch, ss->cache->true_view_normal);
4241 }
4242
4243 /* Important to calculate based on the grabbed location
4244 * (intentionally ignore fade here). */
4245 add_v3_v3(delta_pinch, grab_delta);
4246
4247 sculpt_project_v3(spvc, delta_pinch, delta_pinch);
4248
4249 copy_v3_v3(delta_pinch_init, delta_pinch);
4250
4251 float pinch_fade = pinch * fade;
4252 /* When reducing, scale reduction back by how close to the center we are,
4253 * so we don't pinch into nothingness. */
4254 if (pinch > 0.0f) {
4255 /* Square to have even less impact for close vertices. */
4256 pinch_fade *= pow2f(min_ff(1.0f, len_v3(delta_pinch) / ss->cache->radius));
4257 }
4258 mul_v3_fl(delta_pinch, 1.0f + pinch_fade);
4259 sub_v3_v3v3(delta_pinch, delta_pinch_init, delta_pinch);
4260 add_v3_v3(proxy[vd.i], delta_pinch);
4261 }
4262
4263 if (do_rake_rotation) {
4264 float delta_rotate[3];
4265 sculpt_rake_rotate(ss, test.location, vd.co, fade, delta_rotate);
4266 add_v3_v3(proxy[vd.i], delta_rotate);
4267 }
4268
4269 if (vd.mvert) {
4270 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4271 }
4272 }
4273 }
4274 BKE_pbvh_vertex_iter_end;
4275 }
4276
do_snake_hook_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4277 static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4278 {
4279 SculptSession *ss = ob->sculpt;
4280 Brush *brush = BKE_paint_brush(&sd->paint);
4281 const float bstrength = ss->cache->bstrength;
4282 float grab_delta[3];
4283
4284 SculptProjectVector spvc;
4285
4286 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
4287
4288 if (bstrength < 0.0f) {
4289 negate_v3(grab_delta);
4290 }
4291
4292 if (ss->cache->normal_weight > 0.0f) {
4293 sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta);
4294 }
4295
4296 /* Optionally pinch while painting. */
4297 if (brush->crease_pinch_factor != 0.5f) {
4298 sculpt_project_v3_cache_init(&spvc, grab_delta);
4299 }
4300
4301 SculptThreadedTaskData data = {
4302 .sd = sd,
4303 .ob = ob,
4304 .brush = brush,
4305 .nodes = nodes,
4306 .spvc = &spvc,
4307 .grab_delta = grab_delta,
4308 };
4309
4310 TaskParallelSettings settings;
4311 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4312 BLI_task_parallel_range(0, totnode, &data, do_snake_hook_brush_task_cb_ex, &settings);
4313 }
4314
do_thumb_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4315 static void do_thumb_brush_task_cb_ex(void *__restrict userdata,
4316 const int n,
4317 const TaskParallelTLS *__restrict tls)
4318 {
4319 SculptThreadedTaskData *data = userdata;
4320 SculptSession *ss = data->ob->sculpt;
4321 const Brush *brush = data->brush;
4322 const float *cono = data->cono;
4323
4324 PBVHVertexIter vd;
4325 SculptOrigVertData orig_data;
4326 float(*proxy)[3];
4327 const float bstrength = ss->cache->bstrength;
4328
4329 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
4330
4331 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4332
4333 SculptBrushTest test;
4334 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4335 ss, &test, data->brush->falloff_shape);
4336 const int thread_id = BLI_task_parallel_thread_id(tls);
4337
4338 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4339 {
4340 SCULPT_orig_vert_data_update(&orig_data, &vd);
4341
4342 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
4343 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4344 brush,
4345 orig_data.co,
4346 sqrtf(test.dist),
4347 orig_data.no,
4348 NULL,
4349 vd.mask ? *vd.mask : 0.0f,
4350 vd.index,
4351 thread_id);
4352
4353 mul_v3_v3fl(proxy[vd.i], cono, fade);
4354
4355 if (vd.mvert) {
4356 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4357 }
4358 }
4359 }
4360 BKE_pbvh_vertex_iter_end;
4361 }
4362
do_thumb_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4363 static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4364 {
4365 SculptSession *ss = ob->sculpt;
4366 Brush *brush = BKE_paint_brush(&sd->paint);
4367 float grab_delta[3];
4368 float tmp[3], cono[3];
4369
4370 copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
4371
4372 cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta);
4373 cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm);
4374
4375 SculptThreadedTaskData data = {
4376 .sd = sd,
4377 .ob = ob,
4378 .brush = brush,
4379 .nodes = nodes,
4380 .cono = cono,
4381 };
4382
4383 TaskParallelSettings settings;
4384 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4385 BLI_task_parallel_range(0, totnode, &data, do_thumb_brush_task_cb_ex, &settings);
4386 }
4387
do_rotate_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4388 static void do_rotate_brush_task_cb_ex(void *__restrict userdata,
4389 const int n,
4390 const TaskParallelTLS *__restrict tls)
4391 {
4392 SculptThreadedTaskData *data = userdata;
4393 SculptSession *ss = data->ob->sculpt;
4394 const Brush *brush = data->brush;
4395 const float angle = data->angle;
4396
4397 PBVHVertexIter vd;
4398 SculptOrigVertData orig_data;
4399 float(*proxy)[3];
4400 const float bstrength = ss->cache->bstrength;
4401
4402 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
4403
4404 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4405
4406 SculptBrushTest test;
4407 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4408 ss, &test, data->brush->falloff_shape);
4409 const int thread_id = BLI_task_parallel_thread_id(tls);
4410
4411 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4412 {
4413 SCULPT_orig_vert_data_update(&orig_data, &vd);
4414
4415 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
4416 float vec[3], rot[3][3];
4417 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4418 brush,
4419 orig_data.co,
4420 sqrtf(test.dist),
4421 orig_data.no,
4422 NULL,
4423 vd.mask ? *vd.mask : 0.0f,
4424 vd.index,
4425 thread_id);
4426
4427 sub_v3_v3v3(vec, orig_data.co, ss->cache->location);
4428 axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade);
4429 mul_v3_m3v3(proxy[vd.i], rot, vec);
4430 add_v3_v3(proxy[vd.i], ss->cache->location);
4431 sub_v3_v3(proxy[vd.i], orig_data.co);
4432
4433 if (vd.mvert) {
4434 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4435 }
4436 }
4437 }
4438 BKE_pbvh_vertex_iter_end;
4439 }
4440
do_rotate_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4441 static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4442 {
4443 SculptSession *ss = ob->sculpt;
4444 Brush *brush = BKE_paint_brush(&sd->paint);
4445
4446 static const int flip[8] = {1, -1, -1, 1, -1, 1, 1, -1};
4447 const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];
4448
4449 SculptThreadedTaskData data = {
4450 .sd = sd,
4451 .ob = ob,
4452 .brush = brush,
4453 .nodes = nodes,
4454 .angle = angle,
4455 };
4456
4457 TaskParallelSettings settings;
4458 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4459 BLI_task_parallel_range(0, totnode, &data, do_rotate_brush_task_cb_ex, &settings);
4460 }
4461
do_layer_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4462 static void do_layer_brush_task_cb_ex(void *__restrict userdata,
4463 const int n,
4464 const TaskParallelTLS *__restrict tls)
4465 {
4466 SculptThreadedTaskData *data = userdata;
4467 SculptSession *ss = data->ob->sculpt;
4468 Sculpt *sd = data->sd;
4469 const Brush *brush = data->brush;
4470
4471 const bool use_persistent_base = ss->persistent_base && brush->flag & BRUSH_PERSISTENT;
4472
4473 PBVHVertexIter vd;
4474 SculptOrigVertData orig_data;
4475 const float bstrength = ss->cache->bstrength;
4476 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
4477
4478 SculptBrushTest test;
4479 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4480 ss, &test, data->brush->falloff_shape);
4481 const int thread_id = BLI_task_parallel_thread_id(tls);
4482
4483 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4484 {
4485 SCULPT_orig_vert_data_update(&orig_data, &vd);
4486
4487 if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
4488 const float fade = SCULPT_brush_strength_factor(ss,
4489 brush,
4490 vd.co,
4491 sqrtf(test.dist),
4492 vd.no,
4493 vd.fno,
4494 vd.mask ? *vd.mask : 0.0f,
4495 vd.index,
4496 thread_id);
4497
4498 const int vi = vd.index;
4499 float *disp_factor;
4500 if (use_persistent_base) {
4501 disp_factor = &ss->persistent_base[vi].disp;
4502 }
4503 else {
4504 disp_factor = &ss->cache->layer_displacement_factor[vi];
4505 }
4506
4507 /* When using persistent base, the layer brush (holding Control) invert mode resets the
4508 * height of the layer to 0. This makes possible to clean edges of previously added layers
4509 * on top of the base. */
4510 /* The main direction of the layers is inverted using the regular brush strength with the
4511 * brush direction property. */
4512 if (use_persistent_base && ss->cache->invert) {
4513 (*disp_factor) += fabsf(fade * bstrength * (*disp_factor)) *
4514 ((*disp_factor) > 0.0f ? -1.0f : 1.0f);
4515 }
4516 else {
4517 (*disp_factor) += fade * bstrength * (1.05f - fabsf(*disp_factor));
4518 }
4519 if (vd.mask) {
4520 const float clamp_mask = 1.0f - *vd.mask;
4521 *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask);
4522 }
4523 else {
4524 *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f);
4525 }
4526
4527 float final_co[3];
4528 float normal[3];
4529
4530 if (use_persistent_base) {
4531 SCULPT_vertex_persistent_normal_get(ss, vi, normal);
4532 mul_v3_fl(normal, brush->height);
4533 madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor);
4534 }
4535 else {
4536 normal_short_to_float_v3(normal, orig_data.no);
4537 mul_v3_fl(normal, brush->height);
4538 madd_v3_v3v3fl(final_co, orig_data.co, normal, *disp_factor);
4539 }
4540
4541 float vdisp[3];
4542 sub_v3_v3v3(vdisp, final_co, vd.co);
4543 mul_v3_fl(vdisp, fabsf(fade));
4544 add_v3_v3v3(final_co, vd.co, vdisp);
4545
4546 SCULPT_clip(sd, ss, vd.co, final_co);
4547
4548 if (vd.mvert) {
4549 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4550 }
4551 }
4552 }
4553 BKE_pbvh_vertex_iter_end;
4554 }
4555
do_layer_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4556 static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4557 {
4558 SculptSession *ss = ob->sculpt;
4559 Brush *brush = BKE_paint_brush(&sd->paint);
4560
4561 if (ss->cache->layer_displacement_factor == NULL) {
4562 ss->cache->layer_displacement_factor = MEM_callocN(sizeof(float) * SCULPT_vertex_count_get(ss),
4563 "layer displacement factor");
4564 }
4565
4566 SculptThreadedTaskData data = {
4567 .sd = sd,
4568 .ob = ob,
4569 .brush = brush,
4570 .nodes = nodes,
4571 };
4572
4573 TaskParallelSettings settings;
4574 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4575 BLI_task_parallel_range(0, totnode, &data, do_layer_brush_task_cb_ex, &settings);
4576 }
4577
do_inflate_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4578 static void do_inflate_brush_task_cb_ex(void *__restrict userdata,
4579 const int n,
4580 const TaskParallelTLS *__restrict tls)
4581 {
4582 SculptThreadedTaskData *data = userdata;
4583 SculptSession *ss = data->ob->sculpt;
4584 const Brush *brush = data->brush;
4585
4586 PBVHVertexIter vd;
4587 float(*proxy)[3];
4588 const float bstrength = ss->cache->bstrength;
4589
4590 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4591
4592 SculptBrushTest test;
4593 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4594 ss, &test, data->brush->falloff_shape);
4595 const int thread_id = BLI_task_parallel_thread_id(tls);
4596
4597 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4598 {
4599 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4600 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4601 brush,
4602 vd.co,
4603 sqrtf(test.dist),
4604 vd.no,
4605 vd.fno,
4606 vd.mask ? *vd.mask : 0.0f,
4607 vd.index,
4608 thread_id);
4609 float val[3];
4610
4611 if (vd.fno) {
4612 copy_v3_v3(val, vd.fno);
4613 }
4614 else {
4615 normal_short_to_float_v3(val, vd.no);
4616 }
4617
4618 mul_v3_fl(val, fade * ss->cache->radius);
4619 mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale);
4620
4621 if (vd.mvert) {
4622 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4623 }
4624 }
4625 }
4626 BKE_pbvh_vertex_iter_end;
4627 }
4628
do_inflate_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4629 static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4630 {
4631 Brush *brush = BKE_paint_brush(&sd->paint);
4632
4633 SculptThreadedTaskData data = {
4634 .sd = sd,
4635 .ob = ob,
4636 .brush = brush,
4637 .nodes = nodes,
4638 };
4639
4640 TaskParallelSettings settings;
4641 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4642 BLI_task_parallel_range(0, totnode, &data, do_inflate_brush_task_cb_ex, &settings);
4643 }
4644
SCULPT_plane_trim(const StrokeCache * cache,const Brush * brush,const float val[3])4645 int SCULPT_plane_trim(const StrokeCache *cache, const Brush *brush, const float val[3])
4646 {
4647 return (!(brush->flag & BRUSH_PLANE_TRIM) ||
4648 ((dot_v3v3(val, val) <= cache->radius_squared * cache->plane_trim_squared)));
4649 }
4650
plane_point_side_flip(const float co[3],const float plane[4],const bool flip)4651 static bool plane_point_side_flip(const float co[3], const float plane[4], const bool flip)
4652 {
4653 float d = plane_point_side_v3(plane, co);
4654 if (flip) {
4655 d = -d;
4656 }
4657 return d <= 0.0f;
4658 }
4659
SCULPT_plane_point_side(const float co[3],const float plane[4])4660 int SCULPT_plane_point_side(const float co[3], const float plane[4])
4661 {
4662 float d = plane_point_side_v3(plane, co);
4663 return d <= 0.0f;
4664 }
4665
SCULPT_brush_plane_offset_get(Sculpt * sd,SculptSession * ss)4666 float SCULPT_brush_plane_offset_get(Sculpt *sd, SculptSession *ss)
4667 {
4668 Brush *brush = BKE_paint_brush(&sd->paint);
4669
4670 float rv = brush->plane_offset;
4671
4672 if (brush->flag & BRUSH_OFFSET_PRESSURE) {
4673 rv *= ss->cache->pressure;
4674 }
4675
4676 return rv;
4677 }
4678
do_flatten_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4679 static void do_flatten_brush_task_cb_ex(void *__restrict userdata,
4680 const int n,
4681 const TaskParallelTLS *__restrict tls)
4682 {
4683 SculptThreadedTaskData *data = userdata;
4684 SculptSession *ss = data->ob->sculpt;
4685 const Brush *brush = data->brush;
4686 const float *area_no = data->area_no;
4687 const float *area_co = data->area_co;
4688
4689 PBVHVertexIter vd;
4690 float(*proxy)[3];
4691 const float bstrength = ss->cache->bstrength;
4692
4693 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4694
4695 SculptBrushTest test;
4696 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4697 ss, &test, data->brush->falloff_shape);
4698 const int thread_id = BLI_task_parallel_thread_id(tls);
4699
4700 plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
4701
4702 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4703 {
4704 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4705 float intr[3];
4706 float val[3];
4707
4708 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
4709
4710 sub_v3_v3v3(val, intr, vd.co);
4711
4712 if (SCULPT_plane_trim(ss->cache, brush, val)) {
4713 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4714 brush,
4715 vd.co,
4716 sqrtf(test.dist),
4717 vd.no,
4718 vd.fno,
4719 vd.mask ? *vd.mask : 0.0f,
4720 vd.index,
4721 thread_id);
4722
4723 mul_v3_v3fl(proxy[vd.i], val, fade);
4724
4725 if (vd.mvert) {
4726 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4727 }
4728 }
4729 }
4730 }
4731 BKE_pbvh_vertex_iter_end;
4732 }
4733
do_flatten_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4734 static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4735 {
4736 SculptSession *ss = ob->sculpt;
4737 Brush *brush = BKE_paint_brush(&sd->paint);
4738
4739 const float radius = ss->cache->radius;
4740
4741 float area_no[3];
4742 float area_co[3];
4743
4744 float offset = SCULPT_brush_plane_offset_get(sd, ss);
4745 float displace;
4746 float temp[3];
4747
4748 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
4749
4750 SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
4751
4752 displace = radius * offset;
4753
4754 mul_v3_v3v3(temp, area_no, ss->cache->scale);
4755 mul_v3_fl(temp, displace);
4756 add_v3_v3(area_co, temp);
4757
4758 SculptThreadedTaskData data = {
4759 .sd = sd,
4760 .ob = ob,
4761 .brush = brush,
4762 .nodes = nodes,
4763 .area_no = area_no,
4764 .area_co = area_co,
4765 };
4766
4767 TaskParallelSettings settings;
4768 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4769 BLI_task_parallel_range(0, totnode, &data, do_flatten_brush_task_cb_ex, &settings);
4770 }
4771
4772 /* -------------------------------------------------------------------- */
4773
4774 /** \name Sculpt Clay Brush
4775 * \{ */
4776
4777 typedef struct ClaySampleData {
4778 float plane_dist[2];
4779 } ClaySampleData;
4780
calc_clay_surface_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4781 static void calc_clay_surface_task_cb(void *__restrict userdata,
4782 const int n,
4783 const TaskParallelTLS *__restrict tls)
4784 {
4785 SculptThreadedTaskData *data = userdata;
4786 SculptSession *ss = data->ob->sculpt;
4787 const Brush *brush = data->brush;
4788 ClaySampleData *csd = tls->userdata_chunk;
4789 const float *area_no = data->area_no;
4790 const float *area_co = data->area_co;
4791 float plane[4];
4792
4793 PBVHVertexIter vd;
4794
4795 SculptBrushTest test;
4796 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4797 ss, &test, brush->falloff_shape);
4798
4799 /* Apply the brush normal radius to the test before sampling. */
4800 float test_radius = sqrtf(test.radius_squared);
4801 test_radius *= brush->normal_radius_factor;
4802 test.radius_squared = test_radius * test_radius;
4803 plane_from_point_normal_v3(plane, area_co, area_no);
4804
4805 if (is_zero_v4(plane)) {
4806 return;
4807 }
4808
4809 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4810 {
4811
4812 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4813 float plane_dist = dist_signed_to_plane_v3(vd.co, plane);
4814 float plane_dist_abs = fabsf(plane_dist);
4815 if (plane_dist > 0.0f) {
4816 csd->plane_dist[0] = MIN2(csd->plane_dist[0], plane_dist_abs);
4817 }
4818 else {
4819 csd->plane_dist[1] = MIN2(csd->plane_dist[1], plane_dist_abs);
4820 }
4821 }
4822 BKE_pbvh_vertex_iter_end;
4823 }
4824 }
4825
calc_clay_surface_reduce(const void * __restrict UNUSED (userdata),void * __restrict chunk_join,void * __restrict chunk)4826 static void calc_clay_surface_reduce(const void *__restrict UNUSED(userdata),
4827 void *__restrict chunk_join,
4828 void *__restrict chunk)
4829 {
4830 ClaySampleData *join = chunk_join;
4831 ClaySampleData *csd = chunk;
4832 join->plane_dist[0] = MIN2(csd->plane_dist[0], join->plane_dist[0]);
4833 join->plane_dist[1] = MIN2(csd->plane_dist[1], join->plane_dist[1]);
4834 }
4835
do_clay_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4836 static void do_clay_brush_task_cb_ex(void *__restrict userdata,
4837 const int n,
4838 const TaskParallelTLS *__restrict tls)
4839 {
4840 SculptThreadedTaskData *data = userdata;
4841 SculptSession *ss = data->ob->sculpt;
4842 const Brush *brush = data->brush;
4843 const float *area_no = data->area_no;
4844 const float *area_co = data->area_co;
4845
4846 PBVHVertexIter vd;
4847 float(*proxy)[3];
4848 const float bstrength = fabsf(ss->cache->bstrength);
4849
4850 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4851
4852 SculptBrushTest test;
4853 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
4854 ss, &test, data->brush->falloff_shape);
4855 const int thread_id = BLI_task_parallel_thread_id(tls);
4856
4857 plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
4858
4859 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4860 {
4861 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
4862 float intr[3];
4863 float val[3];
4864 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
4865
4866 sub_v3_v3v3(val, intr, vd.co);
4867
4868 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
4869 brush,
4870 vd.co,
4871 sqrtf(test.dist),
4872 vd.no,
4873 vd.fno,
4874 vd.mask ? *vd.mask : 0.0f,
4875 vd.index,
4876 thread_id);
4877
4878 mul_v3_v3fl(proxy[vd.i], val, fade);
4879
4880 if (vd.mvert) {
4881 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
4882 }
4883 }
4884 }
4885 BKE_pbvh_vertex_iter_end;
4886 }
4887
do_clay_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)4888 static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
4889 {
4890 SculptSession *ss = ob->sculpt;
4891 Brush *brush = BKE_paint_brush(&sd->paint);
4892
4893 const float radius = fabsf(ss->cache->radius);
4894 const float initial_radius = fabsf(ss->cache->initial_radius);
4895 bool flip = ss->cache->bstrength < 0.0f;
4896
4897 float offset = SCULPT_brush_plane_offset_get(sd, ss);
4898 float displace;
4899
4900 float area_no[3];
4901 float area_co[3];
4902 float temp[3];
4903
4904 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
4905
4906 SculptThreadedTaskData sample_data = {
4907 .sd = NULL,
4908 .ob = ob,
4909 .brush = brush,
4910 .nodes = nodes,
4911 .totnode = totnode,
4912 .area_no = area_no,
4913 .area_co = ss->cache->location,
4914 };
4915
4916 ClaySampleData csd = {{0}};
4917
4918 TaskParallelSettings sample_settings;
4919 BKE_pbvh_parallel_range_settings(&sample_settings, true, totnode);
4920 sample_settings.func_reduce = calc_clay_surface_reduce;
4921 sample_settings.userdata_chunk = &csd;
4922 sample_settings.userdata_chunk_size = sizeof(ClaySampleData);
4923
4924 BLI_task_parallel_range(0, totnode, &sample_data, calc_clay_surface_task_cb, &sample_settings);
4925
4926 float d_offset = (csd.plane_dist[0] + csd.plane_dist[1]);
4927 d_offset = min_ff(radius, d_offset);
4928 d_offset = d_offset / radius;
4929 d_offset = 1.0f - d_offset;
4930 displace = fabsf(initial_radius * (0.25f + offset + (d_offset * 0.15f)));
4931 if (flip) {
4932 displace = -displace;
4933 }
4934
4935 mul_v3_v3v3(temp, area_no, ss->cache->scale);
4936 mul_v3_fl(temp, displace);
4937 copy_v3_v3(area_co, ss->cache->location);
4938 add_v3_v3(area_co, temp);
4939
4940 SculptThreadedTaskData data = {
4941 .sd = sd,
4942 .ob = ob,
4943 .brush = brush,
4944 .nodes = nodes,
4945 .area_no = area_no,
4946 .area_co = area_co,
4947 };
4948
4949 TaskParallelSettings settings;
4950 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
4951 BLI_task_parallel_range(0, totnode, &data, do_clay_brush_task_cb_ex, &settings);
4952 }
4953
do_clay_strips_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)4954 static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata,
4955 const int n,
4956 const TaskParallelTLS *__restrict tls)
4957 {
4958 SculptThreadedTaskData *data = userdata;
4959 SculptSession *ss = data->ob->sculpt;
4960 const Brush *brush = data->brush;
4961 float(*mat)[4] = data->mat;
4962 const float *area_no_sp = data->area_no_sp;
4963 const float *area_co = data->area_co;
4964
4965 PBVHVertexIter vd;
4966 SculptBrushTest test;
4967 float(*proxy)[3];
4968 const bool flip = (ss->cache->bstrength < 0.0f);
4969 const float bstrength = flip ? -ss->cache->bstrength : ss->cache->bstrength;
4970
4971 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
4972
4973 SCULPT_brush_test_init(ss, &test);
4974 plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp);
4975 const int thread_id = BLI_task_parallel_thread_id(tls);
4976
4977 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
4978 {
4979 if (SCULPT_brush_test_cube(&test, vd.co, mat, brush->tip_roundness)) {
4980 if (plane_point_side_flip(vd.co, test.plane_tool, flip)) {
4981 float intr[3];
4982 float val[3];
4983
4984 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
4985
4986 sub_v3_v3v3(val, intr, vd.co);
4987
4988 if (SCULPT_plane_trim(ss->cache, brush, val)) {
4989 /* The normal from the vertices is ignored, it causes glitch with planes, see: T44390. */
4990 const float fade = bstrength *
4991 SCULPT_brush_strength_factor(ss,
4992 brush,
4993 vd.co,
4994 ss->cache->radius * test.dist,
4995 vd.no,
4996 vd.fno,
4997 vd.mask ? *vd.mask : 0.0f,
4998 vd.index,
4999 thread_id);
5000
5001 mul_v3_v3fl(proxy[vd.i], val, fade);
5002
5003 if (vd.mvert) {
5004 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
5005 }
5006 }
5007 }
5008 }
5009 }
5010 BKE_pbvh_vertex_iter_end;
5011 }
5012
do_clay_strips_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)5013 static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
5014 {
5015 SculptSession *ss = ob->sculpt;
5016 Brush *brush = BKE_paint_brush(&sd->paint);
5017
5018 const bool flip = (ss->cache->bstrength < 0.0f);
5019 const float radius = flip ? -ss->cache->radius : ss->cache->radius;
5020 const float offset = SCULPT_brush_plane_offset_get(sd, ss);
5021 const float displace = radius * (0.18f + offset);
5022
5023 /* The sculpt-plane normal (whatever its set to). */
5024 float area_no_sp[3];
5025
5026 /* Geometry normal */
5027 float area_no[3];
5028 float area_co[3];
5029
5030 float temp[3];
5031 float mat[4][4];
5032 float scale[4][4];
5033 float tmat[4][4];
5034
5035 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
5036 SCULPT_tilt_apply_to_normal(area_no_sp, ss->cache, brush->tilt_strength_factor);
5037
5038 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
5039 SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
5040 }
5041 else {
5042 copy_v3_v3(area_no, area_no_sp);
5043 }
5044
5045 /* Delay the first daub because grab delta is not setup. */
5046 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
5047 return;
5048 }
5049
5050 if (is_zero_v3(ss->cache->grab_delta_symmetry)) {
5051 return;
5052 }
5053
5054 mul_v3_v3v3(temp, area_no_sp, ss->cache->scale);
5055 mul_v3_fl(temp, displace);
5056 add_v3_v3(area_co, temp);
5057
5058 /* Clay Strips uses a cube test with falloff in the XY axis (not in Z) and a plane to deform the
5059 * vertices. When in Add mode, vertices that are below the plane and inside the cube are move
5060 * towards the plane. In this situation, there may be cases where a vertex is outside the cube
5061 * but below the plane, so won't be deformed, causing artifacts. In order to prevent these
5062 * artifacts, this displaces the test cube space in relation to the plane in order to
5063 * deform more vertices that may be below it. */
5064 /* The 0.7 and 1.25 factors are arbitrary and don't have any relation between them, they were set
5065 * by doing multiple tests using the default "Clay Strips" brush preset. */
5066 float area_co_displaced[3];
5067 madd_v3_v3v3fl(area_co_displaced, area_co, area_no, -radius * 0.7f);
5068
5069 /* Initialize brush local-space matrix. */
5070 cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
5071 mat[0][3] = 0.0f;
5072 cross_v3_v3v3(mat[1], area_no, mat[0]);
5073 mat[1][3] = 0.0f;
5074 copy_v3_v3(mat[2], area_no);
5075 mat[2][3] = 0.0f;
5076 copy_v3_v3(mat[3], area_co_displaced);
5077 mat[3][3] = 1.0f;
5078 normalize_m4(mat);
5079
5080 /* Scale brush local space matrix. */
5081 scale_m4_fl(scale, ss->cache->radius);
5082 mul_m4_m4m4(tmat, mat, scale);
5083
5084 /* Deform the local space in Z to scale the test cube. As the test cube does not have falloff in
5085 * Z this does not produce artifacts in the falloff cube and allows to deform extra vertices
5086 * during big deformation while keeping the surface as uniform as possible. */
5087 mul_v3_fl(tmat[2], 1.25f);
5088
5089 invert_m4_m4(mat, tmat);
5090
5091 SculptThreadedTaskData data = {
5092 .sd = sd,
5093 .ob = ob,
5094 .brush = brush,
5095 .nodes = nodes,
5096 .area_no_sp = area_no_sp,
5097 .area_co = area_co,
5098 .mat = mat,
5099 };
5100
5101 TaskParallelSettings settings;
5102 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5103 BLI_task_parallel_range(0, totnode, &data, do_clay_strips_brush_task_cb_ex, &settings);
5104 }
5105
do_fill_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)5106 static void do_fill_brush_task_cb_ex(void *__restrict userdata,
5107 const int n,
5108 const TaskParallelTLS *__restrict tls)
5109 {
5110 SculptThreadedTaskData *data = userdata;
5111 SculptSession *ss = data->ob->sculpt;
5112 const Brush *brush = data->brush;
5113 const float *area_no = data->area_no;
5114 const float *area_co = data->area_co;
5115
5116 PBVHVertexIter vd;
5117 float(*proxy)[3];
5118 const float bstrength = ss->cache->bstrength;
5119
5120 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
5121
5122 SculptBrushTest test;
5123 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
5124 ss, &test, data->brush->falloff_shape);
5125 const int thread_id = BLI_task_parallel_thread_id(tls);
5126
5127 plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
5128
5129 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
5130 {
5131 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
5132 if (SCULPT_plane_point_side(vd.co, test.plane_tool)) {
5133 float intr[3];
5134 float val[3];
5135
5136 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
5137
5138 sub_v3_v3v3(val, intr, vd.co);
5139
5140 if (SCULPT_plane_trim(ss->cache, brush, val)) {
5141 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
5142 brush,
5143 vd.co,
5144 sqrtf(test.dist),
5145 vd.no,
5146 vd.fno,
5147 vd.mask ? *vd.mask : 0.0f,
5148 vd.index,
5149 thread_id);
5150
5151 mul_v3_v3fl(proxy[vd.i], val, fade);
5152
5153 if (vd.mvert) {
5154 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
5155 }
5156 }
5157 }
5158 }
5159 }
5160 BKE_pbvh_vertex_iter_end;
5161 }
5162
do_fill_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)5163 static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
5164 {
5165 SculptSession *ss = ob->sculpt;
5166 Brush *brush = BKE_paint_brush(&sd->paint);
5167
5168 const float radius = ss->cache->radius;
5169
5170 float area_no[3];
5171 float area_co[3];
5172 float offset = SCULPT_brush_plane_offset_get(sd, ss);
5173
5174 float displace;
5175
5176 float temp[3];
5177
5178 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
5179
5180 SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
5181
5182 displace = radius * offset;
5183
5184 mul_v3_v3v3(temp, area_no, ss->cache->scale);
5185 mul_v3_fl(temp, displace);
5186 add_v3_v3(area_co, temp);
5187
5188 SculptThreadedTaskData data = {
5189 .sd = sd,
5190 .ob = ob,
5191 .brush = brush,
5192 .nodes = nodes,
5193 .area_no = area_no,
5194 .area_co = area_co,
5195 };
5196
5197 TaskParallelSettings settings;
5198 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5199 BLI_task_parallel_range(0, totnode, &data, do_fill_brush_task_cb_ex, &settings);
5200 }
5201
do_scrape_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)5202 static void do_scrape_brush_task_cb_ex(void *__restrict userdata,
5203 const int n,
5204 const TaskParallelTLS *__restrict tls)
5205 {
5206 SculptThreadedTaskData *data = userdata;
5207 SculptSession *ss = data->ob->sculpt;
5208 const Brush *brush = data->brush;
5209 const float *area_no = data->area_no;
5210 const float *area_co = data->area_co;
5211
5212 PBVHVertexIter vd;
5213 float(*proxy)[3];
5214 const float bstrength = ss->cache->bstrength;
5215
5216 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
5217
5218 SculptBrushTest test;
5219 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
5220 ss, &test, data->brush->falloff_shape);
5221 const int thread_id = BLI_task_parallel_thread_id(tls);
5222 plane_from_point_normal_v3(test.plane_tool, area_co, area_no);
5223
5224 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
5225 {
5226 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
5227 if (!SCULPT_plane_point_side(vd.co, test.plane_tool)) {
5228 float intr[3];
5229 float val[3];
5230
5231 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
5232
5233 sub_v3_v3v3(val, intr, vd.co);
5234
5235 if (SCULPT_plane_trim(ss->cache, brush, val)) {
5236 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
5237 brush,
5238 vd.co,
5239 sqrtf(test.dist),
5240 vd.no,
5241 vd.fno,
5242 vd.mask ? *vd.mask : 0.0f,
5243 vd.index,
5244 thread_id);
5245
5246 mul_v3_v3fl(proxy[vd.i], val, fade);
5247
5248 if (vd.mvert) {
5249 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
5250 }
5251 }
5252 }
5253 }
5254 }
5255 BKE_pbvh_vertex_iter_end;
5256 }
5257
do_scrape_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)5258 static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
5259 {
5260 SculptSession *ss = ob->sculpt;
5261 Brush *brush = BKE_paint_brush(&sd->paint);
5262
5263 const float radius = ss->cache->radius;
5264
5265 float area_no[3];
5266 float area_co[3];
5267 float offset = SCULPT_brush_plane_offset_get(sd, ss);
5268
5269 float displace;
5270
5271 float temp[3];
5272
5273 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co);
5274
5275 SCULPT_tilt_apply_to_normal(area_no, ss->cache, brush->tilt_strength_factor);
5276
5277 displace = -radius * offset;
5278
5279 mul_v3_v3v3(temp, area_no, ss->cache->scale);
5280 mul_v3_fl(temp, displace);
5281 add_v3_v3(area_co, temp);
5282
5283 SculptThreadedTaskData data = {
5284 .sd = sd,
5285 .ob = ob,
5286 .brush = brush,
5287 .nodes = nodes,
5288 .area_no = area_no,
5289 .area_co = area_co,
5290 };
5291
5292 TaskParallelSettings settings;
5293 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5294 BLI_task_parallel_range(0, totnode, &data, do_scrape_brush_task_cb_ex, &settings);
5295 }
5296
5297 /* -------------------------------------------------------------------- */
5298
5299 /** \name Sculpt Clay Thumb Brush
5300 * \{ */
5301
do_clay_thumb_brush_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)5302 static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata,
5303 const int n,
5304 const TaskParallelTLS *__restrict tls)
5305 {
5306 SculptThreadedTaskData *data = userdata;
5307 SculptSession *ss = data->ob->sculpt;
5308 const Brush *brush = data->brush;
5309 float(*mat)[4] = data->mat;
5310 const float *area_no_sp = data->area_no_sp;
5311 const float *area_co = data->area_co;
5312
5313 PBVHVertexIter vd;
5314 float(*proxy)[3];
5315 const float bstrength = data->clay_strength;
5316
5317 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
5318
5319 SculptBrushTest test;
5320 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
5321 ss, &test, data->brush->falloff_shape);
5322 const int thread_id = BLI_task_parallel_thread_id(tls);
5323
5324 float plane_tilt[4];
5325 float normal_tilt[3];
5326 float imat[4][4];
5327
5328 invert_m4_m4(imat, mat);
5329 rotate_v3_v3v3fl(normal_tilt, area_no_sp, imat[0], DEG2RADF(-ss->cache->clay_thumb_front_angle));
5330
5331 /* Plane aligned to the geometry normal (back part of the brush). */
5332 plane_from_point_normal_v3(test.plane_tool, area_co, area_no_sp);
5333 /* Tilted plane (front part of the brush). */
5334 plane_from_point_normal_v3(plane_tilt, area_co, normal_tilt);
5335
5336 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
5337 {
5338 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
5339 float local_co[3];
5340 mul_v3_m4v3(local_co, mat, vd.co);
5341 float intr[3], intr_tilt[3];
5342 float val[3];
5343
5344 closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
5345 closest_to_plane_normalized_v3(intr_tilt, plane_tilt, vd.co);
5346
5347 /* Mix the deformation of the aligned and the tilted plane based on the brush space vertex
5348 * coordinates. */
5349 /* We can also control the mix with a curve if it produces noticeable artifacts in the center
5350 * of the brush. */
5351 const float tilt_mix = local_co[1] > 0.0f ? 0.0f : 1.0f;
5352 interp_v3_v3v3(intr, intr, intr_tilt, tilt_mix);
5353 sub_v3_v3v3(val, intr_tilt, vd.co);
5354
5355 const float fade = bstrength * SCULPT_brush_strength_factor(ss,
5356 brush,
5357 vd.co,
5358 sqrtf(test.dist),
5359 vd.no,
5360 vd.fno,
5361 vd.mask ? *vd.mask : 0.0f,
5362 vd.index,
5363 thread_id);
5364
5365 mul_v3_v3fl(proxy[vd.i], val, fade);
5366
5367 if (vd.mvert) {
5368 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
5369 }
5370 }
5371 }
5372 BKE_pbvh_vertex_iter_end;
5373 }
5374
sculpt_clay_thumb_get_stabilized_pressure(StrokeCache * cache)5375 static float sculpt_clay_thumb_get_stabilized_pressure(StrokeCache *cache)
5376 {
5377 float final_pressure = 0.0f;
5378 for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
5379 final_pressure += cache->clay_pressure_stabilizer[i];
5380 }
5381 return final_pressure / SCULPT_CLAY_STABILIZER_LEN;
5382 }
5383
do_clay_thumb_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)5384 static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
5385 {
5386 SculptSession *ss = ob->sculpt;
5387 Brush *brush = BKE_paint_brush(&sd->paint);
5388
5389 const float radius = ss->cache->radius;
5390 const float offset = SCULPT_brush_plane_offset_get(sd, ss);
5391 const float displace = radius * (0.25f + offset);
5392
5393 /* Sampled geometry normal and area center. */
5394 float area_no_sp[3];
5395 float area_no[3];
5396 float area_co[3];
5397
5398 float temp[3];
5399 float mat[4][4];
5400 float scale[4][4];
5401 float tmat[4][4];
5402
5403 SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no_sp, area_co);
5404
5405 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA || (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
5406 SCULPT_calc_area_normal(sd, ob, nodes, totnode, area_no);
5407 }
5408 else {
5409 copy_v3_v3(area_no, area_no_sp);
5410 }
5411
5412 /* Delay the first daub because grab delta is not setup. */
5413 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
5414 ss->cache->clay_thumb_front_angle = 0.0f;
5415 return;
5416 }
5417
5418 /* Simulate the clay accumulation by increasing the plane angle as more samples are added to the
5419 * stroke. */
5420 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
5421 ss->cache->clay_thumb_front_angle += 0.8f;
5422 ss->cache->clay_thumb_front_angle = clamp_f(ss->cache->clay_thumb_front_angle, 0.0f, 60.0f);
5423 }
5424
5425 if (is_zero_v3(ss->cache->grab_delta_symmetry)) {
5426 return;
5427 }
5428
5429 /* Displace the brush planes. */
5430 copy_v3_v3(area_co, ss->cache->location);
5431 mul_v3_v3v3(temp, area_no_sp, ss->cache->scale);
5432 mul_v3_fl(temp, displace);
5433 add_v3_v3(area_co, temp);
5434
5435 /* Initialize brush local-space matrix. */
5436 cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry);
5437 mat[0][3] = 0.0f;
5438 cross_v3_v3v3(mat[1], area_no, mat[0]);
5439 mat[1][3] = 0.0f;
5440 copy_v3_v3(mat[2], area_no);
5441 mat[2][3] = 0.0f;
5442 copy_v3_v3(mat[3], ss->cache->location);
5443 mat[3][3] = 1.0f;
5444 normalize_m4(mat);
5445
5446 /* Scale brush local space matrix. */
5447 scale_m4_fl(scale, ss->cache->radius);
5448 mul_m4_m4m4(tmat, mat, scale);
5449 invert_m4_m4(mat, tmat);
5450
5451 float clay_strength = ss->cache->bstrength *
5452 sculpt_clay_thumb_get_stabilized_pressure(ss->cache);
5453
5454 SculptThreadedTaskData data = {
5455 .sd = sd,
5456 .ob = ob,
5457 .brush = brush,
5458 .nodes = nodes,
5459 .area_no_sp = area_no_sp,
5460 .area_co = ss->cache->location,
5461 .mat = mat,
5462 .clay_strength = clay_strength,
5463 };
5464
5465 TaskParallelSettings settings;
5466 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5467 BLI_task_parallel_range(0, totnode, &data, do_clay_thumb_brush_task_cb_ex, &settings);
5468 }
5469
5470 /** \} */
5471
do_gravity_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)5472 static void do_gravity_task_cb_ex(void *__restrict userdata,
5473 const int n,
5474 const TaskParallelTLS *__restrict tls)
5475 {
5476 SculptThreadedTaskData *data = userdata;
5477 SculptSession *ss = data->ob->sculpt;
5478 const Brush *brush = data->brush;
5479 float *offset = data->offset;
5480
5481 PBVHVertexIter vd;
5482 float(*proxy)[3];
5483
5484 proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
5485
5486 SculptBrushTest test;
5487 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
5488 ss, &test, data->brush->falloff_shape);
5489 const int thread_id = BLI_task_parallel_thread_id(tls);
5490
5491 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
5492 {
5493 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
5494 const float fade = SCULPT_brush_strength_factor(ss,
5495 brush,
5496 vd.co,
5497 sqrtf(test.dist),
5498 vd.no,
5499 vd.fno,
5500 vd.mask ? *vd.mask : 0.0f,
5501 vd.index,
5502 thread_id);
5503
5504 mul_v3_v3fl(proxy[vd.i], offset, fade);
5505
5506 if (vd.mvert) {
5507 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
5508 }
5509 }
5510 }
5511 BKE_pbvh_vertex_iter_end;
5512 }
5513
do_gravity(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode,float bstrength)5514 static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength)
5515 {
5516 SculptSession *ss = ob->sculpt;
5517 Brush *brush = BKE_paint_brush(&sd->paint);
5518
5519 float offset[3];
5520 float gravity_vector[3];
5521
5522 mul_v3_v3fl(gravity_vector, ss->cache->gravity_direction, -ss->cache->radius_squared);
5523
5524 /* Offset with as much as possible factored in already. */
5525 mul_v3_v3v3(offset, gravity_vector, ss->cache->scale);
5526 mul_v3_fl(offset, bstrength);
5527
5528 /* Threaded loop over nodes. */
5529 SculptThreadedTaskData data = {
5530 .sd = sd,
5531 .ob = ob,
5532 .brush = brush,
5533 .nodes = nodes,
5534 .offset = offset,
5535 };
5536
5537 TaskParallelSettings settings;
5538 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5539 BLI_task_parallel_range(0, totnode, &data, do_gravity_task_cb_ex, &settings);
5540 }
5541
SCULPT_vertcos_to_key(Object * ob,KeyBlock * kb,const float (* vertCos)[3])5542 void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3])
5543 {
5544 Mesh *me = (Mesh *)ob->data;
5545 float(*ofs)[3] = NULL;
5546 int a;
5547 const int kb_act_idx = ob->shapenr - 1;
5548 KeyBlock *currkey;
5549
5550 /* For relative keys editing of base should update other keys. */
5551 if (BKE_keyblock_is_basis(me->key, kb_act_idx)) {
5552 ofs = BKE_keyblock_convert_to_vertcos(ob, kb);
5553
5554 /* Calculate key coord offsets (from previous location). */
5555 for (a = 0; a < me->totvert; a++) {
5556 sub_v3_v3v3(ofs[a], vertCos[a], ofs[a]);
5557 }
5558
5559 /* Apply offsets on other keys. */
5560 for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
5561 if ((currkey != kb) && (currkey->relative == kb_act_idx)) {
5562 BKE_keyblock_update_from_offset(ob, currkey, ofs);
5563 }
5564 }
5565
5566 MEM_freeN(ofs);
5567 }
5568
5569 /* Modifying of basis key should update mesh. */
5570 if (kb == me->key->refkey) {
5571 MVert *mvert = me->mvert;
5572
5573 for (a = 0; a < me->totvert; a++, mvert++) {
5574 copy_v3_v3(mvert->co, vertCos[a]);
5575 }
5576
5577 BKE_mesh_calc_normals(me);
5578 }
5579
5580 /* Apply new coords on active key block, no need to re-allocate kb->data here! */
5581 BKE_keyblock_update_from_vertcos(ob, kb, vertCos);
5582 }
5583
5584 /* Note: we do the topology update before any brush actions to avoid
5585 * issues with the proxies. The size of the proxy can't change, so
5586 * topology must be updated first. */
sculpt_topology_update(Sculpt * sd,Object * ob,Brush * brush,UnifiedPaintSettings * UNUSED (ups))5587 static void sculpt_topology_update(Sculpt *sd,
5588 Object *ob,
5589 Brush *brush,
5590 UnifiedPaintSettings *UNUSED(ups))
5591 {
5592 SculptSession *ss = ob->sculpt;
5593
5594 int n, totnode;
5595 /* Build a list of all nodes that are potentially within the brush's area of influence. */
5596 const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
5597 ss->cache->original;
5598 const float radius_scale = 1.25f;
5599 PBVHNode **nodes = sculpt_pbvh_gather_generic(
5600 ob, sd, brush, use_original, radius_scale, &totnode);
5601
5602 /* Only act if some verts are inside the brush area. */
5603 if (totnode) {
5604 PBVHTopologyUpdateMode mode = 0;
5605 float location[3];
5606
5607 if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
5608 if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
5609 mode |= PBVH_Subdivide;
5610 }
5611
5612 if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
5613 mode |= PBVH_Collapse;
5614 }
5615 }
5616
5617 for (n = 0; n < totnode; n++) {
5618 SCULPT_undo_push_node(ob,
5619 nodes[n],
5620 brush->sculpt_tool == SCULPT_TOOL_MASK ? SCULPT_UNDO_MASK :
5621 SCULPT_UNDO_COORDS);
5622 BKE_pbvh_node_mark_update(nodes[n]);
5623
5624 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
5625 BKE_pbvh_node_mark_topology_update(nodes[n]);
5626 BKE_pbvh_bmesh_node_save_orig(ss->bm, nodes[n]);
5627 }
5628 }
5629
5630 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
5631 BKE_pbvh_bmesh_update_topology(ss->pbvh,
5632 mode,
5633 ss->cache->location,
5634 ss->cache->view_normal,
5635 ss->cache->radius,
5636 (brush->flag & BRUSH_FRONTFACE) != 0,
5637 (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
5638 }
5639
5640 MEM_SAFE_FREE(nodes);
5641
5642 /* Update average stroke position. */
5643 copy_v3_v3(location, ss->cache->true_location);
5644 mul_m4_v3(ob->obmat, location);
5645 }
5646 }
5647
do_brush_action_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))5648 static void do_brush_action_task_cb(void *__restrict userdata,
5649 const int n,
5650 const TaskParallelTLS *__restrict UNUSED(tls))
5651 {
5652 SculptThreadedTaskData *data = userdata;
5653 SculptSession *ss = data->ob->sculpt;
5654
5655 /* Face Sets modifications do a single undo push */
5656 if (data->brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) {
5657 BKE_pbvh_node_mark_redraw(data->nodes[n]);
5658 /* Draw face sets in smooth mode moves the vertices. */
5659 if (ss->cache->alt_smooth) {
5660 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
5661 BKE_pbvh_node_mark_update(data->nodes[n]);
5662 }
5663 }
5664 else if (data->brush->sculpt_tool == SCULPT_TOOL_MASK) {
5665 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
5666 BKE_pbvh_node_mark_update_mask(data->nodes[n]);
5667 }
5668 else if (ELEM(data->brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
5669 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COLOR);
5670 BKE_pbvh_node_mark_update_color(data->nodes[n]);
5671 }
5672 else {
5673 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS);
5674 BKE_pbvh_node_mark_update(data->nodes[n]);
5675 }
5676 }
5677
do_brush_action(Sculpt * sd,Object * ob,Brush * brush,UnifiedPaintSettings * ups)5678 static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups)
5679 {
5680 SculptSession *ss = ob->sculpt;
5681 int totnode;
5682 PBVHNode **nodes;
5683
5684 /* Check for unsupported features. */
5685 PBVHType type = BKE_pbvh_type(ss->pbvh);
5686 if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) {
5687 if (!U.experimental.use_sculpt_vertex_colors) {
5688 return;
5689 }
5690 }
5691
5692 if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) {
5693 if (!U.experimental.use_sculpt_vertex_colors) {
5694 return;
5695 }
5696 }
5697
5698 /* Build a list of all nodes that are potentially within the brush's area of influence */
5699
5700 /* These brushes need to update all nodes as they are not constrained by the brush radius */
5701 /* Elastic deform needs all nodes to avoid artifacts as the effect of the brush is not
5702 * constrained by the radius. */
5703 /* Pose needs all nodes because it applies all symmetry iterations at the same time and the IK
5704 * chain can grow to any area of the model. */
5705 /* This can be optimized by filtering the nodes after calculating the chain. */
5706 if (ELEM(brush->sculpt_tool,
5707 SCULPT_TOOL_ELASTIC_DEFORM,
5708 SCULPT_TOOL_POSE,
5709 SCULPT_TOOL_BOUNDARY)) {
5710 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
5711 }
5712 else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
5713 if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) {
5714 SculptSearchSphereData data = {
5715 .ss = ss,
5716 .sd = sd,
5717 .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)),
5718 .original = false,
5719 .ignore_fully_ineffective = false,
5720 .center = ss->cache->initial_location,
5721 };
5722 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
5723 }
5724 if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_DYNAMIC) {
5725 SculptSearchSphereData data = {
5726 .ss = ss,
5727 .sd = sd,
5728 .radius_squared = square_f(ss->cache->radius * (1.0 + brush->cloth_sim_limit)),
5729 .original = false,
5730 .ignore_fully_ineffective = false,
5731 .center = ss->cache->location,
5732 };
5733 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
5734 }
5735 else {
5736 /* Gobal simulation, get all nodes. */
5737 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
5738 }
5739 }
5740 else {
5741 const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
5742 ss->cache->original;
5743 float radius_scale = 1.0f;
5744 /* With these options enabled not all required nodes are inside the original brush radius, so
5745 * the brush can produce artifacts in some situations. */
5746 if (brush->sculpt_tool == SCULPT_TOOL_DRAW && brush->flag & BRUSH_ORIGINAL_NORMAL) {
5747 radius_scale = 2.0f;
5748 }
5749 nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode);
5750 }
5751
5752 /* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the
5753 * vertices and uses regular coords undo. */
5754 /* It also assigns the paint_face_set here as it needs to be done regardless of the stroke type
5755 * and the number of nodes under the brush influence. */
5756 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS &&
5757 SCULPT_stroke_is_first_brush_step(ss->cache) && !ss->cache->alt_smooth) {
5758
5759 /* Dynamic-topology does not support Face Sets data, so it can't store/restore it from undo. */
5760 /* TODO(pablodp606): This check should be done in the undo code and not here, but the rest of
5761 * the sculpt code is not checking for unsupported undo types that may return a null node. */
5762 if (BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) {
5763 SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_FACE_SETS);
5764 }
5765
5766 if (ss->cache->invert) {
5767 /* When inverting the brush, pick the paint face mask ID from the mesh. */
5768 ss->cache->paint_face_set = SCULPT_active_face_set_get(ss);
5769 }
5770 else {
5771 /* By default create a new Face Sets. */
5772 ss->cache->paint_face_set = SCULPT_face_set_next_available_get(ss);
5773 }
5774 }
5775
5776 /* Only act if some verts are inside the brush area. */
5777 if (totnode) {
5778 float location[3];
5779
5780 SculptThreadedTaskData task_data = {
5781 .sd = sd,
5782 .ob = ob,
5783 .brush = brush,
5784 .nodes = nodes,
5785 };
5786
5787 TaskParallelSettings settings;
5788 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
5789 BLI_task_parallel_range(0, totnode, &task_data, do_brush_action_task_cb, &settings);
5790
5791 if (sculpt_brush_needs_normal(ss, brush)) {
5792 update_sculpt_normal(sd, ob, nodes, totnode);
5793 }
5794
5795 if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) {
5796 update_brush_local_mat(sd, ob);
5797 }
5798
5799 if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
5800 if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
5801 ss->cache->automasking = SCULPT_automasking_cache_init(sd, brush, ob);
5802 }
5803 }
5804
5805 if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
5806 SCULPT_pose_brush_init(sd, ob, ss, brush);
5807 }
5808
5809 if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
5810 if (!ss->cache->cloth_sim) {
5811 ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(
5812 ss, 1.0f, 0.0f, 0.0f, false, true);
5813 SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim);
5814 }
5815 SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim);
5816 SCULPT_cloth_brush_ensure_nodes_constraints(
5817 sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
5818 }
5819
5820 bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN;
5821
5822 /* Apply one type of brush action. */
5823 switch (brush->sculpt_tool) {
5824 case SCULPT_TOOL_DRAW:
5825 do_draw_brush(sd, ob, nodes, totnode);
5826 break;
5827 case SCULPT_TOOL_SMOOTH:
5828 if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
5829 SCULPT_do_smooth_brush(sd, ob, nodes, totnode);
5830 }
5831 else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
5832 SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
5833 }
5834 break;
5835 case SCULPT_TOOL_CREASE:
5836 do_crease_brush(sd, ob, nodes, totnode);
5837 break;
5838 case SCULPT_TOOL_BLOB:
5839 do_crease_brush(sd, ob, nodes, totnode);
5840 break;
5841 case SCULPT_TOOL_PINCH:
5842 do_pinch_brush(sd, ob, nodes, totnode);
5843 break;
5844 case SCULPT_TOOL_INFLATE:
5845 do_inflate_brush(sd, ob, nodes, totnode);
5846 break;
5847 case SCULPT_TOOL_GRAB:
5848 do_grab_brush(sd, ob, nodes, totnode);
5849 break;
5850 case SCULPT_TOOL_ROTATE:
5851 do_rotate_brush(sd, ob, nodes, totnode);
5852 break;
5853 case SCULPT_TOOL_SNAKE_HOOK:
5854 do_snake_hook_brush(sd, ob, nodes, totnode);
5855 break;
5856 case SCULPT_TOOL_NUDGE:
5857 do_nudge_brush(sd, ob, nodes, totnode);
5858 break;
5859 case SCULPT_TOOL_THUMB:
5860 do_thumb_brush(sd, ob, nodes, totnode);
5861 break;
5862 case SCULPT_TOOL_LAYER:
5863 do_layer_brush(sd, ob, nodes, totnode);
5864 break;
5865 case SCULPT_TOOL_FLATTEN:
5866 do_flatten_brush(sd, ob, nodes, totnode);
5867 break;
5868 case SCULPT_TOOL_CLAY:
5869 do_clay_brush(sd, ob, nodes, totnode);
5870 break;
5871 case SCULPT_TOOL_CLAY_STRIPS:
5872 do_clay_strips_brush(sd, ob, nodes, totnode);
5873 break;
5874 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
5875 SCULPT_do_multiplane_scrape_brush(sd, ob, nodes, totnode);
5876 break;
5877 case SCULPT_TOOL_CLAY_THUMB:
5878 do_clay_thumb_brush(sd, ob, nodes, totnode);
5879 break;
5880 case SCULPT_TOOL_FILL:
5881 if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
5882 do_scrape_brush(sd, ob, nodes, totnode);
5883 }
5884 else {
5885 do_fill_brush(sd, ob, nodes, totnode);
5886 }
5887 break;
5888 case SCULPT_TOOL_SCRAPE:
5889 if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
5890 do_fill_brush(sd, ob, nodes, totnode);
5891 }
5892 else {
5893 do_scrape_brush(sd, ob, nodes, totnode);
5894 }
5895 break;
5896 case SCULPT_TOOL_MASK:
5897 do_mask_brush(sd, ob, nodes, totnode);
5898 break;
5899 case SCULPT_TOOL_POSE:
5900 SCULPT_do_pose_brush(sd, ob, nodes, totnode);
5901 break;
5902 case SCULPT_TOOL_DRAW_SHARP:
5903 do_draw_sharp_brush(sd, ob, nodes, totnode);
5904 break;
5905 case SCULPT_TOOL_ELASTIC_DEFORM:
5906 do_elastic_deform_brush(sd, ob, nodes, totnode);
5907 break;
5908 case SCULPT_TOOL_SLIDE_RELAX:
5909 do_slide_relax_brush(sd, ob, nodes, totnode);
5910 break;
5911 case SCULPT_TOOL_BOUNDARY:
5912 SCULPT_do_boundary_brush(sd, ob, nodes, totnode);
5913 break;
5914 case SCULPT_TOOL_CLOTH:
5915 SCULPT_do_cloth_brush(sd, ob, nodes, totnode);
5916 break;
5917 case SCULPT_TOOL_DRAW_FACE_SETS:
5918 SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode);
5919 break;
5920 case SCULPT_TOOL_DISPLACEMENT_ERASER:
5921 do_displacement_eraser_brush(sd, ob, nodes, totnode);
5922 break;
5923 case SCULPT_TOOL_PAINT:
5924 SCULPT_do_paint_brush(sd, ob, nodes, totnode);
5925 break;
5926 case SCULPT_TOOL_SMEAR:
5927 SCULPT_do_smear_brush(sd, ob, nodes, totnode);
5928 break;
5929 }
5930
5931 if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
5932 brush->autosmooth_factor > 0) {
5933 if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
5934 SCULPT_smooth(sd,
5935 ob,
5936 nodes,
5937 totnode,
5938 brush->autosmooth_factor * (1.0f - ss->cache->pressure),
5939 false);
5940 }
5941 else {
5942 SCULPT_smooth(sd, ob, nodes, totnode, brush->autosmooth_factor, false);
5943 }
5944 }
5945
5946 if (sculpt_brush_use_topology_rake(ss, brush)) {
5947 bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
5948 }
5949
5950 /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
5951 if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool,
5952 SCULPT_TOOL_CLOTH,
5953 SCULPT_TOOL_DRAW_FACE_SETS,
5954 SCULPT_TOOL_BOUNDARY)) {
5955 do_gravity(sd, ob, nodes, totnode, sd->gravity_factor);
5956 }
5957
5958 if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
5959 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
5960 SCULPT_cloth_sim_activate_nodes(ss->cache->cloth_sim, nodes, totnode);
5961 SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode);
5962 }
5963 }
5964
5965 MEM_SAFE_FREE(nodes);
5966
5967 /* Update average stroke position. */
5968 copy_v3_v3(location, ss->cache->true_location);
5969 mul_m4_v3(ob->obmat, location);
5970
5971 add_v3_v3(ups->average_stroke_accum, location);
5972 ups->average_stroke_counter++;
5973 /* Update last stroke position. */
5974 ups->last_stroke_valid = true;
5975 }
5976 }
5977
5978 /* Flush displacement from deformed PBVH vertex to original mesh. */
sculpt_flush_pbvhvert_deform(Object * ob,PBVHVertexIter * vd)5979 static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd)
5980 {
5981 SculptSession *ss = ob->sculpt;
5982 Mesh *me = ob->data;
5983 float disp[3], newco[3];
5984 int index = vd->vert_indices[vd->i];
5985
5986 sub_v3_v3v3(disp, vd->co, ss->deform_cos[index]);
5987 mul_m3_v3(ss->deform_imats[index], disp);
5988 add_v3_v3v3(newco, disp, ss->orig_cos[index]);
5989
5990 copy_v3_v3(ss->deform_cos[index], vd->co);
5991 copy_v3_v3(ss->orig_cos[index], newco);
5992
5993 if (!ss->shapekey_active) {
5994 copy_v3_v3(me->mvert[index].co, newco);
5995 }
5996 }
5997
sculpt_combine_proxies_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))5998 static void sculpt_combine_proxies_task_cb(void *__restrict userdata,
5999 const int n,
6000 const TaskParallelTLS *__restrict UNUSED(tls))
6001 {
6002 SculptThreadedTaskData *data = userdata;
6003 SculptSession *ss = data->ob->sculpt;
6004 Sculpt *sd = data->sd;
6005 Object *ob = data->ob;
6006
6007 /* These brushes start from original coordinates. */
6008 const bool use_orco = ELEM(data->brush->sculpt_tool,
6009 SCULPT_TOOL_GRAB,
6010 SCULPT_TOOL_ROTATE,
6011 SCULPT_TOOL_THUMB,
6012 SCULPT_TOOL_ELASTIC_DEFORM,
6013 SCULPT_TOOL_BOUNDARY,
6014 SCULPT_TOOL_POSE);
6015
6016 PBVHVertexIter vd;
6017 PBVHProxyNode *proxies;
6018 int proxy_count;
6019 float(*orco)[3] = NULL;
6020
6021 if (use_orco && !ss->bm) {
6022 orco = SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_COORDS)->co;
6023 }
6024
6025 BKE_pbvh_node_get_proxies(data->nodes[n], &proxies, &proxy_count);
6026
6027 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
6028 {
6029 float val[3];
6030
6031 if (use_orco) {
6032 if (ss->bm) {
6033 copy_v3_v3(val, BM_log_original_vert_co(ss->bm_log, vd.bm_vert));
6034 }
6035 else {
6036 copy_v3_v3(val, orco[vd.i]);
6037 }
6038 }
6039 else {
6040 copy_v3_v3(val, vd.co);
6041 }
6042
6043 for (int p = 0; p < proxy_count; p++) {
6044 add_v3_v3(val, proxies[p].co[vd.i]);
6045 }
6046
6047 SCULPT_clip(sd, ss, vd.co, val);
6048
6049 if (ss->deform_modifiers_active) {
6050 sculpt_flush_pbvhvert_deform(ob, &vd);
6051 }
6052 }
6053 BKE_pbvh_vertex_iter_end;
6054
6055 BKE_pbvh_node_free_proxies(data->nodes[n]);
6056 }
6057
sculpt_combine_proxies(Sculpt * sd,Object * ob)6058 static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
6059 {
6060 SculptSession *ss = ob->sculpt;
6061 Brush *brush = BKE_paint_brush(&sd->paint);
6062 PBVHNode **nodes;
6063 int totnode;
6064
6065 BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
6066
6067 /* First line is tools that don't support proxies. */
6068 if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
6069 SculptThreadedTaskData data = {
6070 .sd = sd,
6071 .ob = ob,
6072 .brush = brush,
6073 .nodes = nodes,
6074 };
6075
6076 TaskParallelSettings settings;
6077 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
6078 BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
6079 }
6080
6081 MEM_SAFE_FREE(nodes);
6082 }
6083
6084 /**
6085 * Copy the modified vertices from the #PBVH to the active key.
6086 */
sculpt_update_keyblock(Object * ob)6087 static void sculpt_update_keyblock(Object *ob)
6088 {
6089 SculptSession *ss = ob->sculpt;
6090 float(*vertCos)[3];
6091
6092 /* Key-block update happens after handling deformation caused by modifiers,
6093 * so ss->orig_cos would be updated with new stroke. */
6094 if (ss->orig_cos) {
6095 vertCos = ss->orig_cos;
6096 }
6097 else {
6098 vertCos = BKE_pbvh_vert_coords_alloc(ss->pbvh);
6099 }
6100
6101 if (vertCos) {
6102 SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
6103
6104 if (vertCos != ss->orig_cos) {
6105 MEM_freeN(vertCos);
6106 }
6107 }
6108 }
6109
SCULPT_flush_stroke_deform_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))6110 static void SCULPT_flush_stroke_deform_task_cb(void *__restrict userdata,
6111 const int n,
6112 const TaskParallelTLS *__restrict UNUSED(tls))
6113 {
6114 SculptThreadedTaskData *data = userdata;
6115 SculptSession *ss = data->ob->sculpt;
6116 Object *ob = data->ob;
6117 float(*vertCos)[3] = data->vertCos;
6118
6119 PBVHVertexIter vd;
6120
6121 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
6122 {
6123 sculpt_flush_pbvhvert_deform(ob, &vd);
6124
6125 if (vertCos) {
6126 int index = vd.vert_indices[vd.i];
6127 copy_v3_v3(vertCos[index], ss->orig_cos[index]);
6128 }
6129 }
6130 BKE_pbvh_vertex_iter_end;
6131 }
6132
6133 /* Flush displacement from deformed PBVH to original layer. */
SCULPT_flush_stroke_deform(Sculpt * sd,Object * ob,bool is_proxy_used)6134 void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
6135 {
6136 SculptSession *ss = ob->sculpt;
6137 Brush *brush = BKE_paint_brush(&sd->paint);
6138
6139 if (is_proxy_used && ss->deform_modifiers_active) {
6140 /* This brushes aren't using proxies, so sculpt_combine_proxies() wouldn't propagate needed
6141 * deformation to original base. */
6142
6143 int totnode;
6144 Mesh *me = (Mesh *)ob->data;
6145 PBVHNode **nodes;
6146 float(*vertCos)[3] = NULL;
6147
6148 if (ss->shapekey_active) {
6149 vertCos = MEM_mallocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts");
6150
6151 /* Mesh could have isolated verts which wouldn't be in BVH, to deal with this we copy old
6152 * coordinates over new ones and then update coordinates for all vertices from BVH. */
6153 memcpy(vertCos, ss->orig_cos, sizeof(*vertCos) * me->totvert);
6154 }
6155
6156 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
6157
6158 SculptThreadedTaskData data = {
6159 .sd = sd,
6160 .ob = ob,
6161 .brush = brush,
6162 .nodes = nodes,
6163 .vertCos = vertCos,
6164 };
6165
6166 TaskParallelSettings settings;
6167 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
6168 BLI_task_parallel_range(0, totnode, &data, SCULPT_flush_stroke_deform_task_cb, &settings);
6169
6170 if (vertCos) {
6171 SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
6172 MEM_freeN(vertCos);
6173 }
6174
6175 MEM_SAFE_FREE(nodes);
6176
6177 /* Modifiers could depend on mesh normals, so we should update them.
6178 * Note, then if sculpting happens on locked key, normals should be re-calculate after applying
6179 * coords from key-block on base mesh. */
6180 BKE_mesh_calc_normals(me);
6181 }
6182 else if (ss->shapekey_active) {
6183 sculpt_update_keyblock(ob);
6184 }
6185 }
6186
6187 /**
6188 * Flip all the edit-data across the axis/axes specified by \a symm.
6189 * Used to calculate multiple modifications to the mesh when symmetry is enabled.
6190 */
SCULPT_cache_calc_brushdata_symm(StrokeCache * cache,const char symm,const char axis,const float angle)6191 void SCULPT_cache_calc_brushdata_symm(StrokeCache *cache,
6192 const char symm,
6193 const char axis,
6194 const float angle)
6195 {
6196 flip_v3_v3(cache->location, cache->true_location, symm);
6197 flip_v3_v3(cache->last_location, cache->true_last_location, symm);
6198 flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
6199 flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
6200
6201 flip_v3_v3(cache->initial_location, cache->true_initial_location, symm);
6202 flip_v3_v3(cache->initial_normal, cache->true_initial_normal, symm);
6203
6204 /* XXX This reduces the length of the grab delta if it approaches the line of symmetry
6205 * XXX However, a different approach appears to be needed. */
6206 #if 0
6207 if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
6208 float frac = 1.0f / max_overlap_count(sd);
6209 float reduce = (feather - frac) / (1.0f - frac);
6210
6211 printf("feather: %f frac: %f reduce: %f\n", feather, frac, reduce);
6212
6213 if (frac < 1.0f) {
6214 mul_v3_fl(cache->grab_delta_symmetry, reduce);
6215 }
6216 }
6217 #endif
6218
6219 unit_m4(cache->symm_rot_mat);
6220 unit_m4(cache->symm_rot_mat_inv);
6221 zero_v3(cache->plane_offset);
6222
6223 /* Expects XYZ. */
6224 if (axis) {
6225 rotate_m4(cache->symm_rot_mat, axis, angle);
6226 rotate_m4(cache->symm_rot_mat_inv, axis, -angle);
6227 }
6228
6229 mul_m4_v3(cache->symm_rot_mat, cache->location);
6230 mul_m4_v3(cache->symm_rot_mat, cache->grab_delta_symmetry);
6231
6232 if (cache->supports_gravity) {
6233 flip_v3_v3(cache->gravity_direction, cache->true_gravity_direction, symm);
6234 mul_m4_v3(cache->symm_rot_mat, cache->gravity_direction);
6235 }
6236
6237 if (cache->is_rake_rotation_valid) {
6238 flip_qt_qt(cache->rake_rotation_symmetry, cache->rake_rotation, symm);
6239 }
6240 }
6241
6242 typedef void (*BrushActionFunc)(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups);
6243
do_tiled(Sculpt * sd,Object * ob,Brush * brush,UnifiedPaintSettings * ups,BrushActionFunc action)6244 static void do_tiled(
6245 Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups, BrushActionFunc action)
6246 {
6247 SculptSession *ss = ob->sculpt;
6248 StrokeCache *cache = ss->cache;
6249 const float radius = cache->radius;
6250 BoundBox *bb = BKE_object_boundbox_get(ob);
6251 const float *bbMin = bb->vec[0];
6252 const float *bbMax = bb->vec[6];
6253 const float *step = sd->paint.tile_offset;
6254
6255 /* These are integer locations, for real location: multiply with step and add orgLoc.
6256 * So 0,0,0 is at orgLoc. */
6257 int start[3];
6258 int end[3];
6259 int cur[3];
6260
6261 /* Position of the "prototype" stroke for tiling. */
6262 float orgLoc[3];
6263 float original_initial_location[3];
6264 copy_v3_v3(orgLoc, cache->location);
6265 copy_v3_v3(original_initial_location, cache->initial_location);
6266
6267 for (int dim = 0; dim < 3; dim++) {
6268 if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
6269 start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
6270 end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
6271 }
6272 else {
6273 start[dim] = end[dim] = 0;
6274 }
6275 }
6276
6277 /* First do the "untiled" position to initialize the stroke for this location. */
6278 cache->tile_pass = 0;
6279 action(sd, ob, brush, ups);
6280
6281 /* Now do it for all the tiles. */
6282 copy_v3_v3_int(cur, start);
6283 for (cur[0] = start[0]; cur[0] <= end[0]; cur[0]++) {
6284 for (cur[1] = start[1]; cur[1] <= end[1]; cur[1]++) {
6285 for (cur[2] = start[2]; cur[2] <= end[2]; cur[2]++) {
6286 if (!cur[0] && !cur[1] && !cur[2]) {
6287 /* Skip tile at orgLoc, this was already handled before all others. */
6288 continue;
6289 }
6290
6291 ++cache->tile_pass;
6292
6293 for (int dim = 0; dim < 3; dim++) {
6294 cache->location[dim] = cur[dim] * step[dim] + orgLoc[dim];
6295 cache->plane_offset[dim] = cur[dim] * step[dim];
6296 cache->initial_location[dim] = cur[dim] * step[dim] + original_initial_location[dim];
6297 }
6298 action(sd, ob, brush, ups);
6299 }
6300 }
6301 }
6302 }
6303
do_radial_symmetry(Sculpt * sd,Object * ob,Brush * brush,UnifiedPaintSettings * ups,BrushActionFunc action,const char symm,const int axis,const float UNUSED (feather))6304 static void do_radial_symmetry(Sculpt *sd,
6305 Object *ob,
6306 Brush *brush,
6307 UnifiedPaintSettings *ups,
6308 BrushActionFunc action,
6309 const char symm,
6310 const int axis,
6311 const float UNUSED(feather))
6312 {
6313 SculptSession *ss = ob->sculpt;
6314
6315 for (int i = 1; i < sd->radial_symm[axis - 'X']; i++) {
6316 const float angle = 2.0f * M_PI * i / sd->radial_symm[axis - 'X'];
6317 ss->cache->radial_symmetry_pass = i;
6318 SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
6319 do_tiled(sd, ob, brush, ups, action);
6320 }
6321 }
6322
6323 /**
6324 * Noise texture gives different values for the same input coord; this
6325 * can tear a multi-resolution mesh during sculpting so do a stitch in this case.
6326 */
sculpt_fix_noise_tear(Sculpt * sd,Object * ob)6327 static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
6328 {
6329 SculptSession *ss = ob->sculpt;
6330 Brush *brush = BKE_paint_brush(&sd->paint);
6331 MTex *mtex = &brush->mtex;
6332
6333 if (ss->multires.active && mtex->tex && mtex->tex->type == TEX_NOISE) {
6334 multires_stitch_grids(ob);
6335 }
6336 }
6337
do_symmetrical_brush_actions(Sculpt * sd,Object * ob,BrushActionFunc action,UnifiedPaintSettings * ups)6338 static void do_symmetrical_brush_actions(Sculpt *sd,
6339 Object *ob,
6340 BrushActionFunc action,
6341 UnifiedPaintSettings *ups)
6342 {
6343 Brush *brush = BKE_paint_brush(&sd->paint);
6344 SculptSession *ss = ob->sculpt;
6345 StrokeCache *cache = ss->cache;
6346 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
6347
6348 float feather = calc_symmetry_feather(sd, ss->cache);
6349
6350 cache->bstrength = brush_strength(sd, cache, feather, ups);
6351 cache->symmetry = symm;
6352
6353 /* `symm` is a bit combination of XYZ -
6354 * 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
6355 for (int i = 0; i <= symm; i++) {
6356 if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
6357 cache->mirror_symmetry_pass = i;
6358 cache->radial_symmetry_pass = 0;
6359
6360 SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0);
6361 do_tiled(sd, ob, brush, ups, action);
6362
6363 do_radial_symmetry(sd, ob, brush, ups, action, i, 'X', feather);
6364 do_radial_symmetry(sd, ob, brush, ups, action, i, 'Y', feather);
6365 do_radial_symmetry(sd, ob, brush, ups, action, i, 'Z', feather);
6366 }
6367 }
6368 }
6369
sculpt_update_tex(const Scene * scene,Sculpt * sd,SculptSession * ss)6370 static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
6371 {
6372 Brush *brush = BKE_paint_brush(&sd->paint);
6373 const int radius = BKE_brush_size_get(scene, brush);
6374
6375 if (ss->texcache) {
6376 MEM_freeN(ss->texcache);
6377 ss->texcache = NULL;
6378 }
6379
6380 if (ss->tex_pool) {
6381 BKE_image_pool_free(ss->tex_pool);
6382 ss->tex_pool = NULL;
6383 }
6384
6385 /* Need to allocate a bigger buffer for bigger brush size. */
6386 ss->texcache_side = 2 * radius;
6387 if (!ss->texcache || ss->texcache_side > ss->texcache_actual) {
6388 ss->texcache = BKE_brush_gen_texture_cache(brush, radius, false);
6389 ss->texcache_actual = ss->texcache_side;
6390 ss->tex_pool = BKE_image_pool_new();
6391 }
6392 }
6393
SCULPT_mode_poll(bContext * C)6394 bool SCULPT_mode_poll(bContext *C)
6395 {
6396 Object *ob = CTX_data_active_object(C);
6397 return ob && ob->mode & OB_MODE_SCULPT;
6398 }
6399
SCULPT_vertex_colors_poll(bContext * C)6400 bool SCULPT_vertex_colors_poll(bContext *C)
6401 {
6402 if (!U.experimental.use_sculpt_vertex_colors) {
6403 return false;
6404 }
6405 return SCULPT_mode_poll(C);
6406 }
6407
SCULPT_mode_poll_view3d(bContext * C)6408 bool SCULPT_mode_poll_view3d(bContext *C)
6409 {
6410 return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C));
6411 }
6412
SCULPT_poll_view3d(bContext * C)6413 bool SCULPT_poll_view3d(bContext *C)
6414 {
6415 return (SCULPT_poll(C) && CTX_wm_region_view3d(C));
6416 }
6417
SCULPT_poll(bContext * C)6418 bool SCULPT_poll(bContext *C)
6419 {
6420 return SCULPT_mode_poll(C) && paint_poll(C);
6421 }
6422
sculpt_tool_name(Sculpt * sd)6423 static const char *sculpt_tool_name(Sculpt *sd)
6424 {
6425 Brush *brush = BKE_paint_brush(&sd->paint);
6426
6427 switch ((eBrushSculptTool)brush->sculpt_tool) {
6428 case SCULPT_TOOL_DRAW:
6429 return "Draw Brush";
6430 case SCULPT_TOOL_SMOOTH:
6431 return "Smooth Brush";
6432 case SCULPT_TOOL_CREASE:
6433 return "Crease Brush";
6434 case SCULPT_TOOL_BLOB:
6435 return "Blob Brush";
6436 case SCULPT_TOOL_PINCH:
6437 return "Pinch Brush";
6438 case SCULPT_TOOL_INFLATE:
6439 return "Inflate Brush";
6440 case SCULPT_TOOL_GRAB:
6441 return "Grab Brush";
6442 case SCULPT_TOOL_NUDGE:
6443 return "Nudge Brush";
6444 case SCULPT_TOOL_THUMB:
6445 return "Thumb Brush";
6446 case SCULPT_TOOL_LAYER:
6447 return "Layer Brush";
6448 case SCULPT_TOOL_FLATTEN:
6449 return "Flatten Brush";
6450 case SCULPT_TOOL_CLAY:
6451 return "Clay Brush";
6452 case SCULPT_TOOL_CLAY_STRIPS:
6453 return "Clay Strips Brush";
6454 case SCULPT_TOOL_CLAY_THUMB:
6455 return "Clay Thumb Brush";
6456 case SCULPT_TOOL_FILL:
6457 return "Fill Brush";
6458 case SCULPT_TOOL_SCRAPE:
6459 return "Scrape Brush";
6460 case SCULPT_TOOL_SNAKE_HOOK:
6461 return "Snake Hook Brush";
6462 case SCULPT_TOOL_ROTATE:
6463 return "Rotate Brush";
6464 case SCULPT_TOOL_MASK:
6465 return "Mask Brush";
6466 case SCULPT_TOOL_SIMPLIFY:
6467 return "Simplify Brush";
6468 case SCULPT_TOOL_DRAW_SHARP:
6469 return "Draw Sharp Brush";
6470 case SCULPT_TOOL_ELASTIC_DEFORM:
6471 return "Elastic Deform Brush";
6472 case SCULPT_TOOL_POSE:
6473 return "Pose Brush";
6474 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
6475 return "Multi-plane Scrape Brush";
6476 case SCULPT_TOOL_SLIDE_RELAX:
6477 return "Slide/Relax Brush";
6478 case SCULPT_TOOL_BOUNDARY:
6479 return "Boundary Brush";
6480 case SCULPT_TOOL_CLOTH:
6481 return "Cloth Brush";
6482 case SCULPT_TOOL_DRAW_FACE_SETS:
6483 return "Draw Face Sets";
6484 case SCULPT_TOOL_DISPLACEMENT_ERASER:
6485 return "Multires Displacement Eraser";
6486 case SCULPT_TOOL_PAINT:
6487 return "Paint Brush";
6488 case SCULPT_TOOL_SMEAR:
6489 return "Smear Brush";
6490 }
6491
6492 return "Sculpting";
6493 }
6494
6495 /**
6496 * Operator for applying a stroke (various attributes including mouse path)
6497 * using the current brush. */
6498
SCULPT_cache_free(StrokeCache * cache)6499 void SCULPT_cache_free(StrokeCache *cache)
6500 {
6501 MEM_SAFE_FREE(cache->dial);
6502 MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
6503 MEM_SAFE_FREE(cache->layer_displacement_factor);
6504 MEM_SAFE_FREE(cache->prev_colors);
6505 MEM_SAFE_FREE(cache->detail_directions);
6506
6507 if (cache->pose_ik_chain) {
6508 SCULPT_pose_ik_chain_free(cache->pose_ik_chain);
6509 }
6510
6511 for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
6512 if (cache->boundaries[i]) {
6513 SCULPT_boundary_data_free(cache->boundaries[i]);
6514 }
6515 }
6516
6517 if (cache->cloth_sim) {
6518 SCULPT_cloth_simulation_free(cache->cloth_sim);
6519 }
6520
6521 MEM_freeN(cache);
6522 }
6523
6524 /* Initialize mirror modifier clipping. */
sculpt_init_mirror_clipping(Object * ob,SculptSession * ss)6525 static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
6526 {
6527 ModifierData *md;
6528
6529 for (md = ob->modifiers.first; md; md = md->next) {
6530 if (md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) {
6531 MirrorModifierData *mmd = (MirrorModifierData *)md;
6532
6533 if (mmd->flag & MOD_MIR_CLIPPING) {
6534 /* Check each axis for mirroring. */
6535 for (int i = 0; i < 3; i++) {
6536 if (mmd->flag & (MOD_MIR_AXIS_X << i)) {
6537 /* Enable sculpt clipping. */
6538 ss->cache->flag |= CLIP_X << i;
6539
6540 /* Update the clip tolerance. */
6541 if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
6542 ss->cache->clip_tolerance[i] = mmd->tolerance;
6543 }
6544 }
6545 }
6546 }
6547 }
6548 }
6549 }
6550
6551 /* Initialize the stroke cache invariants from operator properties. */
sculpt_update_cache_invariants(bContext * C,Sculpt * sd,SculptSession * ss,wmOperator * op,const float mouse[2])6552 static void sculpt_update_cache_invariants(
6553 bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mouse[2])
6554 {
6555 StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
6556 Main *bmain = CTX_data_main(C);
6557 Scene *scene = CTX_data_scene(C);
6558 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
6559 Brush *brush = BKE_paint_brush(&sd->paint);
6560 ViewContext *vc = paint_stroke_view_context(op->customdata);
6561 Object *ob = CTX_data_active_object(C);
6562 float mat[3][3];
6563 float viewDir[3] = {0.0f, 0.0f, 1.0f};
6564 float max_scale;
6565 int mode;
6566
6567 ss->cache = cache;
6568
6569 /* Set scaling adjustment. */
6570 max_scale = 0.0f;
6571 for (int i = 0; i < 3; i++) {
6572 max_scale = max_ff(max_scale, fabsf(ob->scale[i]));
6573 }
6574 cache->scale[0] = max_scale / ob->scale[0];
6575 cache->scale[1] = max_scale / ob->scale[1];
6576 cache->scale[2] = max_scale / ob->scale[2];
6577
6578 cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
6579
6580 cache->flag = 0;
6581
6582 sculpt_init_mirror_clipping(ob, ss);
6583
6584 /* Initial mouse location. */
6585 if (mouse) {
6586 copy_v2_v2(cache->initial_mouse, mouse);
6587 }
6588 else {
6589 zero_v2(cache->initial_mouse);
6590 }
6591
6592 copy_v3_v3(cache->initial_location, ss->cursor_location);
6593 copy_v3_v3(cache->true_initial_location, ss->cursor_location);
6594
6595 copy_v3_v3(cache->initial_normal, ss->cursor_normal);
6596 copy_v3_v3(cache->true_initial_normal, ss->cursor_normal);
6597
6598 mode = RNA_enum_get(op->ptr, "mode");
6599 cache->invert = mode == BRUSH_STROKE_INVERT;
6600 cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH;
6601 cache->normal_weight = brush->normal_weight;
6602
6603 /* Interpret invert as following normal, for grab brushes. */
6604 if (SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool)) {
6605 if (cache->invert) {
6606 cache->invert = false;
6607 cache->normal_weight = (cache->normal_weight == 0.0f);
6608 }
6609 }
6610
6611 /* Not very nice, but with current events system implementation
6612 * we can't handle brush appearance inversion hotkey separately (sergey). */
6613 if (cache->invert) {
6614 ups->draw_inverted = true;
6615 }
6616 else {
6617 ups->draw_inverted = false;
6618 }
6619
6620 /* Alt-Smooth. */
6621 if (cache->alt_smooth) {
6622 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
6623 cache->saved_mask_brush_tool = brush->mask_tool;
6624 brush->mask_tool = BRUSH_MASK_SMOOTH;
6625 }
6626 else if (ELEM(brush->sculpt_tool,
6627 SCULPT_TOOL_SLIDE_RELAX,
6628 SCULPT_TOOL_DRAW_FACE_SETS,
6629 SCULPT_TOOL_PAINT,
6630 SCULPT_TOOL_SMEAR)) {
6631 /* Do nothing, this tool has its own smooth mode. */
6632 }
6633 else {
6634 Paint *p = &sd->paint;
6635 Brush *br;
6636 int size = BKE_brush_size_get(scene, brush);
6637
6638 BLI_strncpy(cache->saved_active_brush_name,
6639 brush->id.name + 2,
6640 sizeof(cache->saved_active_brush_name));
6641
6642 br = (Brush *)BKE_libblock_find_name(bmain, ID_BR, "Smooth");
6643 if (br) {
6644 BKE_paint_brush_set(p, br);
6645 brush = br;
6646 cache->saved_smooth_size = BKE_brush_size_get(scene, brush);
6647 BKE_brush_size_set(scene, brush, size);
6648 BKE_curvemapping_init(brush->curve);
6649 }
6650 }
6651 }
6652
6653 copy_v2_v2(cache->mouse, cache->initial_mouse);
6654 copy_v2_v2(cache->mouse_event, cache->initial_mouse);
6655 copy_v2_v2(ups->tex_mouse, cache->initial_mouse);
6656
6657 /* Truly temporary data that isn't stored in properties. */
6658
6659 cache->vc = vc;
6660
6661 cache->brush = brush;
6662
6663 /* Cache projection matrix. */
6664 ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
6665
6666 invert_m4_m4(ob->imat, ob->obmat);
6667 copy_m3_m4(mat, cache->vc->rv3d->viewinv);
6668 mul_m3_v3(mat, viewDir);
6669 copy_m3_m4(mat, ob->imat);
6670 mul_m3_v3(mat, viewDir);
6671 normalize_v3_v3(cache->true_view_normal, viewDir);
6672
6673 cache->supports_gravity = (!ELEM(brush->sculpt_tool,
6674 SCULPT_TOOL_MASK,
6675 SCULPT_TOOL_SMOOTH,
6676 SCULPT_TOOL_SIMPLIFY,
6677 SCULPT_TOOL_DISPLACEMENT_ERASER) &&
6678 (sd->gravity_factor > 0.0f));
6679 /* Get gravity vector in world space. */
6680 if (cache->supports_gravity) {
6681 if (sd->gravity_object) {
6682 Object *gravity_object = sd->gravity_object;
6683
6684 copy_v3_v3(cache->true_gravity_direction, gravity_object->obmat[2]);
6685 }
6686 else {
6687 cache->true_gravity_direction[0] = cache->true_gravity_direction[1] = 0.0f;
6688 cache->true_gravity_direction[2] = 1.0f;
6689 }
6690
6691 /* Transform to sculpted object space. */
6692 mul_m3_v3(mat, cache->true_gravity_direction);
6693 normalize_v3(cache->true_gravity_direction);
6694 }
6695
6696 /* Make copies of the mesh vertex locations and normals for some tools. */
6697 if (brush->flag & BRUSH_ANCHORED) {
6698 cache->original = true;
6699 }
6700
6701 /* Draw sharp does not need the original coordinates to produce the accumulate effect, so it
6702 * should work the opposite way. */
6703 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_SHARP) {
6704 cache->original = true;
6705 }
6706
6707 if (SCULPT_TOOL_HAS_ACCUMULATE(brush->sculpt_tool)) {
6708 if (!(brush->flag & BRUSH_ACCUMULATE)) {
6709 cache->original = true;
6710 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_SHARP) {
6711 cache->original = false;
6712 }
6713 }
6714 }
6715
6716 cache->first_time = true;
6717
6718 #define PIXEL_INPUT_THRESHHOLD 5
6719 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
6720 cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
6721 }
6722
6723 #undef PIXEL_INPUT_THRESHHOLD
6724 }
6725
sculpt_brush_dynamic_size_get(Brush * brush,StrokeCache * cache,float initial_size)6726 static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, float initial_size)
6727 {
6728 switch (brush->sculpt_tool) {
6729 case SCULPT_TOOL_CLAY:
6730 return max_ff(initial_size * 0.20f, initial_size * pow3f(cache->pressure));
6731 case SCULPT_TOOL_CLAY_STRIPS:
6732 return max_ff(initial_size * 0.30f, initial_size * powf(cache->pressure, 1.5f));
6733 case SCULPT_TOOL_CLAY_THUMB: {
6734 float clay_stabilized_pressure = sculpt_clay_thumb_get_stabilized_pressure(cache);
6735 return initial_size * clay_stabilized_pressure;
6736 }
6737 default:
6738 return initial_size * cache->pressure;
6739 }
6740 }
6741
6742 /* In these brushes the grab delta is calculated always from the initial stroke location, which is
6743 * generally used to create grab deformations. */
sculpt_needs_delta_from_anchored_origin(Brush * brush)6744 static bool sculpt_needs_delta_from_anchored_origin(Brush *brush)
6745 {
6746 if (ELEM(brush->sculpt_tool,
6747 SCULPT_TOOL_GRAB,
6748 SCULPT_TOOL_POSE,
6749 SCULPT_TOOL_BOUNDARY,
6750 SCULPT_TOOL_THUMB,
6751 SCULPT_TOOL_ELASTIC_DEFORM)) {
6752 return true;
6753 }
6754 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
6755 brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
6756 return true;
6757 }
6758 return false;
6759 }
6760
6761 /* In these brushes the grab delta is calculated from the previous stroke location, which is used
6762 * to calculate to orientate the brush tip and deformation towards the stroke direction. */
sculpt_needs_delta_for_tip_orientation(Brush * brush)6763 static bool sculpt_needs_delta_for_tip_orientation(Brush *brush)
6764 {
6765 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
6766 return brush->cloth_deform_type != BRUSH_CLOTH_DEFORM_GRAB;
6767 }
6768 return ELEM(brush->sculpt_tool,
6769 SCULPT_TOOL_CLAY_STRIPS,
6770 SCULPT_TOOL_PINCH,
6771 SCULPT_TOOL_MULTIPLANE_SCRAPE,
6772 SCULPT_TOOL_CLAY_THUMB,
6773 SCULPT_TOOL_NUDGE,
6774 SCULPT_TOOL_SNAKE_HOOK);
6775 }
6776
sculpt_update_brush_delta(UnifiedPaintSettings * ups,Object * ob,Brush * brush)6777 static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Brush *brush)
6778 {
6779 SculptSession *ss = ob->sculpt;
6780 StrokeCache *cache = ss->cache;
6781 const float mouse[2] = {
6782 cache->mouse_event[0],
6783 cache->mouse_event[1],
6784 };
6785 int tool = brush->sculpt_tool;
6786
6787 if (ELEM(tool,
6788 SCULPT_TOOL_PAINT,
6789 SCULPT_TOOL_GRAB,
6790 SCULPT_TOOL_ELASTIC_DEFORM,
6791 SCULPT_TOOL_CLOTH,
6792 SCULPT_TOOL_NUDGE,
6793 SCULPT_TOOL_CLAY_STRIPS,
6794 SCULPT_TOOL_PINCH,
6795 SCULPT_TOOL_MULTIPLANE_SCRAPE,
6796 SCULPT_TOOL_CLAY_THUMB,
6797 SCULPT_TOOL_SNAKE_HOOK,
6798 SCULPT_TOOL_POSE,
6799 SCULPT_TOOL_BOUNDARY,
6800 SCULPT_TOOL_THUMB) ||
6801 sculpt_brush_use_topology_rake(ss, brush)) {
6802 float grab_location[3], imat[4][4], delta[3], loc[3];
6803
6804 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
6805 if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
6806 copy_v3_v3(cache->orig_grab_location,
6807 SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
6808 }
6809 else {
6810 copy_v3_v3(cache->orig_grab_location, cache->true_location);
6811 }
6812 }
6813 else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
6814 (tool == SCULPT_TOOL_CLOTH &&
6815 brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) {
6816 add_v3_v3(cache->true_location, cache->grab_delta);
6817 }
6818
6819 /* Compute 3d coordinate at same z from original location + mouse. */
6820 mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
6821 ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
6822
6823 /* Compute delta to move verts by. */
6824 if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
6825 if (sculpt_needs_delta_from_anchored_origin(brush)) {
6826 sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
6827 invert_m4_m4(imat, ob->obmat);
6828 mul_mat3_m4_v3(imat, delta);
6829 add_v3_v3(cache->grab_delta, delta);
6830 }
6831 else if (sculpt_needs_delta_for_tip_orientation(brush)) {
6832 if (brush->flag & BRUSH_ANCHORED) {
6833 float orig[3];
6834 mul_v3_m4v3(orig, ob->obmat, cache->orig_grab_location);
6835 sub_v3_v3v3(cache->grab_delta, grab_location, orig);
6836 }
6837 else {
6838 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
6839 }
6840 invert_m4_m4(imat, ob->obmat);
6841 mul_mat3_m4_v3(imat, cache->grab_delta);
6842 }
6843 else {
6844 /* Use for 'Brush.topology_rake_factor'. */
6845 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
6846 }
6847 }
6848 else {
6849 zero_v3(cache->grab_delta);
6850 }
6851
6852 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
6853 project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
6854 }
6855
6856 copy_v3_v3(cache->old_grab_location, grab_location);
6857
6858 if (tool == SCULPT_TOOL_GRAB) {
6859 if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
6860 copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
6861 }
6862 else {
6863 copy_v3_v3(cache->anchored_location, cache->true_location);
6864 }
6865 }
6866 else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || SCULPT_is_cloth_deform_brush(brush)) {
6867 copy_v3_v3(cache->anchored_location, cache->true_location);
6868 }
6869 else if (tool == SCULPT_TOOL_THUMB) {
6870 copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
6871 }
6872
6873 if (sculpt_needs_delta_from_anchored_origin(brush)) {
6874 /* Location stays the same for finding vertices in brush radius. */
6875 copy_v3_v3(cache->true_location, cache->orig_grab_location);
6876
6877 ups->draw_anchored = true;
6878 copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
6879 ups->anchored_size = ups->pixel_radius;
6880 }
6881
6882 /* Handle 'rake' */
6883 cache->is_rake_rotation_valid = false;
6884
6885 invert_m4_m4(imat, ob->obmat);
6886 mul_mat3_m4_v3(imat, grab_location);
6887
6888 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
6889 copy_v3_v3(cache->rake_data.follow_co, grab_location);
6890 }
6891
6892 if (sculpt_brush_needs_rake_rotation(brush)) {
6893 cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
6894
6895 if (!is_zero_v3(cache->grab_delta)) {
6896 const float eps = 0.00001f;
6897
6898 float v1[3], v2[3];
6899
6900 copy_v3_v3(v1, cache->rake_data.follow_co);
6901 copy_v3_v3(v2, cache->rake_data.follow_co);
6902 sub_v3_v3(v2, cache->grab_delta);
6903
6904 sub_v3_v3(v1, grab_location);
6905 sub_v3_v3(v2, grab_location);
6906
6907 if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) &&
6908 (len_squared_v3v3(v1, v2) > eps)) {
6909 const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
6910 const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
6911 1.0f :
6912 sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
6913
6914 float axis[3], angle;
6915 float tquat[4];
6916
6917 rotation_between_vecs_to_quat(tquat, v1, v2);
6918
6919 /* Use axis-angle to scale rotation since the factor may be above 1. */
6920 quat_to_axis_angle(axis, &angle, tquat);
6921 normalize_v3(axis);
6922
6923 angle *= brush->rake_factor * rake_fade;
6924 axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
6925 cache->is_rake_rotation_valid = true;
6926 }
6927 }
6928 sculpt_rake_data_update(&cache->rake_data, grab_location);
6929 }
6930 }
6931 }
6932
sculpt_update_cache_paint_variants(StrokeCache * cache,const Brush * brush)6933 static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
6934 {
6935 cache->paint_brush.hardness = brush->hardness;
6936 if (brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE) {
6937 cache->paint_brush.hardness *= brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE_INVERT ?
6938 1.0f - cache->pressure :
6939 cache->pressure;
6940 }
6941
6942 cache->paint_brush.flow = brush->flow;
6943 if (brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE) {
6944 cache->paint_brush.flow *= brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE_INVERT ?
6945 1.0f - cache->pressure :
6946 cache->pressure;
6947 }
6948
6949 cache->paint_brush.wet_mix = brush->wet_mix;
6950 if (brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE) {
6951 cache->paint_brush.wet_mix *= brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE_INVERT ?
6952 1.0f - cache->pressure :
6953 cache->pressure;
6954
6955 /* This makes wet mix more sensible in higher values, which allows to create brushes that have
6956 * a wider pressure range were they only blend colors without applying too much of the brush
6957 * color. */
6958 cache->paint_brush.wet_mix = 1.0f - pow2f(1.0f - cache->paint_brush.wet_mix);
6959 }
6960
6961 cache->paint_brush.wet_persistence = brush->wet_persistence;
6962 if (brush->paint_flags & BRUSH_PAINT_WET_PERSISTENCE_PRESSURE) {
6963 cache->paint_brush.wet_persistence = brush->paint_flags &
6964 BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT ?
6965 1.0f - cache->pressure :
6966 cache->pressure;
6967 }
6968
6969 cache->paint_brush.density = brush->density;
6970 if (brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE) {
6971 cache->paint_brush.density = brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE_INVERT ?
6972 1.0f - cache->pressure :
6973 cache->pressure;
6974 }
6975 }
6976
6977 /* Initialize the stroke cache variants from operator properties. */
sculpt_update_cache_variants(bContext * C,Sculpt * sd,Object * ob,PointerRNA * ptr)6978 static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr)
6979 {
6980 Scene *scene = CTX_data_scene(C);
6981 UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
6982 SculptSession *ss = ob->sculpt;
6983 StrokeCache *cache = ss->cache;
6984 Brush *brush = BKE_paint_brush(&sd->paint);
6985
6986 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
6987 !((brush->flag & BRUSH_ANCHORED) || (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) ||
6988 (brush->sculpt_tool == SCULPT_TOOL_ROTATE) || SCULPT_is_cloth_deform_brush(brush))) {
6989 RNA_float_get_array(ptr, "location", cache->true_location);
6990 }
6991
6992 cache->pen_flip = RNA_boolean_get(ptr, "pen_flip");
6993 RNA_float_get_array(ptr, "mouse", cache->mouse);
6994 RNA_float_get_array(ptr, "mouse_event", cache->mouse_event);
6995
6996 /* XXX: Use pressure value from first brush step for brushes which don't support strokes (grab,
6997 * thumb). They depends on initial state and brush coord/pressure/etc.
6998 * It's more an events design issue, which doesn't split coordinate/pressure/angle changing
6999 * events. We should avoid this after events system re-design. */
7000 if (paint_supports_dynamic_size(brush, PAINT_MODE_SCULPT) || cache->first_time) {
7001 cache->pressure = RNA_float_get(ptr, "pressure");
7002 }
7003
7004 cache->x_tilt = RNA_float_get(ptr, "x_tilt");
7005 cache->y_tilt = RNA_float_get(ptr, "y_tilt");
7006
7007 /* Truly temporary data that isn't stored in properties. */
7008 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
7009 if (!BKE_brush_use_locked_size(scene, brush)) {
7010 cache->initial_radius = paint_calc_object_space_radius(
7011 cache->vc, cache->true_location, BKE_brush_size_get(scene, brush));
7012 BKE_brush_unprojected_radius_set(scene, brush, cache->initial_radius);
7013 }
7014 else {
7015 cache->initial_radius = BKE_brush_unprojected_radius_get(scene, brush);
7016 }
7017 }
7018
7019 /* Clay stabilized pressure. */
7020 if (brush->sculpt_tool == SCULPT_TOOL_CLAY_THUMB) {
7021 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
7022 for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
7023 ss->cache->clay_pressure_stabilizer[i] = 0.0f;
7024 }
7025 ss->cache->clay_pressure_stabilizer_index = 0;
7026 }
7027 else {
7028 cache->clay_pressure_stabilizer[cache->clay_pressure_stabilizer_index] = cache->pressure;
7029 cache->clay_pressure_stabilizer_index += 1;
7030 if (cache->clay_pressure_stabilizer_index >= SCULPT_CLAY_STABILIZER_LEN) {
7031 cache->clay_pressure_stabilizer_index = 0;
7032 }
7033 }
7034 }
7035
7036 if (BKE_brush_use_size_pressure(brush) &&
7037 paint_supports_dynamic_size(brush, PAINT_MODE_SCULPT)) {
7038 cache->radius = sculpt_brush_dynamic_size_get(brush, cache, cache->initial_radius);
7039 cache->dyntopo_pixel_radius = sculpt_brush_dynamic_size_get(
7040 brush, cache, ups->initial_pixel_radius);
7041 }
7042 else {
7043 cache->radius = cache->initial_radius;
7044 cache->dyntopo_pixel_radius = ups->initial_pixel_radius;
7045 }
7046
7047 sculpt_update_cache_paint_variants(cache, brush);
7048
7049 cache->radius_squared = cache->radius * cache->radius;
7050
7051 if (brush->flag & BRUSH_ANCHORED) {
7052 /* True location has been calculated as part of the stroke system already here. */
7053 if (brush->flag & BRUSH_EDGE_TO_EDGE) {
7054 RNA_float_get_array(ptr, "location", cache->true_location);
7055 }
7056
7057 cache->radius = paint_calc_object_space_radius(
7058 cache->vc, cache->true_location, ups->pixel_radius);
7059 cache->radius_squared = cache->radius * cache->radius;
7060
7061 copy_v3_v3(cache->anchored_location, cache->true_location);
7062 }
7063
7064 sculpt_update_brush_delta(ups, ob, brush);
7065
7066 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
7067 cache->vertex_rotation = -BLI_dial_angle(cache->dial, cache->mouse) * cache->bstrength;
7068
7069 ups->draw_anchored = true;
7070 copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
7071 copy_v3_v3(cache->anchored_location, cache->true_location);
7072 ups->anchored_size = ups->pixel_radius;
7073 }
7074
7075 cache->special_rotation = ups->brush_rotation;
7076
7077 cache->iteration_count++;
7078 }
7079
7080 /* Returns true if any of the smoothing modes are active (currently
7081 * one of smooth brush, autosmooth, mask smooth, or shift-key
7082 * smooth). */
sculpt_needs_connectivity_info(const Sculpt * sd,const Brush * brush,SculptSession * ss,int stroke_mode)7083 static bool sculpt_needs_connectivity_info(const Sculpt *sd,
7084 const Brush *brush,
7085 SculptSession *ss,
7086 int stroke_mode)
7087 {
7088 if (ss && ss->pbvh && SCULPT_is_automasking_enabled(sd, ss, brush)) {
7089 return true;
7090 }
7091 return ((stroke_mode == BRUSH_STROKE_SMOOTH) || (ss && ss->cache && ss->cache->alt_smooth) ||
7092 (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) ||
7093 ((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) ||
7094 (brush->sculpt_tool == SCULPT_TOOL_POSE) ||
7095 (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) ||
7096 (brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
7097 (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
7098 (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS));
7099 }
7100
SCULPT_stroke_modifiers_check(const bContext * C,Object * ob,const Brush * brush)7101 void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush)
7102 {
7103 SculptSession *ss = ob->sculpt;
7104 View3D *v3d = CTX_wm_view3d(C);
7105 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7106
7107 bool need_pmap = sculpt_needs_connectivity_info(sd, brush, ss, 0);
7108 if (ss->shapekey_active || ss->deform_modifiers_active ||
7109 (!BKE_sculptsession_use_pbvh_draw(ob, v3d) && need_pmap)) {
7110 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
7111 BKE_sculpt_update_object_for_edit(depsgraph, ob, need_pmap, false, false);
7112 }
7113 }
7114
sculpt_raycast_cb(PBVHNode * node,void * data_v,float * tmin)7115 static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin)
7116 {
7117 if (BKE_pbvh_node_get_tmin(node) < *tmin) {
7118 SculptRaycastData *srd = data_v;
7119 float(*origco)[3] = NULL;
7120 bool use_origco = false;
7121
7122 if (srd->original && srd->ss->cache) {
7123 if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
7124 use_origco = true;
7125 }
7126 else {
7127 /* Intersect with coordinates from before we started stroke. */
7128 SculptUndoNode *unode = SCULPT_undo_get_node(node);
7129 origco = (unode) ? unode->co : NULL;
7130 use_origco = origco ? true : false;
7131 }
7132 }
7133
7134 if (BKE_pbvh_node_raycast(srd->ss->pbvh,
7135 node,
7136 origco,
7137 use_origco,
7138 srd->ray_start,
7139 srd->ray_normal,
7140 &srd->isect_precalc,
7141 &srd->depth,
7142 &srd->active_vertex_index,
7143 &srd->active_face_grid_index,
7144 srd->face_normal)) {
7145 srd->hit = true;
7146 *tmin = srd->depth;
7147 }
7148 }
7149 }
7150
sculpt_find_nearest_to_ray_cb(PBVHNode * node,void * data_v,float * tmin)7151 static void sculpt_find_nearest_to_ray_cb(PBVHNode *node, void *data_v, float *tmin)
7152 {
7153 if (BKE_pbvh_node_get_tmin(node) < *tmin) {
7154 SculptFindNearestToRayData *srd = data_v;
7155 float(*origco)[3] = NULL;
7156 bool use_origco = false;
7157
7158 if (srd->original && srd->ss->cache) {
7159 if (BKE_pbvh_type(srd->ss->pbvh) == PBVH_BMESH) {
7160 use_origco = true;
7161 }
7162 else {
7163 /* Intersect with coordinates from before we started stroke. */
7164 SculptUndoNode *unode = SCULPT_undo_get_node(node);
7165 origco = (unode) ? unode->co : NULL;
7166 use_origco = origco ? true : false;
7167 }
7168 }
7169
7170 if (BKE_pbvh_node_find_nearest_to_ray(srd->ss->pbvh,
7171 node,
7172 origco,
7173 use_origco,
7174 srd->ray_start,
7175 srd->ray_normal,
7176 &srd->depth,
7177 &srd->dist_sq_to_ray)) {
7178 srd->hit = true;
7179 *tmin = srd->dist_sq_to_ray;
7180 }
7181 }
7182 }
7183
SCULPT_raycast_init(ViewContext * vc,const float mouse[2],float ray_start[3],float ray_end[3],float ray_normal[3],bool original)7184 float SCULPT_raycast_init(ViewContext *vc,
7185 const float mouse[2],
7186 float ray_start[3],
7187 float ray_end[3],
7188 float ray_normal[3],
7189 bool original)
7190 {
7191 float obimat[4][4];
7192 float dist;
7193 Object *ob = vc->obact;
7194 RegionView3D *rv3d = vc->region->regiondata;
7195 View3D *v3d = vc->v3d;
7196
7197 /* TODO: what if the segment is totally clipped? (return == 0). */
7198 ED_view3d_win_to_segment_clipped(
7199 vc->depsgraph, vc->region, vc->v3d, mouse, ray_start, ray_end, true);
7200
7201 invert_m4_m4(obimat, ob->obmat);
7202 mul_m4_v3(obimat, ray_start);
7203 mul_m4_v3(obimat, ray_end);
7204
7205 sub_v3_v3v3(ray_normal, ray_end, ray_start);
7206 dist = normalize_v3(ray_normal);
7207
7208 if ((rv3d->is_persp == false) &&
7209 /* If the ray is clipped, don't adjust its start/end. */
7210 !RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
7211 BKE_pbvh_raycast_project_ray_root(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
7212
7213 /* rRecalculate the normal. */
7214 sub_v3_v3v3(ray_normal, ray_end, ray_start);
7215 dist = normalize_v3(ray_normal);
7216 }
7217
7218 return dist;
7219 }
7220
7221 /* Gets the normal, location and active vertex location of the geometry under the cursor. This also
7222 * updates the active vertex and cursor related data of the SculptSession using the mouse position
7223 */
SCULPT_cursor_geometry_info_update(bContext * C,SculptCursorGeometryInfo * out,const float mouse[2],bool use_sampled_normal)7224 bool SCULPT_cursor_geometry_info_update(bContext *C,
7225 SculptCursorGeometryInfo *out,
7226 const float mouse[2],
7227 bool use_sampled_normal)
7228 {
7229 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
7230 Scene *scene = CTX_data_scene(C);
7231 Sculpt *sd = scene->toolsettings->sculpt;
7232 Object *ob;
7233 SculptSession *ss;
7234 ViewContext vc;
7235 const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
7236 float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3], sampled_normal[3],
7237 mat[3][3];
7238 float viewDir[3] = {0.0f, 0.0f, 1.0f};
7239 int totnode;
7240 bool original = false;
7241
7242 ED_view3d_viewcontext_init(C, &vc, depsgraph);
7243
7244 ob = vc.obact;
7245 ss = ob->sculpt;
7246
7247 if (!ss->pbvh) {
7248 zero_v3(out->location);
7249 zero_v3(out->normal);
7250 zero_v3(out->active_vertex_co);
7251 return false;
7252 }
7253
7254 /* PBVH raycast to get active vertex and face normal. */
7255 depth = SCULPT_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
7256 SCULPT_stroke_modifiers_check(C, ob, brush);
7257
7258 SculptRaycastData srd = {
7259 .original = original,
7260 .ss = ob->sculpt,
7261 .hit = false,
7262 .ray_start = ray_start,
7263 .ray_normal = ray_normal,
7264 .depth = depth,
7265 .face_normal = face_normal,
7266 };
7267 isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
7268 BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
7269
7270 /* Cursor is not over the mesh, return default values. */
7271 if (!srd.hit) {
7272 zero_v3(out->location);
7273 zero_v3(out->normal);
7274 zero_v3(out->active_vertex_co);
7275 return false;
7276 }
7277
7278 /* Update the active vertex of the SculptSession. */
7279 ss->active_vertex_index = srd.active_vertex_index;
7280 SCULPT_vertex_random_access_ensure(ss);
7281 copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss));
7282
7283 switch (BKE_pbvh_type(ss->pbvh)) {
7284 case PBVH_FACES:
7285 ss->active_face_index = srd.active_face_grid_index;
7286 ss->active_grid_index = 0;
7287 break;
7288 case PBVH_GRIDS:
7289 ss->active_face_index = 0;
7290 ss->active_grid_index = srd.active_face_grid_index;
7291 break;
7292 case PBVH_BMESH:
7293 ss->active_face_index = 0;
7294 ss->active_grid_index = 0;
7295 break;
7296 }
7297
7298 copy_v3_v3(out->location, ray_normal);
7299 mul_v3_fl(out->location, srd.depth);
7300 add_v3_v3(out->location, ray_start);
7301
7302 /* Option to return the face normal directly for performance o accuracy reasons. */
7303 if (!use_sampled_normal) {
7304 copy_v3_v3(out->normal, srd.face_normal);
7305 return srd.hit;
7306 }
7307
7308 /* Sampled normal calculation. */
7309 float radius;
7310
7311 /* Update cursor data in SculptSession. */
7312 invert_m4_m4(ob->imat, ob->obmat);
7313 copy_m3_m4(mat, vc.rv3d->viewinv);
7314 mul_m3_v3(mat, viewDir);
7315 copy_m3_m4(mat, ob->imat);
7316 mul_m3_v3(mat, viewDir);
7317 normalize_v3_v3(ss->cursor_view_normal, viewDir);
7318 copy_v3_v3(ss->cursor_normal, srd.face_normal);
7319 copy_v3_v3(ss->cursor_location, out->location);
7320 ss->rv3d = vc.rv3d;
7321 ss->v3d = vc.v3d;
7322
7323 if (!BKE_brush_use_locked_size(scene, brush)) {
7324 radius = paint_calc_object_space_radius(&vc, out->location, BKE_brush_size_get(scene, brush));
7325 }
7326 else {
7327 radius = BKE_brush_unprojected_radius_get(scene, brush);
7328 }
7329 ss->cursor_radius = radius;
7330
7331 PBVHNode **nodes = sculpt_pbvh_gather_cursor_update(ob, sd, original, &totnode);
7332
7333 /* In case there are no nodes under the cursor, return the face normal. */
7334 if (!totnode) {
7335 MEM_SAFE_FREE(nodes);
7336 copy_v3_v3(out->normal, srd.face_normal);
7337 return true;
7338 }
7339
7340 /* Calculate the sampled normal. */
7341 if (SCULPT_pbvh_calc_area_normal(brush, ob, nodes, totnode, true, sampled_normal)) {
7342 copy_v3_v3(out->normal, sampled_normal);
7343 copy_v3_v3(ss->cursor_sampled_normal, sampled_normal);
7344 }
7345 else {
7346 /* Use face normal when there are no vertices to sample inside the cursor radius. */
7347 copy_v3_v3(out->normal, srd.face_normal);
7348 }
7349 MEM_SAFE_FREE(nodes);
7350 return true;
7351 }
7352
7353 /* Do a raycast in the tree to find the 3d brush location
7354 * (This allows us to ignore the GL depth buffer)
7355 * Returns 0 if the ray doesn't hit the mesh, non-zero otherwise. */
SCULPT_stroke_get_location(bContext * C,float out[3],const float mouse[2])7356 bool SCULPT_stroke_get_location(bContext *C, float out[3], const float mouse[2])
7357 {
7358 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
7359 Object *ob;
7360 SculptSession *ss;
7361 StrokeCache *cache;
7362 float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3];
7363 bool original;
7364 ViewContext vc;
7365
7366 ED_view3d_viewcontext_init(C, &vc, depsgraph);
7367
7368 ob = vc.obact;
7369
7370 ss = ob->sculpt;
7371 cache = ss->cache;
7372 original = (cache) ? cache->original : false;
7373
7374 const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
7375
7376 SCULPT_stroke_modifiers_check(C, ob, brush);
7377
7378 depth = SCULPT_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original);
7379
7380 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
7381 BM_mesh_elem_table_ensure(ss->bm, BM_VERT);
7382 BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
7383 }
7384
7385 bool hit = false;
7386 {
7387 SculptRaycastData srd;
7388 srd.ss = ob->sculpt;
7389 srd.ray_start = ray_start;
7390 srd.ray_normal = ray_normal;
7391 srd.hit = false;
7392 srd.depth = depth;
7393 srd.original = original;
7394 srd.face_normal = face_normal;
7395 isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
7396
7397 BKE_pbvh_raycast(ss->pbvh, sculpt_raycast_cb, &srd, ray_start, ray_normal, srd.original);
7398 if (srd.hit) {
7399 hit = true;
7400 copy_v3_v3(out, ray_normal);
7401 mul_v3_fl(out, srd.depth);
7402 add_v3_v3(out, ray_start);
7403 }
7404 }
7405
7406 if (!hit) {
7407 if (ELEM(brush->falloff_shape, PAINT_FALLOFF_SHAPE_TUBE)) {
7408 SculptFindNearestToRayData srd = {
7409 .original = original,
7410 .ss = ob->sculpt,
7411 .hit = false,
7412 .ray_start = ray_start,
7413 .ray_normal = ray_normal,
7414 .depth = FLT_MAX,
7415 .dist_sq_to_ray = FLT_MAX,
7416 };
7417 BKE_pbvh_find_nearest_to_ray(
7418 ss->pbvh, sculpt_find_nearest_to_ray_cb, &srd, ray_start, ray_normal, srd.original);
7419 if (srd.hit) {
7420 hit = true;
7421 copy_v3_v3(out, ray_normal);
7422 mul_v3_fl(out, srd.depth);
7423 add_v3_v3(out, ray_start);
7424 }
7425 }
7426 }
7427
7428 return hit;
7429 }
7430
sculpt_brush_init_tex(const Scene * scene,Sculpt * sd,SculptSession * ss)7431 static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
7432 {
7433 Brush *brush = BKE_paint_brush(&sd->paint);
7434 MTex *mtex = &brush->mtex;
7435
7436 /* Init mtex nodes. */
7437 if (mtex->tex && mtex->tex->nodetree) {
7438 /* Has internal flag to detect it only does it once. */
7439 ntreeTexBeginExecTree(mtex->tex->nodetree);
7440 }
7441
7442 /* TODO: Shouldn't really have to do this at the start of every stroke, but sculpt would need
7443 * some sort of notification when changes are made to the texture. */
7444 sculpt_update_tex(scene, sd, ss);
7445 }
7446
sculpt_brush_stroke_init(bContext * C,wmOperator * op)7447 static void sculpt_brush_stroke_init(bContext *C, wmOperator *op)
7448 {
7449 Scene *scene = CTX_data_scene(C);
7450 Object *ob = CTX_data_active_object(C);
7451 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7452 SculptSession *ss = CTX_data_active_object(C)->sculpt;
7453 Brush *brush = BKE_paint_brush(&sd->paint);
7454 int mode = RNA_enum_get(op->ptr, "mode");
7455 bool is_smooth, needs_colors;
7456 bool need_mask = false;
7457
7458 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
7459 need_mask = true;
7460 }
7461
7462 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH ||
7463 brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
7464 need_mask = true;
7465 }
7466
7467 view3d_operator_needs_opengl(C);
7468 sculpt_brush_init_tex(scene, sd, ss);
7469
7470 is_smooth = sculpt_needs_connectivity_info(sd, brush, ss, mode);
7471 needs_colors = ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR);
7472
7473 if (needs_colors) {
7474 BKE_sculpt_color_layer_create_if_needed(ob);
7475 }
7476
7477 /* CTX_data_ensure_evaluated_depsgraph should be used at the end to include the updates of
7478 * earlier steps modifying the data. */
7479 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
7480 BKE_sculpt_update_object_for_edit(depsgraph, ob, is_smooth, need_mask, needs_colors);
7481 }
7482
sculpt_restore_mesh(Sculpt * sd,Object * ob)7483 static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
7484 {
7485 SculptSession *ss = ob->sculpt;
7486 Brush *brush = BKE_paint_brush(&sd->paint);
7487
7488 /* For the cloth brush it makes more sense to not restore the mesh state to keep running the
7489 * simulation from the previous state. */
7490 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
7491 return;
7492 }
7493
7494 /* Restore the mesh before continuing with anchored stroke. */
7495 if ((brush->flag & BRUSH_ANCHORED) ||
7496 ((brush->sculpt_tool == SCULPT_TOOL_GRAB ||
7497 brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) &&
7498 BKE_brush_use_size_pressure(brush)) ||
7499 (brush->flag & BRUSH_DRAG_DOT)) {
7500
7501 SculptUndoNode *unode = SCULPT_undo_get_first_node();
7502 if (unode && unode->type == SCULPT_UNDO_FACE_SETS) {
7503 for (int i = 0; i < ss->totfaces; i++) {
7504 ss->face_sets[i] = unode->face_sets[i];
7505 }
7506 }
7507
7508 paint_mesh_restore_co(sd, ob);
7509
7510 if (ss->cache) {
7511 MEM_SAFE_FREE(ss->cache->layer_displacement_factor);
7512 }
7513 }
7514 }
7515
7516 /* Copy the PBVH bounding box into the object's bounding box. */
SCULPT_update_object_bounding_box(Object * ob)7517 void SCULPT_update_object_bounding_box(Object *ob)
7518 {
7519 if (ob->runtime.bb) {
7520 float bb_min[3], bb_max[3];
7521
7522 BKE_pbvh_bounding_box(ob->sculpt->pbvh, bb_min, bb_max);
7523 BKE_boundbox_init_from_minmax(ob->runtime.bb, bb_min, bb_max);
7524 }
7525 }
7526
SCULPT_flush_update_step(bContext * C,SculptUpdateType update_flags)7527 void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
7528 {
7529 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
7530 Object *ob = CTX_data_active_object(C);
7531 SculptSession *ss = ob->sculpt;
7532 ARegion *region = CTX_wm_region(C);
7533 MultiresModifierData *mmd = ss->multires.modifier;
7534 View3D *v3d = CTX_wm_view3d(C);
7535 RegionView3D *rv3d = CTX_wm_region_view3d(C);
7536
7537 if (rv3d) {
7538 /* Mark for faster 3D viewport redraws. */
7539 rv3d->rflag |= RV3D_PAINTING;
7540 }
7541
7542 if (mmd != NULL) {
7543 multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
7544 }
7545
7546 DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
7547
7548 /* Only current viewport matters, slower update for all viewports will
7549 * be done in sculpt_flush_update_done. */
7550 if (!BKE_sculptsession_use_pbvh_draw(ob, v3d)) {
7551 /* Slow update with full dependency graph update and all that comes with it.
7552 * Needed when there are modifiers or full shading in the 3D viewport. */
7553 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
7554 ED_region_tag_redraw(region);
7555 }
7556 else {
7557 /* Fast path where we just update the BVH nodes that changed, and redraw
7558 * only the part of the 3D viewport where changes happened. */
7559 rcti r;
7560
7561 if (update_flags & SCULPT_UPDATE_COORDS) {
7562 BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB);
7563 /* Update the object's bounding box too so that the object
7564 * doesn't get incorrectly clipped during drawing in
7565 * draw_mesh_object(). T33790. */
7566 SCULPT_update_object_bounding_box(ob);
7567 }
7568
7569 if (SCULPT_get_redraw_rect(region, CTX_wm_region_view3d(C), ob, &r)) {
7570 if (ss->cache) {
7571 ss->cache->current_r = r;
7572 }
7573
7574 /* previous is not set in the current cache else
7575 * the partial rect will always grow */
7576 sculpt_extend_redraw_rect_previous(ob, &r);
7577
7578 r.xmin += region->winrct.xmin - 2;
7579 r.xmax += region->winrct.xmin + 2;
7580 r.ymin += region->winrct.ymin - 2;
7581 r.ymax += region->winrct.ymin + 2;
7582 ED_region_tag_redraw_partial(region, &r, true);
7583 }
7584 }
7585 }
7586
SCULPT_flush_update_done(const bContext * C,Object * ob,SculptUpdateType update_flags)7587 void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
7588 {
7589 /* After we are done drawing the stroke, check if we need to do a more
7590 * expensive depsgraph tag to update geometry. */
7591 wmWindowManager *wm = CTX_wm_manager(C);
7592 View3D *current_v3d = CTX_wm_view3d(C);
7593 RegionView3D *rv3d = CTX_wm_region_view3d(C);
7594 SculptSession *ss = ob->sculpt;
7595 Mesh *mesh = ob->data;
7596
7597 /* Always needed for linked duplicates. */
7598 bool need_tag = (ID_REAL_USERS(&mesh->id) > 1);
7599
7600 if (rv3d) {
7601 rv3d->rflag &= ~RV3D_PAINTING;
7602 }
7603
7604 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
7605 bScreen *screen = WM_window_get_active_screen(win);
7606 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
7607 SpaceLink *sl = area->spacedata.first;
7608 if (sl->spacetype == SPACE_VIEW3D) {
7609 View3D *v3d = (View3D *)sl;
7610 if (v3d != current_v3d) {
7611 need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, v3d);
7612 }
7613
7614 /* Tag all 3D viewports for redraw now that we are done. Others
7615 * viewports did not get a full redraw, and anti-aliasing for the
7616 * current viewport was deactivated. */
7617 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
7618 if (region->regiontype == RGN_TYPE_WINDOW) {
7619 ED_region_tag_redraw(region);
7620 }
7621 }
7622 }
7623 }
7624 }
7625
7626 if (update_flags & SCULPT_UPDATE_COORDS) {
7627 BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateOriginalBB);
7628
7629 /* Coordinates were modified, so fake neighbors are not longer valid. */
7630 SCULPT_fake_neighbors_free(ob);
7631 }
7632
7633 if (update_flags & SCULPT_UPDATE_MASK) {
7634 BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
7635 }
7636
7637 if (update_flags & SCULPT_UPDATE_COLOR) {
7638 BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateColor);
7639 }
7640
7641 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
7642 BKE_pbvh_bmesh_after_stroke(ss->pbvh);
7643 }
7644
7645 /* Optimization: if there is locked key and active modifiers present in */
7646 /* the stack, keyblock is updating at each step. otherwise we could update */
7647 /* keyblock only when stroke is finished. */
7648 if (ss->shapekey_active && !ss->deform_modifiers_active) {
7649 sculpt_update_keyblock(ob);
7650 }
7651
7652 if (need_tag) {
7653 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
7654 }
7655 }
7656
7657 /* Returns whether the mouse/stylus is over the mesh (1)
7658 * or over the background (0). */
over_mesh(bContext * C,struct wmOperator * UNUSED (op),float x,float y)7659 static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float y)
7660 {
7661 float mouse[2], co[3];
7662
7663 mouse[0] = x;
7664 mouse[1] = y;
7665
7666 return SCULPT_stroke_get_location(C, co, mouse);
7667 }
7668
sculpt_stroke_test_start(bContext * C,struct wmOperator * op,const float mouse[2])7669 static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2])
7670 {
7671 /* Don't start the stroke until mouse goes over the mesh.
7672 * note: mouse will only be null when re-executing the saved stroke.
7673 * We have exception for 'exec' strokes since they may not set 'mouse',
7674 * only 'location', see: T52195. */
7675 if (((op->flag & OP_IS_INVOKE) == 0) || (mouse == NULL) ||
7676 over_mesh(C, op, mouse[0], mouse[1])) {
7677 Object *ob = CTX_data_active_object(C);
7678 SculptSession *ss = ob->sculpt;
7679 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7680
7681 ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C));
7682
7683 sculpt_update_cache_invariants(C, sd, ss, op, mouse);
7684
7685 SCULPT_undo_push_begin(sculpt_tool_name(sd));
7686
7687 return true;
7688 }
7689 return false;
7690 }
7691
sculpt_stroke_update_step(bContext * C,struct PaintStroke * UNUSED (stroke),PointerRNA * itemptr)7692 static void sculpt_stroke_update_step(bContext *C,
7693 struct PaintStroke *UNUSED(stroke),
7694 PointerRNA *itemptr)
7695 {
7696 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
7697 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7698 Object *ob = CTX_data_active_object(C);
7699 SculptSession *ss = ob->sculpt;
7700 const Brush *brush = BKE_paint_brush(&sd->paint);
7701
7702 SCULPT_stroke_modifiers_check(C, ob, brush);
7703 sculpt_update_cache_variants(C, sd, ob, itemptr);
7704 sculpt_restore_mesh(sd, ob);
7705
7706 if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
7707 float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
7708 BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
7709 }
7710 else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
7711 BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f);
7712 }
7713 else {
7714 BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
7715 (ss->cache->radius / ss->cache->dyntopo_pixel_radius) *
7716 (sd->detail_size * U.pixelsize) / 0.4f);
7717 }
7718
7719 if (SCULPT_stroke_is_dynamic_topology(ss, brush)) {
7720 do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups);
7721 }
7722
7723 do_symmetrical_brush_actions(sd, ob, do_brush_action, ups);
7724 sculpt_combine_proxies(sd, ob);
7725
7726 /* Hack to fix noise texture tearing mesh. */
7727 sculpt_fix_noise_tear(sd, ob);
7728
7729 /* TODO(sergey): This is not really needed for the solid shading,
7730 * which does use pBVH drawing anyway, but texture and wireframe
7731 * requires this.
7732 *
7733 * Could be optimized later, but currently don't think it's so
7734 * much common scenario.
7735 *
7736 * Same applies to the DEG_id_tag_update() invoked from
7737 * sculpt_flush_update_step().
7738 */
7739 if (ss->deform_modifiers_active) {
7740 SCULPT_flush_stroke_deform(sd, ob, sculpt_tool_is_proxy_used(brush->sculpt_tool));
7741 }
7742 else if (ss->shapekey_active) {
7743 sculpt_update_keyblock(ob);
7744 }
7745
7746 ss->cache->first_time = false;
7747 copy_v3_v3(ss->cache->true_last_location, ss->cache->true_location);
7748
7749 /* Cleanup. */
7750 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
7751 SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
7752 }
7753 else if (ELEM(brush->sculpt_tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
7754 SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
7755 }
7756 else {
7757 SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
7758 }
7759 }
7760
sculpt_brush_exit_tex(Sculpt * sd)7761 static void sculpt_brush_exit_tex(Sculpt *sd)
7762 {
7763 Brush *brush = BKE_paint_brush(&sd->paint);
7764 MTex *mtex = &brush->mtex;
7765
7766 if (mtex->tex && mtex->tex->nodetree) {
7767 ntreeTexEndExecTree(mtex->tex->nodetree->execdata);
7768 }
7769 }
7770
sculpt_stroke_done(const bContext * C,struct PaintStroke * UNUSED (stroke))7771 static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke))
7772 {
7773 Main *bmain = CTX_data_main(C);
7774 Object *ob = CTX_data_active_object(C);
7775 Scene *scene = CTX_data_scene(C);
7776 SculptSession *ss = ob->sculpt;
7777 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7778
7779 /* Finished. */
7780 if (ss->cache) {
7781 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
7782 Brush *brush = BKE_paint_brush(&sd->paint);
7783 BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
7784 ups->draw_inverted = false;
7785
7786 SCULPT_stroke_modifiers_check(C, ob, brush);
7787
7788 /* Alt-Smooth. */
7789 if (ss->cache->alt_smooth) {
7790 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
7791 brush->mask_tool = ss->cache->saved_mask_brush_tool;
7792 }
7793 else if (ELEM(brush->sculpt_tool,
7794 SCULPT_TOOL_SLIDE_RELAX,
7795 SCULPT_TOOL_DRAW_FACE_SETS,
7796 SCULPT_TOOL_PAINT,
7797 SCULPT_TOOL_SMEAR)) {
7798 /* Do nothing. */
7799 }
7800 else {
7801 BKE_brush_size_set(scene, brush, ss->cache->saved_smooth_size);
7802 brush = (Brush *)BKE_libblock_find_name(bmain, ID_BR, ss->cache->saved_active_brush_name);
7803 if (brush) {
7804 BKE_paint_brush_set(&sd->paint, brush);
7805 }
7806 }
7807 }
7808
7809 if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
7810 SCULPT_automasking_cache_free(ss->cache->automasking);
7811 }
7812
7813 BKE_pbvh_node_color_buffer_free(ss->pbvh);
7814 SCULPT_cache_free(ss->cache);
7815 ss->cache = NULL;
7816
7817 SCULPT_undo_push_end();
7818
7819 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
7820 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
7821 }
7822 else {
7823 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
7824 }
7825
7826 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
7827 }
7828
7829 sculpt_brush_exit_tex(sd);
7830 }
7831
sculpt_brush_stroke_invoke(bContext * C,wmOperator * op,const wmEvent * event)7832 static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
7833 {
7834 struct PaintStroke *stroke;
7835 int ignore_background_click;
7836 int retval;
7837
7838 sculpt_brush_stroke_init(C, op);
7839
7840 stroke = paint_stroke_new(C,
7841 op,
7842 SCULPT_stroke_get_location,
7843 sculpt_stroke_test_start,
7844 sculpt_stroke_update_step,
7845 NULL,
7846 sculpt_stroke_done,
7847 event->type);
7848
7849 op->customdata = stroke;
7850
7851 /* For tablet rotation. */
7852 ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click");
7853
7854 if (ignore_background_click && !over_mesh(C, op, event->x, event->y)) {
7855 paint_stroke_free(C, op);
7856 return OPERATOR_PASS_THROUGH;
7857 }
7858
7859 if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
7860 paint_stroke_free(C, op);
7861 return OPERATOR_FINISHED;
7862 }
7863 /* Add modal handler. */
7864 WM_event_add_modal_handler(C, op);
7865
7866 OPERATOR_RETVAL_CHECK(retval);
7867 BLI_assert(retval == OPERATOR_RUNNING_MODAL);
7868
7869 return OPERATOR_RUNNING_MODAL;
7870 }
7871
sculpt_brush_stroke_exec(bContext * C,wmOperator * op)7872 static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
7873 {
7874 sculpt_brush_stroke_init(C, op);
7875
7876 op->customdata = paint_stroke_new(C,
7877 op,
7878 SCULPT_stroke_get_location,
7879 sculpt_stroke_test_start,
7880 sculpt_stroke_update_step,
7881 NULL,
7882 sculpt_stroke_done,
7883 0);
7884
7885 /* Frees op->customdata. */
7886 paint_stroke_exec(C, op);
7887
7888 return OPERATOR_FINISHED;
7889 }
7890
sculpt_brush_stroke_cancel(bContext * C,wmOperator * op)7891 static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
7892 {
7893 Object *ob = CTX_data_active_object(C);
7894 SculptSession *ss = ob->sculpt;
7895 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
7896 const Brush *brush = BKE_paint_brush(&sd->paint);
7897
7898 /* XXX Canceling strokes that way does not work with dynamic topology,
7899 * user will have to do real undo for now. See T46456. */
7900 if (ss->cache && !SCULPT_stroke_is_dynamic_topology(ss, brush)) {
7901 paint_mesh_restore_co(sd, ob);
7902 }
7903
7904 paint_stroke_cancel(C, op);
7905
7906 if (ss->cache) {
7907 SCULPT_cache_free(ss->cache);
7908 ss->cache = NULL;
7909 }
7910
7911 sculpt_brush_exit_tex(sd);
7912 }
7913
SCULPT_OT_brush_stroke(wmOperatorType * ot)7914 static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
7915 {
7916 /* Identifiers. */
7917 ot->name = "Sculpt";
7918 ot->idname = "SCULPT_OT_brush_stroke";
7919 ot->description = "Sculpt a stroke into the geometry";
7920
7921 /* API callbacks. */
7922 ot->invoke = sculpt_brush_stroke_invoke;
7923 ot->modal = paint_stroke_modal;
7924 ot->exec = sculpt_brush_stroke_exec;
7925 ot->poll = SCULPT_poll;
7926 ot->cancel = sculpt_brush_stroke_cancel;
7927
7928 /* Flags (sculpt does own undo? (ton)). */
7929 ot->flag = OPTYPE_BLOCKING;
7930
7931 /* Properties. */
7932
7933 paint_stroke_operator_properties(ot);
7934
7935 RNA_def_boolean(ot->srna,
7936 "ignore_background_click",
7937 0,
7938 "Ignore Background Click",
7939 "Clicks on the background do not start the stroke");
7940 }
7941
7942 /* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
7943
sculpt_set_persistent_base_exec(bContext * C,wmOperator * UNUSED (op))7944 static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
7945 {
7946 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
7947 Object *ob = CTX_data_active_object(C);
7948 SculptSession *ss = ob->sculpt;
7949
7950 if (ss) {
7951 SCULPT_vertex_random_access_ensure(ss);
7952 BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
7953
7954 MEM_SAFE_FREE(ss->persistent_base);
7955
7956 const int totvert = SCULPT_vertex_count_get(ss);
7957 ss->persistent_base = MEM_mallocN(sizeof(SculptPersistentBase) * totvert,
7958 "layer persistent base");
7959
7960 for (int i = 0; i < totvert; i++) {
7961 copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i));
7962 SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no);
7963 ss->persistent_base[i].disp = 0.0f;
7964 }
7965 }
7966
7967 return OPERATOR_FINISHED;
7968 }
7969
SCULPT_OT_set_persistent_base(wmOperatorType * ot)7970 static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
7971 {
7972 /* Identifiers. */
7973 ot->name = "Set Persistent Base";
7974 ot->idname = "SCULPT_OT_set_persistent_base";
7975 ot->description = "Reset the copy of the mesh that is being sculpted on";
7976
7977 /* API callbacks. */
7978 ot->exec = sculpt_set_persistent_base_exec;
7979 ot->poll = SCULPT_mode_poll;
7980
7981 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
7982 }
7983
7984 /************************* SCULPT_OT_optimize *************************/
7985
sculpt_optimize_exec(bContext * C,wmOperator * UNUSED (op))7986 static int sculpt_optimize_exec(bContext *C, wmOperator *UNUSED(op))
7987 {
7988 Object *ob = CTX_data_active_object(C);
7989
7990 SCULPT_pbvh_clear(ob);
7991 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
7992
7993 return OPERATOR_FINISHED;
7994 }
7995
7996 /* The BVH gets less optimal more quickly with dynamic topology than
7997 * regular sculpting. There is no doubt more clever stuff we can do to
7998 * optimize it on the fly, but for now this gives the user a nicer way
7999 * to recalculate it than toggling modes. */
SCULPT_OT_optimize(wmOperatorType * ot)8000 static void SCULPT_OT_optimize(wmOperatorType *ot)
8001 {
8002 /* Identifiers. */
8003 ot->name = "Rebuild BVH";
8004 ot->idname = "SCULPT_OT_optimize";
8005 ot->description = "Recalculate the sculpt BVH to improve performance";
8006
8007 /* API callbacks. */
8008 ot->exec = sculpt_optimize_exec;
8009 ot->poll = SCULPT_mode_poll;
8010
8011 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
8012 }
8013
8014 /********************* Dynamic topology symmetrize ********************/
8015
sculpt_no_multires_poll(bContext * C)8016 static bool sculpt_no_multires_poll(bContext *C)
8017 {
8018 Object *ob = CTX_data_active_object(C);
8019 if (SCULPT_mode_poll(C) && ob->sculpt && ob->sculpt->pbvh) {
8020 return BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_GRIDS;
8021 }
8022 return false;
8023 }
8024
sculpt_symmetrize_exec(bContext * C,wmOperator * op)8025 static int sculpt_symmetrize_exec(bContext *C, wmOperator *op)
8026 {
8027 Object *ob = CTX_data_active_object(C);
8028 const Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
8029 SculptSession *ss = ob->sculpt;
8030 PBVH *pbvh = ss->pbvh;
8031
8032 if (!pbvh) {
8033 return OPERATOR_CANCELLED;
8034 }
8035
8036 switch (BKE_pbvh_type(pbvh)) {
8037 case PBVH_BMESH:
8038 /* Dyntopo Symmetrize. */
8039
8040 /* To simplify undo for symmetrize, all BMesh elements are logged
8041 * as deleted, then after symmetrize operation all BMesh elements
8042 * are logged as added (as opposed to attempting to store just the
8043 * parts that symmetrize modifies). */
8044 SCULPT_undo_push_begin("Dynamic topology symmetrize");
8045 SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_SYMMETRIZE);
8046 BM_log_before_all_removed(ss->bm, ss->bm_log);
8047
8048 BM_mesh_toolflags_set(ss->bm, true);
8049
8050 /* Symmetrize and re-triangulate. */
8051 BMO_op_callf(ss->bm,
8052 (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE),
8053 "symmetrize input=%avef direction=%i dist=%f",
8054 sd->symmetrize_direction,
8055 0.00001f);
8056 SCULPT_dynamic_topology_triangulate(ss->bm);
8057
8058 /* Bisect operator flags edges (keep tags clean for edge queue). */
8059 BM_mesh_elem_hflag_disable_all(ss->bm, BM_EDGE, BM_ELEM_TAG, false);
8060
8061 BM_mesh_toolflags_set(ss->bm, false);
8062
8063 /* Finish undo. */
8064 BM_log_all_added(ss->bm, ss->bm_log);
8065 SCULPT_undo_push_end();
8066
8067 break;
8068 case PBVH_FACES:
8069 /* Mesh Symmetrize. */
8070 ED_sculpt_undo_geometry_begin(ob, "mesh symmetrize");
8071 Mesh *mesh = ob->data;
8072 Mesh *mesh_mirror;
8073 MirrorModifierData mmd = {{0}};
8074 int axis = 0;
8075 mmd.flag = 0;
8076 mmd.tolerance = RNA_float_get(op->ptr, "merge_tolerance");
8077 switch (sd->symmetrize_direction) {
8078 case BMO_SYMMETRIZE_NEGATIVE_X:
8079 axis = 0;
8080 mmd.flag |= MOD_MIR_AXIS_X | MOD_MIR_BISECT_AXIS_X | MOD_MIR_BISECT_FLIP_AXIS_X;
8081 break;
8082 case BMO_SYMMETRIZE_NEGATIVE_Y:
8083 axis = 1;
8084 mmd.flag |= MOD_MIR_AXIS_Y | MOD_MIR_BISECT_AXIS_Y | MOD_MIR_BISECT_FLIP_AXIS_Y;
8085 break;
8086 case BMO_SYMMETRIZE_NEGATIVE_Z:
8087 axis = 2;
8088 mmd.flag |= MOD_MIR_AXIS_Z | MOD_MIR_BISECT_AXIS_Z | MOD_MIR_BISECT_FLIP_AXIS_Z;
8089 break;
8090 case BMO_SYMMETRIZE_POSITIVE_X:
8091 axis = 0;
8092 mmd.flag |= MOD_MIR_AXIS_X | MOD_MIR_BISECT_AXIS_X;
8093 break;
8094 case BMO_SYMMETRIZE_POSITIVE_Y:
8095 axis = 1;
8096 mmd.flag |= MOD_MIR_AXIS_Y | MOD_MIR_BISECT_AXIS_Y;
8097 break;
8098 case BMO_SYMMETRIZE_POSITIVE_Z:
8099 axis = 2;
8100 mmd.flag |= MOD_MIR_AXIS_Z | MOD_MIR_BISECT_AXIS_Z;
8101 break;
8102 }
8103 mesh_mirror = BKE_mesh_mirror_apply_mirror_on_axis(&mmd, NULL, ob, mesh, axis);
8104 if (mesh_mirror) {
8105 BKE_mesh_nomain_to_mesh(mesh_mirror, mesh, ob, &CD_MASK_MESH, true);
8106 }
8107 ED_sculpt_undo_geometry_end(ob);
8108 BKE_mesh_calc_normals(ob->data);
8109 BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
8110
8111 break;
8112 case PBVH_GRIDS:
8113 return OPERATOR_CANCELLED;
8114 }
8115
8116 /* Redraw. */
8117 SCULPT_pbvh_clear(ob);
8118 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
8119
8120 return OPERATOR_FINISHED;
8121 }
8122
SCULPT_OT_symmetrize(wmOperatorType * ot)8123 static void SCULPT_OT_symmetrize(wmOperatorType *ot)
8124 {
8125 /* Identifiers. */
8126 ot->name = "Symmetrize";
8127 ot->idname = "SCULPT_OT_symmetrize";
8128 ot->description = "Symmetrize the topology modifications";
8129
8130 /* API callbacks. */
8131 ot->exec = sculpt_symmetrize_exec;
8132 ot->poll = sculpt_no_multires_poll;
8133
8134 RNA_def_float(ot->srna,
8135 "merge_tolerance",
8136 0.001f,
8137 0.0f,
8138 FLT_MAX,
8139 "Merge Distance",
8140 "Distance within which symmetrical vertices are merged",
8141 0.0f,
8142 1.0f);
8143 }
8144
8145 /**** Toggle operator for turning sculpt mode on or off ****/
8146
sculpt_init_session(Depsgraph * depsgraph,Scene * scene,Object * ob)8147 static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
8148 {
8149 /* Create persistent sculpt mode data. */
8150 BKE_sculpt_toolsettings_data_ensure(scene);
8151
8152 ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
8153 ob->sculpt->mode_type = OB_MODE_SCULPT;
8154 BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false);
8155
8156 /* Here we can detect geometry that was just added to Sculpt Mode as it has the
8157 * SCULPT_FACE_SET_NONE assigned, so we can create a new Face Set for it. */
8158 /* In sculpt mode all geometry that is assigned to SCULPT_FACE_SET_NONE is considered as not
8159 * initialized, which is used is some operators that modify the mesh topology to preform certain
8160 * actions in the new polys. After these operations are finished, all polys should have a valid
8161 * face set ID assigned (different from SCULPT_FACE_SET_NONE) to manage their visibility
8162 * correctly. */
8163 /* TODO(pablodp606): Based on this we can improve the UX in future tools for creating new
8164 * objects, like moving the transform pivot position to the new area or masking existing
8165 * geometry. */
8166 SculptSession *ss = ob->sculpt;
8167 const int new_face_set = SCULPT_face_set_next_available_get(ss);
8168 for (int i = 0; i < ss->totfaces; i++) {
8169 if (ss->face_sets[i] == SCULPT_FACE_SET_NONE) {
8170 ss->face_sets[i] = new_face_set;
8171 }
8172 }
8173
8174 /* Update the Face Sets visibility with the vertex visibility changes that may have been done
8175 * outside Sculpt Mode */
8176 Mesh *mesh = ob->data;
8177 BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(mesh);
8178 }
8179
ed_object_sculptmode_flush_recalc_flag(Scene * scene,Object * ob,MultiresModifierData * mmd)8180 static int ed_object_sculptmode_flush_recalc_flag(Scene *scene,
8181 Object *ob,
8182 MultiresModifierData *mmd)
8183 {
8184 int flush_recalc = 0;
8185 /* Multires in sculpt mode could have different from object mode subdivision level. */
8186 flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
8187 /* If object has got active modifiers, its dm could be different in sculpt mode. */
8188 flush_recalc |= sculpt_has_active_modifiers(scene, ob);
8189 return flush_recalc;
8190 }
8191
ED_object_sculptmode_enter_ex(Main * bmain,Depsgraph * depsgraph,Scene * scene,Object * ob,const bool force_dyntopo,ReportList * reports)8192 void ED_object_sculptmode_enter_ex(Main *bmain,
8193 Depsgraph *depsgraph,
8194 Scene *scene,
8195 Object *ob,
8196 const bool force_dyntopo,
8197 ReportList *reports)
8198 {
8199 const int mode_flag = OB_MODE_SCULPT;
8200 Mesh *me = BKE_mesh_from_object(ob);
8201
8202 /* Enter sculpt mode. */
8203 ob->mode |= mode_flag;
8204
8205 MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
8206
8207 const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
8208
8209 if (flush_recalc) {
8210 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
8211 }
8212
8213 /* Create sculpt mode session data. */
8214 if (ob->sculpt) {
8215 BKE_sculptsession_free(ob);
8216 }
8217
8218 /* Make sure derived final from original object does not reference possibly
8219 * freed memory. */
8220 BKE_object_free_derived_caches(ob);
8221
8222 /* Copy the current mesh visibility to the Face Sets. */
8223 BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(me);
8224
8225 sculpt_init_session(depsgraph, scene, ob);
8226
8227 /* Mask layer is required. */
8228 if (mmd) {
8229 /* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res)
8230 * but this ends up being quite tricky (and slow). */
8231 BKE_sculpt_mask_layers_ensure(ob, mmd);
8232 }
8233
8234 if (!(fabsf(ob->scale[0] - ob->scale[1]) < 1e-4f &&
8235 fabsf(ob->scale[1] - ob->scale[2]) < 1e-4f)) {
8236 BKE_report(
8237 reports, RPT_WARNING, "Object has non-uniform scale, sculpting may be unpredictable");
8238 }
8239 else if (is_negative_m4(ob->obmat)) {
8240 BKE_report(reports, RPT_WARNING, "Object has negative scale, sculpting may be unpredictable");
8241 }
8242
8243 Paint *paint = BKE_paint_get_active_from_paintmode(scene, PAINT_MODE_SCULPT);
8244 BKE_paint_init(bmain, scene, PAINT_MODE_SCULPT, PAINT_CURSOR_SCULPT);
8245
8246 paint_cursor_start(paint, SCULPT_mode_poll_view3d);
8247
8248 /* Check dynamic-topology flag; re-enter dynamic-topology mode when changing modes,
8249 * As long as no data was added that is not supported. */
8250 if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
8251 const char *message_unsupported = NULL;
8252 if (me->totloop != me->totpoly * 3) {
8253 message_unsupported = TIP_("non-triangle face");
8254 }
8255 else if (mmd != NULL) {
8256 message_unsupported = TIP_("multi-res modifier");
8257 }
8258 else {
8259 enum eDynTopoWarnFlag flag = SCULPT_dynamic_topology_check(scene, ob);
8260 if (flag == 0) {
8261 /* pass */
8262 }
8263 else if (flag & DYNTOPO_WARN_VDATA) {
8264 message_unsupported = TIP_("vertex data");
8265 }
8266 else if (flag & DYNTOPO_WARN_EDATA) {
8267 message_unsupported = TIP_("edge data");
8268 }
8269 else if (flag & DYNTOPO_WARN_LDATA) {
8270 message_unsupported = TIP_("face data");
8271 }
8272 else if (flag & DYNTOPO_WARN_MODIFIER) {
8273 message_unsupported = TIP_("constructive modifier");
8274 }
8275 else {
8276 BLI_assert(0);
8277 }
8278 }
8279
8280 if ((message_unsupported == NULL) || force_dyntopo) {
8281 /* Needed because we may be entering this mode before the undo system loads. */
8282 wmWindowManager *wm = bmain->wm.first;
8283 bool has_undo = wm->undo_stack != NULL;
8284 /* Undo push is needed to prevent memory leak. */
8285 if (has_undo) {
8286 SCULPT_undo_push_begin("Dynamic topology enable");
8287 }
8288 SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob);
8289 if (has_undo) {
8290 SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN);
8291 SCULPT_undo_push_end();
8292 }
8293 }
8294 else {
8295 BKE_reportf(
8296 reports, RPT_WARNING, "Dynamic Topology found: %s, disabled", message_unsupported);
8297 me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY;
8298 }
8299 }
8300
8301 /* Flush object mode. */
8302 DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
8303 }
8304
ED_object_sculptmode_enter(struct bContext * C,Depsgraph * depsgraph,ReportList * reports)8305 void ED_object_sculptmode_enter(struct bContext *C, Depsgraph *depsgraph, ReportList *reports)
8306 {
8307 Main *bmain = CTX_data_main(C);
8308 Scene *scene = CTX_data_scene(C);
8309 ViewLayer *view_layer = CTX_data_view_layer(C);
8310 Object *ob = OBACT(view_layer);
8311 ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, reports);
8312 }
8313
ED_object_sculptmode_exit_ex(Main * bmain,Depsgraph * depsgraph,Scene * scene,Object * ob)8314 void ED_object_sculptmode_exit_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
8315 {
8316 const int mode_flag = OB_MODE_SCULPT;
8317 Mesh *me = BKE_mesh_from_object(ob);
8318
8319 multires_flush_sculpt_updates(ob);
8320
8321 /* Not needed for now. */
8322 #if 0
8323 MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
8324 const int flush_recalc = ed_object_sculptmode_flush_recalc_flag(scene, ob, mmd);
8325 #endif
8326
8327 /* Always for now, so leaving sculpt mode always ensures scene is in
8328 * a consistent state. */
8329 if (true || /* flush_recalc || */ (ob->sculpt && ob->sculpt->bm)) {
8330 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
8331 }
8332
8333 if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
8334 /* Dynamic topology must be disabled before exiting sculpt
8335 * mode to ensure the undo stack stays in a consistent
8336 * state. */
8337 sculpt_dynamic_topology_disable_with_undo(bmain, depsgraph, scene, ob);
8338
8339 /* Store so we know to re-enable when entering sculpt mode. */
8340 me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY;
8341 }
8342
8343 /* Leave sculpt mode. */
8344 ob->mode &= ~mode_flag;
8345
8346 BKE_sculptsession_free(ob);
8347
8348 paint_cursor_delete_textures();
8349
8350 /* Never leave derived meshes behind. */
8351 BKE_object_free_derived_caches(ob);
8352
8353 /* Flush object mode. */
8354 DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
8355 }
8356
ED_object_sculptmode_exit(bContext * C,Depsgraph * depsgraph)8357 void ED_object_sculptmode_exit(bContext *C, Depsgraph *depsgraph)
8358 {
8359 Main *bmain = CTX_data_main(C);
8360 Scene *scene = CTX_data_scene(C);
8361 ViewLayer *view_layer = CTX_data_view_layer(C);
8362 Object *ob = OBACT(view_layer);
8363 ED_object_sculptmode_exit_ex(bmain, depsgraph, scene, ob);
8364 }
8365
sculpt_mode_toggle_exec(bContext * C,wmOperator * op)8366 static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
8367 {
8368 struct wmMsgBus *mbus = CTX_wm_message_bus(C);
8369 Main *bmain = CTX_data_main(C);
8370 Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
8371 Scene *scene = CTX_data_scene(C);
8372 ToolSettings *ts = scene->toolsettings;
8373 ViewLayer *view_layer = CTX_data_view_layer(C);
8374 Object *ob = OBACT(view_layer);
8375 const int mode_flag = OB_MODE_SCULPT;
8376 const bool is_mode_set = (ob->mode & mode_flag) != 0;
8377
8378 if (!is_mode_set) {
8379 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
8380 return OPERATOR_CANCELLED;
8381 }
8382 }
8383
8384 if (is_mode_set) {
8385 ED_object_sculptmode_exit_ex(bmain, depsgraph, scene, ob);
8386 }
8387 else {
8388 if (depsgraph) {
8389 depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
8390 }
8391 ED_object_sculptmode_enter_ex(bmain, depsgraph, scene, ob, false, op->reports);
8392 BKE_paint_toolslots_brush_validate(bmain, &ts->sculpt->paint);
8393
8394 if (ob->mode & mode_flag) {
8395 Mesh *me = ob->data;
8396 /* Dyntopo adds its own undo step. */
8397 if ((me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) == 0) {
8398 /* Without this the memfile undo step is used,
8399 * while it works it causes lag when undoing the first undo step, see T71564. */
8400 wmWindowManager *wm = CTX_wm_manager(C);
8401 if (wm->op_undo_depth <= 1) {
8402 SCULPT_undo_push_begin(op->type->name);
8403 }
8404 }
8405 }
8406 }
8407
8408 WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
8409
8410 WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
8411
8412 WM_toolsystem_update_from_context_view3d(C);
8413
8414 return OPERATOR_FINISHED;
8415 }
8416
SCULPT_OT_sculptmode_toggle(wmOperatorType * ot)8417 static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot)
8418 {
8419 /* Identifiers. */
8420 ot->name = "Sculpt Mode";
8421 ot->idname = "SCULPT_OT_sculptmode_toggle";
8422 ot->description = "Toggle sculpt mode in 3D view";
8423
8424 /* API callbacks. */
8425 ot->exec = sculpt_mode_toggle_exec;
8426 ot->poll = ED_operator_object_active_editable_mesh;
8427
8428 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
8429 }
8430
SCULPT_geometry_preview_lines_update(bContext * C,SculptSession * ss,float radius)8431 void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float radius)
8432 {
8433 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
8434 Object *ob = CTX_data_active_object(C);
8435
8436 ss->preview_vert_index_count = 0;
8437 int totpoints = 0;
8438
8439 /* This function is called from the cursor drawing code, so the PBVH may not be build yet. */
8440 if (!ss->pbvh) {
8441 return;
8442 }
8443
8444 if (!ss->deform_modifiers_active) {
8445 return;
8446 }
8447
8448 if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
8449 return;
8450 }
8451
8452 BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
8453
8454 if (!ss->pmap) {
8455 return;
8456 }
8457
8458 float brush_co[3];
8459 copy_v3_v3(brush_co, SCULPT_active_vertex_co_get(ss));
8460
8461 BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices");
8462
8463 /* Assuming an average of 6 edges per vertex in a triangulated mesh. */
8464 const int max_preview_vertices = SCULPT_vertex_count_get(ss) * 3 * 2;
8465
8466 if (ss->preview_vert_index_list == NULL) {
8467 ss->preview_vert_index_list = MEM_callocN(max_preview_vertices * sizeof(int), "preview lines");
8468 }
8469
8470 GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(int));
8471 int active_v = SCULPT_active_vertex_get(ss);
8472 BLI_gsqueue_push(not_visited_vertices, &active_v);
8473
8474 while (!BLI_gsqueue_is_empty(not_visited_vertices)) {
8475 int from_v;
8476 BLI_gsqueue_pop(not_visited_vertices, &from_v);
8477 SculptVertexNeighborIter ni;
8478 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
8479 if (totpoints + (ni.size * 2) < max_preview_vertices) {
8480 int to_v = ni.index;
8481 ss->preview_vert_index_list[totpoints] = from_v;
8482 totpoints++;
8483 ss->preview_vert_index_list[totpoints] = to_v;
8484 totpoints++;
8485 if (!BLI_BITMAP_TEST(visited_vertices, to_v)) {
8486 BLI_BITMAP_ENABLE(visited_vertices, to_v);
8487 const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v);
8488 if (len_squared_v3v3(brush_co, co) < radius * radius) {
8489 BLI_gsqueue_push(not_visited_vertices, &to_v);
8490 }
8491 }
8492 }
8493 }
8494 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
8495 }
8496
8497 BLI_gsqueue_free(not_visited_vertices);
8498
8499 MEM_freeN(visited_vertices);
8500
8501 ss->preview_vert_index_count = totpoints;
8502 }
8503
vertex_to_loop_colors_exec(bContext * C,wmOperator * UNUSED (op))8504 static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op))
8505 {
8506 Object *ob = CTX_data_active_object(C);
8507
8508 ID *data;
8509 data = ob->data;
8510 if (data && ID_IS_LINKED(data)) {
8511 return OPERATOR_CANCELLED;
8512 }
8513
8514 if (ob->type != OB_MESH) {
8515 return OPERATOR_CANCELLED;
8516 }
8517
8518 Mesh *mesh = ob->data;
8519
8520 const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL);
8521 if (mloopcol_layer_n == -1) {
8522 return OPERATOR_CANCELLED;
8523 }
8524 MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n);
8525
8526 const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
8527 if (MPropCol_layer_n == -1) {
8528 return OPERATOR_CANCELLED;
8529 }
8530 MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
8531
8532 MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
8533 MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
8534
8535 for (int i = 0; i < mesh->totpoly; i++) {
8536 MPoly *c_poly = &polys[i];
8537 for (int j = 0; j < c_poly->totloop; j++) {
8538 int loop_index = c_poly->loopstart + j;
8539 MLoop *c_loop = &loops[c_poly->loopstart + j];
8540 loopcols[loop_index].r = (char)(vertcols[c_loop->v].color[0] * 255);
8541 loopcols[loop_index].g = (char)(vertcols[c_loop->v].color[1] * 255);
8542 loopcols[loop_index].b = (char)(vertcols[c_loop->v].color[2] * 255);
8543 loopcols[loop_index].a = (char)(vertcols[c_loop->v].color[3] * 255);
8544 }
8545 }
8546
8547 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
8548 WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
8549
8550 return OPERATOR_FINISHED;
8551 }
8552
SCULPT_OT_vertex_to_loop_colors(wmOperatorType * ot)8553 static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot)
8554 {
8555 /* identifiers */
8556 ot->name = "Sculpt Vertex Color to Vertex Color";
8557 ot->description = "Copy the Sculpt Vertex Color to a regular color layer";
8558 ot->idname = "SCULPT_OT_vertex_to_loop_colors";
8559
8560 /* api callbacks */
8561 ot->poll = SCULPT_vertex_colors_poll;
8562 ot->exec = vertex_to_loop_colors_exec;
8563
8564 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
8565 }
8566
loop_to_vertex_colors_exec(bContext * C,wmOperator * UNUSED (op))8567 static int loop_to_vertex_colors_exec(bContext *C, wmOperator *UNUSED(op))
8568 {
8569 Object *ob = CTX_data_active_object(C);
8570
8571 ID *data;
8572 data = ob->data;
8573 if (data && ID_IS_LINKED(data)) {
8574 return OPERATOR_CANCELLED;
8575 }
8576
8577 if (ob->type != OB_MESH) {
8578 return OPERATOR_CANCELLED;
8579 }
8580
8581 Mesh *mesh = ob->data;
8582
8583 const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL);
8584 if (mloopcol_layer_n == -1) {
8585 return OPERATOR_CANCELLED;
8586 }
8587 MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n);
8588
8589 const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR);
8590 if (MPropCol_layer_n == -1) {
8591 return OPERATOR_CANCELLED;
8592 }
8593 MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n);
8594
8595 MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP);
8596 MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY);
8597
8598 for (int i = 0; i < mesh->totpoly; i++) {
8599 MPoly *c_poly = &polys[i];
8600 for (int j = 0; j < c_poly->totloop; j++) {
8601 int loop_index = c_poly->loopstart + j;
8602 MLoop *c_loop = &loops[c_poly->loopstart + j];
8603 vertcols[c_loop->v].color[0] = (loopcols[loop_index].r / 255.0f);
8604 vertcols[c_loop->v].color[1] = (loopcols[loop_index].g / 255.0f);
8605 vertcols[c_loop->v].color[2] = (loopcols[loop_index].b / 255.0f);
8606 vertcols[c_loop->v].color[3] = (loopcols[loop_index].a / 255.0f);
8607 }
8608 }
8609
8610 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
8611 WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
8612
8613 return OPERATOR_FINISHED;
8614 }
8615
SCULPT_OT_loop_to_vertex_colors(wmOperatorType * ot)8616 static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot)
8617 {
8618 /* identifiers */
8619 ot->name = "Vertex Color to Sculpt Vertex Color";
8620 ot->description = "Copy the active loop color layer to the vertex color";
8621 ot->idname = "SCULPT_OT_loop_to_vertex_colors";
8622
8623 /* api callbacks */
8624 ot->poll = SCULPT_vertex_colors_poll;
8625 ot->exec = loop_to_vertex_colors_exec;
8626
8627 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
8628 }
8629
sculpt_sample_color_invoke(bContext * C,wmOperator * UNUSED (op),const wmEvent * UNUSED (e))8630 static int sculpt_sample_color_invoke(bContext *C,
8631 wmOperator *UNUSED(op),
8632 const wmEvent *UNUSED(e))
8633 {
8634 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
8635 Scene *scene = CTX_data_scene(C);
8636 Object *ob = CTX_data_active_object(C);
8637 Brush *brush = BKE_paint_brush(&sd->paint);
8638 SculptSession *ss = ob->sculpt;
8639 int active_vertex = SCULPT_active_vertex_get(ss);
8640 const float *active_vertex_color = SCULPT_vertex_color_get(ss, active_vertex);
8641 if (!active_vertex_color) {
8642 return OPERATOR_CANCELLED;
8643 }
8644
8645 float color_srgb[3];
8646 copy_v3_v3(color_srgb, active_vertex_color);
8647 IMB_colormanagement_scene_linear_to_srgb_v3(color_srgb);
8648 BKE_brush_color_set(scene, brush, color_srgb);
8649
8650 WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush);
8651
8652 return OPERATOR_FINISHED;
8653 }
8654
SCULPT_OT_sample_color(wmOperatorType * ot)8655 static void SCULPT_OT_sample_color(wmOperatorType *ot)
8656 {
8657 /* identifiers */
8658 ot->name = "Sample color";
8659 ot->idname = "SCULPT_OT_sample_color";
8660 ot->description = "Sample the vertex color of the active vertex";
8661
8662 /* api callbacks */
8663 ot->invoke = sculpt_sample_color_invoke;
8664 ot->poll = SCULPT_vertex_colors_poll;
8665
8666 ot->flag = OPTYPE_REGISTER;
8667 }
8668
8669 /* Fake Neighbors. */
8670 /* This allows the sculpt tools to work on meshes with multiple connected components as they had
8671 * only one connected component. When initialized and enabled, the sculpt API will return extra
8672 * connectivity neighbors that are not in the real mesh. These neighbors are calculated for each
8673 * vertex using the minimum distance to a vertex that is in a different connected component. */
8674
8675 /* The fake neighbors first need to be ensured to be initialized.
8676 * After that tools which needs fake neighbors functionality need to
8677 * temporarily enable it:
8678 *
8679 * void my_awesome_sculpt_tool() {
8680 * SCULPT_fake_neighbors_ensure(sd, object, brush->disconnected_distance_max);
8681 * SCULPT_fake_neighbors_enable(ob);
8682 *
8683 * ... Logic of the tool ...
8684 * SCULPT_fake_neighbors_disable(ob);
8685 * }
8686 *
8687 * Such approach allows to keep all the connectivity information ready for reuse
8688 * (without having lag prior to every stroke), but also makes it so the affect
8689 * is localized to a specific brushes and tools only. */
8690
8691 enum {
8692 SCULPT_TOPOLOGY_ID_NONE,
8693 SCULPT_TOPOLOGY_ID_DEFAULT,
8694 };
8695
SCULPT_vertex_get_connected_component(SculptSession * ss,int index)8696 static int SCULPT_vertex_get_connected_component(SculptSession *ss, int index)
8697 {
8698 if (ss->vertex_info.connected_component) {
8699 return ss->vertex_info.connected_component[index];
8700 }
8701 return SCULPT_TOPOLOGY_ID_DEFAULT;
8702 }
8703
SCULPT_fake_neighbor_init(SculptSession * ss,const float max_dist)8704 static void SCULPT_fake_neighbor_init(SculptSession *ss, const float max_dist)
8705 {
8706 const int totvert = SCULPT_vertex_count_get(ss);
8707 ss->fake_neighbors.fake_neighbor_index = MEM_malloc_arrayN(
8708 totvert, sizeof(int), "fake neighbor");
8709 for (int i = 0; i < totvert; i++) {
8710 ss->fake_neighbors.fake_neighbor_index[i] = FAKE_NEIGHBOR_NONE;
8711 }
8712
8713 ss->fake_neighbors.current_max_distance = max_dist;
8714 }
8715
SCULPT_fake_neighbor_add(SculptSession * ss,int v_index_a,int v_index_b)8716 static void SCULPT_fake_neighbor_add(SculptSession *ss, int v_index_a, int v_index_b)
8717 {
8718 if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) {
8719 ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b;
8720 ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a;
8721 }
8722 }
8723
sculpt_pose_fake_neighbors_free(SculptSession * ss)8724 static void sculpt_pose_fake_neighbors_free(SculptSession *ss)
8725 {
8726 MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
8727 }
8728
8729 typedef struct NearestVertexFakeNeighborTLSData {
8730 int nearest_vertex_index;
8731 float nearest_vertex_distance_squared;
8732 int current_topology_id;
8733 } NearestVertexFakeNeighborTLSData;
8734
do_fake_neighbor_search_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict tls)8735 static void do_fake_neighbor_search_task_cb(void *__restrict userdata,
8736 const int n,
8737 const TaskParallelTLS *__restrict tls)
8738 {
8739 SculptThreadedTaskData *data = userdata;
8740 SculptSession *ss = data->ob->sculpt;
8741 NearestVertexFakeNeighborTLSData *nvtd = tls->userdata_chunk;
8742 PBVHVertexIter vd;
8743
8744 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
8745 {
8746 int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.index);
8747 if (vd_topology_id != nvtd->current_topology_id &&
8748 ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE) {
8749 float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co);
8750 if (distance_squared < nvtd->nearest_vertex_distance_squared &&
8751 distance_squared < data->max_distance_squared) {
8752 nvtd->nearest_vertex_index = vd.index;
8753 nvtd->nearest_vertex_distance_squared = distance_squared;
8754 }
8755 }
8756 }
8757 BKE_pbvh_vertex_iter_end;
8758 }
8759
fake_neighbor_search_reduce(const void * __restrict UNUSED (userdata),void * __restrict chunk_join,void * __restrict chunk)8760 static void fake_neighbor_search_reduce(const void *__restrict UNUSED(userdata),
8761 void *__restrict chunk_join,
8762 void *__restrict chunk)
8763 {
8764 NearestVertexFakeNeighborTLSData *join = chunk_join;
8765 NearestVertexFakeNeighborTLSData *nvtd = chunk;
8766 if (join->nearest_vertex_index == -1) {
8767 join->nearest_vertex_index = nvtd->nearest_vertex_index;
8768 join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
8769 }
8770 else if (nvtd->nearest_vertex_distance_squared < join->nearest_vertex_distance_squared) {
8771 join->nearest_vertex_index = nvtd->nearest_vertex_index;
8772 join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared;
8773 }
8774 }
8775
SCULPT_fake_neighbor_search(Sculpt * sd,Object * ob,const int index,float max_distance)8776 static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, float max_distance)
8777 {
8778 SculptSession *ss = ob->sculpt;
8779 PBVHNode **nodes = NULL;
8780 int totnode;
8781 SculptSearchSphereData data = {
8782 .ss = ss,
8783 .sd = sd,
8784 .radius_squared = max_distance * max_distance,
8785 .original = false,
8786 .center = SCULPT_vertex_co_get(ss, index),
8787 };
8788 BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode);
8789
8790 if (totnode == 0) {
8791 return -1;
8792 }
8793
8794 SculptThreadedTaskData task_data = {
8795 .sd = sd,
8796 .ob = ob,
8797 .nodes = nodes,
8798 .max_distance_squared = max_distance * max_distance,
8799 };
8800
8801 copy_v3_v3(task_data.nearest_vertex_search_co, SCULPT_vertex_co_get(ss, index));
8802
8803 NearestVertexFakeNeighborTLSData nvtd;
8804 nvtd.nearest_vertex_index = -1;
8805 nvtd.nearest_vertex_distance_squared = FLT_MAX;
8806 nvtd.current_topology_id = SCULPT_vertex_get_connected_component(ss, index);
8807
8808 TaskParallelSettings settings;
8809 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
8810 settings.func_reduce = fake_neighbor_search_reduce;
8811 settings.userdata_chunk = &nvtd;
8812 settings.userdata_chunk_size = sizeof(NearestVertexFakeNeighborTLSData);
8813 BLI_task_parallel_range(0, totnode, &task_data, do_fake_neighbor_search_task_cb, &settings);
8814
8815 MEM_SAFE_FREE(nodes);
8816
8817 return nvtd.nearest_vertex_index;
8818 }
8819
8820 typedef struct SculptTopologyIDFloodFillData {
8821 int next_id;
8822 } SculptTopologyIDFloodFillData;
8823
SCULPT_connected_components_floodfill_cb(SculptSession * ss,int from_v,int to_v,bool UNUSED (is_duplicate),void * userdata)8824 static bool SCULPT_connected_components_floodfill_cb(
8825 SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata)
8826 {
8827 SculptTopologyIDFloodFillData *data = userdata;
8828 ss->vertex_info.connected_component[from_v] = data->next_id;
8829 ss->vertex_info.connected_component[to_v] = data->next_id;
8830 return true;
8831 }
8832
sculpt_connected_components_ensure(Object * ob)8833 static void sculpt_connected_components_ensure(Object *ob)
8834 {
8835 SculptSession *ss = ob->sculpt;
8836
8837 /* Topology IDs already initialized. They only need to be recalculated when the PBVH is rebuild.
8838 */
8839 if (ss->vertex_info.connected_component) {
8840 return;
8841 }
8842
8843 const int totvert = SCULPT_vertex_count_get(ss);
8844 ss->vertex_info.connected_component = MEM_malloc_arrayN(totvert, sizeof(int), "topology ID");
8845
8846 for (int i = 0; i < totvert; i++) {
8847 ss->vertex_info.connected_component[i] = SCULPT_TOPOLOGY_ID_NONE;
8848 }
8849
8850 int next_id = 0;
8851 for (int i = 0; i < totvert; i++) {
8852 if (ss->vertex_info.connected_component[i] == SCULPT_TOPOLOGY_ID_NONE) {
8853 SculptFloodFill flood;
8854 SCULPT_floodfill_init(ss, &flood);
8855 SCULPT_floodfill_add_initial(&flood, i);
8856 SculptTopologyIDFloodFillData data;
8857 data.next_id = next_id;
8858 SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data);
8859 SCULPT_floodfill_free(&flood);
8860 next_id++;
8861 }
8862 }
8863 }
8864
SCULPT_boundary_info_ensure(Object * object)8865 void SCULPT_boundary_info_ensure(Object *object)
8866 {
8867 SculptSession *ss = object->sculpt;
8868 if (ss->vertex_info.boundary) {
8869 return;
8870 }
8871
8872 Mesh *base_mesh = BKE_mesh_from_object(object);
8873 ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info");
8874 int *adjacent_faces_edge_count = MEM_calloc_arrayN(
8875 base_mesh->totedge, sizeof(int), "Adjacent face edge count");
8876
8877 for (int p = 0; p < base_mesh->totpoly; p++) {
8878 MPoly *poly = &base_mesh->mpoly[p];
8879 for (int l = 0; l < poly->totloop; l++) {
8880 MLoop *loop = &base_mesh->mloop[l + poly->loopstart];
8881 adjacent_faces_edge_count[loop->e]++;
8882 }
8883 }
8884
8885 for (int e = 0; e < base_mesh->totedge; e++) {
8886 if (adjacent_faces_edge_count[e] < 2) {
8887 MEdge *edge = &base_mesh->medge[e];
8888 BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v1, true);
8889 BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v2, true);
8890 }
8891 }
8892
8893 MEM_freeN(adjacent_faces_edge_count);
8894 }
8895
SCULPT_fake_neighbors_ensure(Sculpt * sd,Object * ob,const float max_dist)8896 void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist)
8897 {
8898 SculptSession *ss = ob->sculpt;
8899 const int totvert = SCULPT_vertex_count_get(ss);
8900
8901 /* Fake neighbors were already initialized with the same distance, so no need to be recalculated.
8902 */
8903 if (ss->fake_neighbors.fake_neighbor_index &&
8904 ss->fake_neighbors.current_max_distance == max_dist) {
8905 return;
8906 }
8907
8908 sculpt_connected_components_ensure(ob);
8909 SCULPT_fake_neighbor_init(ss, max_dist);
8910
8911 for (int i = 0; i < totvert; i++) {
8912 const int from_v = i;
8913
8914 /* This vertex does not have a fake neighbor yet, seach one for it. */
8915 if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) {
8916 const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist);
8917 if (to_v != -1) {
8918 /* Add the fake neighbor if available. */
8919 SCULPT_fake_neighbor_add(ss, from_v, to_v);
8920 }
8921 }
8922 }
8923 }
8924
SCULPT_fake_neighbors_enable(Object * ob)8925 void SCULPT_fake_neighbors_enable(Object *ob)
8926 {
8927 SculptSession *ss = ob->sculpt;
8928 BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
8929 ss->fake_neighbors.use_fake_neighbors = true;
8930 }
8931
SCULPT_fake_neighbors_disable(Object * ob)8932 void SCULPT_fake_neighbors_disable(Object *ob)
8933 {
8934 SculptSession *ss = ob->sculpt;
8935 BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL);
8936 ss->fake_neighbors.use_fake_neighbors = false;
8937 }
8938
SCULPT_fake_neighbors_free(Object * ob)8939 void SCULPT_fake_neighbors_free(Object *ob)
8940 {
8941 SculptSession *ss = ob->sculpt;
8942 sculpt_pose_fake_neighbors_free(ss);
8943 }
8944
8945 /**
8946 * #sculpt_mask_by_color_delta_get returns values in the (0,1) range that are used to generate the
8947 * mask based on the difference between two colors (the active color and the color of any other
8948 * vertex). Ideally, a threshold of 0 should mask only the colors that are equal to the active
8949 * color and threshold of 1 should mask all colors. In order to avoid artifacts and produce softer
8950 * falloffs in the mask, the MASK_BY_COLOR_SLOPE defines the size of the transition values between
8951 * masked and unmasked vertices. The smaller this value is, the sharper the generated mask is going
8952 * to be.
8953 */
8954 #define MASK_BY_COLOR_SLOPE 0.25f
8955
sculpt_mask_by_color_delta_get(const float * color_a,const float * color_b,const float threshold,const bool invert)8956 static float sculpt_mask_by_color_delta_get(const float *color_a,
8957 const float *color_b,
8958 const float threshold,
8959 const bool invert)
8960 {
8961 float len = len_v3v3(color_a, color_b);
8962 /* Normalize len to the (0, 1) range. */
8963 len = len / M_SQRT3;
8964
8965 if (len < threshold - MASK_BY_COLOR_SLOPE) {
8966 len = 1.0f;
8967 }
8968 else if (len >= threshold) {
8969 len = 0.0f;
8970 }
8971 else {
8972 len = (-len + threshold) / MASK_BY_COLOR_SLOPE;
8973 }
8974
8975 if (invert) {
8976 return 1.0f - len;
8977 }
8978 return len;
8979 }
8980
sculpt_mask_by_color_final_mask_get(const float current_mask,const float new_mask,const bool invert,const bool preserve_mask)8981 static float sculpt_mask_by_color_final_mask_get(const float current_mask,
8982 const float new_mask,
8983 const bool invert,
8984 const bool preserve_mask)
8985 {
8986 if (preserve_mask) {
8987 if (invert) {
8988 return min_ff(current_mask, new_mask);
8989 }
8990 return max_ff(current_mask, new_mask);
8991 }
8992 return new_mask;
8993 }
8994
8995 typedef struct MaskByColorContiguousFloodFillData {
8996 float threshold;
8997 bool invert;
8998 float *new_mask;
8999 float initial_color[3];
9000 } MaskByColorContiguousFloodFillData;
9001
do_mask_by_color_contiguous_update_nodes_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))9002 static void do_mask_by_color_contiguous_update_nodes_cb(
9003 void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls))
9004 {
9005 SculptThreadedTaskData *data = userdata;
9006 SculptSession *ss = data->ob->sculpt;
9007
9008 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
9009 bool update_node = false;
9010
9011 const bool invert = data->mask_by_color_invert;
9012 const bool preserve_mask = data->mask_by_color_preserve_mask;
9013
9014 PBVHVertexIter vd;
9015 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
9016 {
9017 const float current_mask = *vd.mask;
9018 const float new_mask = data->mask_by_color_floodfill[vd.index];
9019 *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
9020 if (current_mask != *vd.mask) {
9021 update_node = true;
9022 if (vd.mvert) {
9023 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
9024 }
9025 }
9026 }
9027 BKE_pbvh_vertex_iter_end;
9028 if (update_node) {
9029 BKE_pbvh_node_mark_redraw(data->nodes[n]);
9030 }
9031 }
9032
sculpt_mask_by_color_contiguous_floodfill_cb(SculptSession * ss,int from_v,int to_v,bool is_duplicate,void * userdata)9033 static bool sculpt_mask_by_color_contiguous_floodfill_cb(
9034 SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
9035 {
9036 MaskByColorContiguousFloodFillData *data = userdata;
9037 const float *current_color = SCULPT_vertex_color_get(ss, to_v);
9038 float new_vertex_mask = sculpt_mask_by_color_delta_get(
9039 current_color, data->initial_color, data->threshold, data->invert);
9040 data->new_mask[to_v] = new_vertex_mask;
9041
9042 if (is_duplicate) {
9043 data->new_mask[to_v] = data->new_mask[from_v];
9044 }
9045
9046 float len = len_v3v3(current_color, data->initial_color);
9047 len = len / M_SQRT3;
9048 return len <= data->threshold;
9049 }
9050
sculpt_mask_by_color_contiguous(Object * object,const int vertex,const float threshold,const bool invert,const bool preserve_mask)9051 static void sculpt_mask_by_color_contiguous(Object *object,
9052 const int vertex,
9053 const float threshold,
9054 const bool invert,
9055 const bool preserve_mask)
9056 {
9057 SculptSession *ss = object->sculpt;
9058 const int totvert = SCULPT_vertex_count_get(ss);
9059
9060 float *new_mask = MEM_calloc_arrayN(totvert, sizeof(float), "new mask");
9061
9062 if (invert) {
9063 for (int i = 0; i < totvert; i++) {
9064 new_mask[i] = 1.0f;
9065 }
9066 }
9067
9068 SculptFloodFill flood;
9069 SCULPT_floodfill_init(ss, &flood);
9070 SCULPT_floodfill_add_initial(&flood, vertex);
9071
9072 MaskByColorContiguousFloodFillData ffd;
9073 ffd.threshold = threshold;
9074 ffd.invert = invert;
9075 ffd.new_mask = new_mask;
9076 copy_v3_v3(ffd.initial_color, SCULPT_vertex_color_get(ss, vertex));
9077
9078 SCULPT_floodfill_execute(ss, &flood, sculpt_mask_by_color_contiguous_floodfill_cb, &ffd);
9079 SCULPT_floodfill_free(&flood);
9080
9081 int totnode;
9082 PBVHNode **nodes;
9083 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
9084
9085 SculptThreadedTaskData data = {
9086 .ob = object,
9087 .nodes = nodes,
9088 .mask_by_color_floodfill = new_mask,
9089 .mask_by_color_vertex = vertex,
9090 .mask_by_color_threshold = threshold,
9091 .mask_by_color_invert = invert,
9092 .mask_by_color_preserve_mask = preserve_mask,
9093 };
9094
9095 TaskParallelSettings settings;
9096 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
9097 BLI_task_parallel_range(
9098 0, totnode, &data, do_mask_by_color_contiguous_update_nodes_cb, &settings);
9099
9100 MEM_SAFE_FREE(nodes);
9101
9102 MEM_freeN(new_mask);
9103 }
9104
do_mask_by_color_task_cb(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))9105 static void do_mask_by_color_task_cb(void *__restrict userdata,
9106 const int n,
9107 const TaskParallelTLS *__restrict UNUSED(tls))
9108 {
9109 SculptThreadedTaskData *data = userdata;
9110 SculptSession *ss = data->ob->sculpt;
9111
9112 SCULPT_undo_push_node(data->ob, data->nodes[n], SCULPT_UNDO_MASK);
9113 bool update_node = false;
9114
9115 const float threshold = data->mask_by_color_threshold;
9116 const bool invert = data->mask_by_color_invert;
9117 const bool preserve_mask = data->mask_by_color_preserve_mask;
9118 const float *active_color = SCULPT_vertex_color_get(ss, data->mask_by_color_vertex);
9119
9120 PBVHVertexIter vd;
9121 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
9122 {
9123 const float current_mask = *vd.mask;
9124 const float new_mask = sculpt_mask_by_color_delta_get(active_color, vd.col, threshold, invert);
9125 *vd.mask = sculpt_mask_by_color_final_mask_get(current_mask, new_mask, invert, preserve_mask);
9126
9127 if (current_mask != *vd.mask) {
9128 update_node = true;
9129 if (vd.mvert) {
9130 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
9131 }
9132 }
9133 }
9134 BKE_pbvh_vertex_iter_end;
9135 if (update_node) {
9136 BKE_pbvh_node_mark_redraw(data->nodes[n]);
9137 }
9138 }
9139
sculpt_mask_by_color_full_mesh(Object * object,const int vertex,const float threshold,const bool invert,const bool preserve_mask)9140 static void sculpt_mask_by_color_full_mesh(Object *object,
9141 const int vertex,
9142 const float threshold,
9143 const bool invert,
9144 const bool preserve_mask)
9145 {
9146 SculptSession *ss = object->sculpt;
9147
9148 int totnode;
9149 PBVHNode **nodes;
9150 BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
9151
9152 SculptThreadedTaskData data = {
9153 .ob = object,
9154 .nodes = nodes,
9155 .mask_by_color_vertex = vertex,
9156 .mask_by_color_threshold = threshold,
9157 .mask_by_color_invert = invert,
9158 .mask_by_color_preserve_mask = preserve_mask,
9159 };
9160
9161 TaskParallelSettings settings;
9162 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
9163 BLI_task_parallel_range(0, totnode, &data, do_mask_by_color_task_cb, &settings);
9164
9165 MEM_SAFE_FREE(nodes);
9166 }
9167
sculpt_mask_by_color_invoke(bContext * C,wmOperator * op,const wmEvent * event)9168 static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
9169 {
9170 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
9171 Object *ob = CTX_data_active_object(C);
9172 SculptSession *ss = ob->sculpt;
9173
9174 BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
9175
9176 /* Color data is not available in Multires. */
9177 if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
9178 return OPERATOR_CANCELLED;
9179 }
9180
9181 if (!ss->vcol) {
9182 return OPERATOR_CANCELLED;
9183 }
9184
9185 SCULPT_vertex_random_access_ensure(ss);
9186
9187 /* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move,
9188 * so it needs to be updated here. */
9189 SculptCursorGeometryInfo sgi;
9190 float mouse[2];
9191 mouse[0] = event->mval[0];
9192 mouse[1] = event->mval[1];
9193 SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
9194
9195 SCULPT_undo_push_begin("Mask by color");
9196
9197 const int active_vertex = SCULPT_active_vertex_get(ss);
9198 const float threshold = RNA_float_get(op->ptr, "threshold");
9199 const bool invert = RNA_boolean_get(op->ptr, "invert");
9200 const bool preserve_mask = RNA_boolean_get(op->ptr, "preserve_previous_mask");
9201
9202 if (RNA_boolean_get(op->ptr, "contiguous")) {
9203 sculpt_mask_by_color_contiguous(ob, active_vertex, threshold, invert, preserve_mask);
9204 }
9205 else {
9206 sculpt_mask_by_color_full_mesh(ob, active_vertex, threshold, invert, preserve_mask);
9207 }
9208
9209 BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateMask);
9210 SCULPT_undo_push_end();
9211
9212 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
9213
9214 return OPERATOR_FINISHED;
9215 }
9216
SCULPT_OT_mask_by_color(wmOperatorType * ot)9217 static void SCULPT_OT_mask_by_color(wmOperatorType *ot)
9218 {
9219 /* identifiers */
9220 ot->name = "Mask By Color";
9221 ot->idname = "SCULPT_OT_mask_by_color";
9222 ot->description = "Creates a mask based on the sculpt vertex colors";
9223
9224 /* api callbacks */
9225 ot->invoke = sculpt_mask_by_color_invoke;
9226 ot->poll = SCULPT_vertex_colors_poll;
9227
9228 ot->flag = OPTYPE_REGISTER;
9229
9230 ot->prop = RNA_def_boolean(
9231 ot->srna, "contiguous", false, "Contiguous", "Mask only contiguous color areas");
9232
9233 ot->prop = RNA_def_boolean(ot->srna, "invert", false, "Invert", "Invert the generated mask");
9234 ot->prop = RNA_def_boolean(
9235 ot->srna,
9236 "preserve_previous_mask",
9237 false,
9238 "Preserve Previous Mask",
9239 "Preserve the previous mask and add or subtract the new one generated by the colors");
9240
9241 RNA_def_float(ot->srna,
9242 "threshold",
9243 0.35f,
9244 0.0f,
9245 1.0f,
9246 "Threshold",
9247 "How much changes in color affect the mask generation",
9248 0.0f,
9249 1.0f);
9250 }
9251
ED_operatortypes_sculpt(void)9252 void ED_operatortypes_sculpt(void)
9253 {
9254 WM_operatortype_append(SCULPT_OT_brush_stroke);
9255 WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
9256 WM_operatortype_append(SCULPT_OT_set_persistent_base);
9257 WM_operatortype_append(SCULPT_OT_dynamic_topology_toggle);
9258 WM_operatortype_append(SCULPT_OT_optimize);
9259 WM_operatortype_append(SCULPT_OT_symmetrize);
9260 WM_operatortype_append(SCULPT_OT_detail_flood_fill);
9261 WM_operatortype_append(SCULPT_OT_sample_detail_size);
9262 WM_operatortype_append(SCULPT_OT_set_detail_size);
9263 WM_operatortype_append(SCULPT_OT_mesh_filter);
9264 WM_operatortype_append(SCULPT_OT_mask_filter);
9265 WM_operatortype_append(SCULPT_OT_dirty_mask);
9266 WM_operatortype_append(SCULPT_OT_mask_expand);
9267 WM_operatortype_append(SCULPT_OT_set_pivot_position);
9268 WM_operatortype_append(SCULPT_OT_face_sets_create);
9269 WM_operatortype_append(SCULPT_OT_face_sets_change_visibility);
9270 WM_operatortype_append(SCULPT_OT_face_sets_randomize_colors);
9271 WM_operatortype_append(SCULPT_OT_face_sets_init);
9272 WM_operatortype_append(SCULPT_OT_cloth_filter);
9273 WM_operatortype_append(SCULPT_OT_face_sets_edit);
9274 WM_operatortype_append(SCULPT_OT_face_set_lasso_gesture);
9275 WM_operatortype_append(SCULPT_OT_face_set_box_gesture);
9276 WM_operatortype_append(SCULPT_OT_trim_box_gesture);
9277 WM_operatortype_append(SCULPT_OT_trim_lasso_gesture);
9278 WM_operatortype_append(SCULPT_OT_project_line_gesture);
9279
9280 WM_operatortype_append(SCULPT_OT_sample_color);
9281 WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors);
9282 WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors);
9283 WM_operatortype_append(SCULPT_OT_color_filter);
9284 WM_operatortype_append(SCULPT_OT_mask_by_color);
9285 }
9286