Cleanup: Use const argument to sculpt accessor functions
[blender.git] / source / blender / editors / sculpt_paint / sculpt.cc
blob01be621ca98802ec6d6b8639bb557dda76fb6509
1 /* SPDX-FileCopyrightText: 2006 by Nicholas Bishop. All rights reserved.
3 * SPDX-License-Identifier: GPL-2.0-or-later */
5 /** \file
6 * \ingroup edsculpt
7 * Implements the Sculpt Mode tools.
8 */
10 #include <cmath>
11 #include <cstdlib>
12 #include <cstring>
13 #include <iostream>
15 #include "MEM_guardedalloc.h"
17 #include "CLG_log.h"
19 #include "BLI_array_utils.hh"
20 #include "BLI_bit_span_ops.hh"
21 #include "BLI_blenlib.h"
22 #include "BLI_dial_2d.h"
23 #include "BLI_ghash.h"
24 #include "BLI_math_geom.h"
25 #include "BLI_math_matrix.h"
26 #include "BLI_set.hh"
27 #include "BLI_span.hh"
28 #include "BLI_task.h"
29 #include "BLI_task.hh"
30 #include "BLI_utildefines.h"
31 #include "BLI_vector.hh"
33 #include "DNA_brush_types.h"
34 #include "DNA_customdata_types.h"
35 #include "DNA_key_types.h"
36 #include "DNA_node_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
40 #include "BKE_attribute.hh"
41 #include "BKE_brush.hh"
42 #include "BKE_ccg.h"
43 #include "BKE_colortools.hh"
44 #include "BKE_context.hh"
45 #include "BKE_customdata.hh"
46 #include "BKE_image.h"
47 #include "BKE_key.hh"
48 #include "BKE_layer.hh"
49 #include "BKE_lib_id.hh"
50 #include "BKE_main.hh"
51 #include "BKE_mesh.hh"
52 #include "BKE_mesh_mapping.hh"
53 #include "BKE_modifier.hh"
54 #include "BKE_multires.hh"
55 #include "BKE_node_runtime.hh"
56 #include "BKE_object.hh"
57 #include "BKE_object_types.hh"
58 #include "BKE_paint.hh"
59 #include "BKE_pbvh_api.hh"
60 #include "BKE_report.hh"
61 #include "BKE_scene.hh"
62 #include "BKE_subdiv_ccg.hh"
63 #include "BKE_subsurf.hh"
64 #include "BLI_math_vector.hh"
66 #include "NOD_texture.h"
68 #include "DEG_depsgraph.hh"
70 #include "WM_api.hh"
71 #include "WM_types.hh"
73 #include "ED_gpencil_legacy.hh"
74 #include "ED_paint.hh"
75 #include "ED_screen.hh"
76 #include "ED_sculpt.hh"
77 #include "ED_view3d.hh"
79 #include "paint_intern.hh"
80 #include "sculpt_intern.hh"
82 #include "RNA_access.hh"
83 #include "RNA_define.hh"
85 #include "bmesh.hh"
87 using blender::float3;
88 using blender::MutableSpan;
89 using blender::Set;
90 using blender::Span;
91 using blender::Vector;
93 static CLG_LogRef LOG = {"ed.sculpt_paint"};
95 namespace blender::ed::sculpt_paint {
96 float sculpt_calc_radius(ViewContext *vc,
97 const Brush *brush,
98 const Scene *scene,
99 const float3 location)
101 if (!BKE_brush_use_locked_size(scene, brush)) {
102 return paint_calc_object_space_radius(vc, location, BKE_brush_size_get(scene, brush));
104 else {
105 return BKE_brush_unprojected_radius_get(scene, brush);
108 } // namespace blender::ed::sculpt_paint
110 bool ED_sculpt_report_if_shape_key_is_locked(const Object *ob, ReportList *reports)
112 SculptSession *ss = ob->sculpt;
114 BLI_assert(ss);
116 if (ss->shapekey_active && (ss->shapekey_active->flag & KEYBLOCK_LOCKED_SHAPE) != 0) {
117 if (reports) {
118 BKE_reportf(reports, RPT_ERROR, "The active shape key of %s is locked", ob->id.name + 2);
120 return true;
123 return false;
126 /* -------------------------------------------------------------------- */
127 /** \name Sculpt PBVH Abstraction API
129 * This is read-only, for writing use PBVH vertex iterators. There vd.index matches
130 * the indices used here.
132 * For multi-resolution, the same vertex in multiple grids is counted multiple times, with
133 * different index for each grid.
134 * \{ */
136 SculptMaskWriteInfo SCULPT_mask_get_for_write(SculptSession *ss)
138 SculptMaskWriteInfo info;
139 switch (BKE_pbvh_type(ss->pbvh)) {
140 case PBVH_FACES: {
141 Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh);
142 info.layer = static_cast<float *>(CustomData_get_layer_named_for_write(
143 &mesh->vert_data, CD_PROP_FLOAT, ".sculpt_mask", mesh->verts_num));
144 break;
146 case PBVH_BMESH:
147 info.bm_offset = CustomData_get_offset_named(
148 &BKE_pbvh_get_bmesh(ss->pbvh)->vdata, CD_PROP_FLOAT, ".sculpt_mask");
149 break;
150 case PBVH_GRIDS:
151 break;
153 return info;
156 void SCULPT_vertex_random_access_ensure(SculptSession *ss)
158 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
159 BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
160 BM_mesh_elem_table_ensure(ss->bm, BM_VERT);
164 int SCULPT_vertex_count_get(const SculptSession *ss)
166 switch (BKE_pbvh_type(ss->pbvh)) {
167 case PBVH_FACES:
168 return ss->totvert;
169 case PBVH_BMESH:
170 return BM_mesh_elem_count(BKE_pbvh_get_bmesh(ss->pbvh), BM_VERT);
171 case PBVH_GRIDS:
172 return BKE_pbvh_get_grid_num_verts(ss->pbvh);
175 return 0;
178 const float *SCULPT_vertex_co_get(const SculptSession *ss, PBVHVertRef vertex)
180 switch (BKE_pbvh_type(ss->pbvh)) {
181 case PBVH_FACES: {
182 if (ss->shapekey_active || ss->deform_modifiers_active) {
183 const Span<float3> positions = BKE_pbvh_get_vert_positions(ss->pbvh);
184 return positions[vertex.i];
186 return ss->vert_positions[vertex.i];
188 case PBVH_BMESH:
189 return ((BMVert *)vertex.i)->co;
190 case PBVH_GRIDS: {
191 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
192 const int grid_index = vertex.i / key->grid_area;
193 const int index_in_grid = vertex.i - grid_index * key->grid_area;
194 CCGElem *elem = ss->subdiv_ccg->grids[grid_index];
195 return CCG_elem_co(key, CCG_elem_offset(key, elem, index_in_grid));
198 return nullptr;
201 bool SCULPT_has_loop_colors(const Object *ob)
203 using namespace blender;
204 Mesh *mesh = BKE_object_get_original_mesh(ob);
205 const std::optional<bke::AttributeMetaData> meta_data = mesh->attributes().lookup_meta_data(
206 mesh->active_color_attribute);
207 if (!meta_data) {
208 return false;
210 if (meta_data->domain != bke::AttrDomain::Corner) {
211 return false;
213 if (!(CD_TYPE_AS_MASK(meta_data->data_type) & CD_MASK_COLOR_ALL)) {
214 return false;
216 return true;
219 bool SCULPT_has_colors(const SculptSession *ss)
221 return ss->vcol || ss->mcol;
224 void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4])
226 BKE_pbvh_vertex_color_get(ss->pbvh, vertex, r_color);
229 void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4])
231 BKE_pbvh_vertex_color_set(ss->pbvh, vertex, color);
234 void SCULPT_vertex_normal_get(const SculptSession *ss, PBVHVertRef vertex, float no[3])
236 switch (BKE_pbvh_type(ss->pbvh)) {
237 case PBVH_FACES: {
238 const Span<float3> vert_normals = BKE_pbvh_get_vert_normals(ss->pbvh);
239 copy_v3_v3(no, vert_normals[vertex.i]);
240 break;
242 case PBVH_BMESH: {
243 BMVert *v = (BMVert *)vertex.i;
244 copy_v3_v3(no, v->no);
245 break;
247 case PBVH_GRIDS: {
248 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
249 const int grid_index = vertex.i / key->grid_area;
250 const int index_in_grid = vertex.i - grid_index * key->grid_area;
251 CCGElem *elem = ss->subdiv_ccg->grids[grid_index];
252 copy_v3_v3(no, CCG_elem_no(key, CCG_elem_offset(key, elem, index_in_grid)));
253 break;
258 const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex)
260 if (ss->attrs.persistent_co) {
261 return (const float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_co);
264 return SCULPT_vertex_co_get(ss, vertex);
267 const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, PBVHVertRef vertex)
269 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
270 /* Always grab active shape key if the sculpt happens on shapekey. */
271 if (ss->shapekey_active) {
272 const Span<float3> positions = BKE_pbvh_get_vert_positions(ss->pbvh);
273 return positions[vertex.i];
276 /* Sculpting on the base mesh. */
277 return ss->vert_positions[vertex.i];
280 /* Everything else, such as sculpting on multires. */
281 return SCULPT_vertex_co_get(ss, vertex);
284 void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, float r_co[3])
286 switch (BKE_pbvh_type(ss->pbvh)) {
287 case PBVH_FACES:
288 case PBVH_BMESH:
289 copy_v3_v3(r_co, SCULPT_vertex_co_get(ss, vertex));
290 break;
291 case PBVH_GRIDS: {
292 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
293 const int grid_index = vertex.i / key->grid_area;
294 const int index_in_grid = vertex.i - grid_index * key->grid_area;
296 SubdivCCGCoord coord{};
297 coord.grid_index = grid_index;
298 coord.x = index_in_grid % key->grid_size;
299 coord.y = index_in_grid / key->grid_size;
300 BKE_subdiv_ccg_eval_limit_point(*ss->subdiv_ccg, coord, r_co);
301 break;
306 void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3])
308 if (ss->attrs.persistent_no) {
309 copy_v3_v3(no, (float *)SCULPT_vertex_attr_get(vertex, ss->attrs.persistent_no));
310 return;
312 SCULPT_vertex_normal_get(ss, vertex, no);
315 float SCULPT_mask_get_at_grids_vert_index(const SubdivCCG &subdiv_ccg,
316 const CCGKey &key,
317 const int vert_index)
319 if (key.mask_offset == -1) {
320 return 0.0f;
322 const int grid_index = vert_index / key.grid_area;
323 const int index_in_grid = vert_index - grid_index * key.grid_area;
324 CCGElem *elem = subdiv_ccg.grids[grid_index];
325 return *CCG_elem_offset_mask(&key, elem, index_in_grid);
328 PBVHVertRef SCULPT_active_vertex_get(SculptSession *ss)
330 if (ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) {
331 return ss->active_vertex;
334 return BKE_pbvh_make_vref(PBVH_REF_NONE);
337 const float *SCULPT_active_vertex_co_get(SculptSession *ss)
339 return SCULPT_vertex_co_get(ss, SCULPT_active_vertex_get(ss));
342 MutableSpan<float3> SCULPT_mesh_deformed_positions_get(SculptSession *ss)
344 switch (BKE_pbvh_type(ss->pbvh)) {
345 case PBVH_FACES:
346 if (ss->shapekey_active || ss->deform_modifiers_active) {
347 return BKE_pbvh_get_vert_positions(ss->pbvh);
349 return ss->vert_positions;
350 case PBVH_BMESH:
351 case PBVH_GRIDS:
352 return {};
354 return {};
357 float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss,
358 const int deform_target,
359 PBVHVertexIter *iter)
361 switch (deform_target) {
362 case BRUSH_DEFORM_TARGET_GEOMETRY:
363 return iter->co;
364 case BRUSH_DEFORM_TARGET_CLOTH_SIM:
365 return ss->cache->cloth_sim->deformation_pos[iter->index];
367 return iter->co;
370 ePaintSymmetryFlags SCULPT_mesh_symmetry_xyz_get(Object *object)
372 const Mesh *mesh = BKE_mesh_from_object(object);
373 return ePaintSymmetryFlags(mesh->symmetry);
376 /* Sculpt Face Sets and Visibility. */
378 namespace blender::ed::sculpt_paint {
380 namespace face_set {
382 int active_face_set_get(const SculptSession *ss)
384 switch (BKE_pbvh_type(ss->pbvh)) {
385 case PBVH_FACES:
386 if (!ss->face_sets) {
387 return SCULPT_FACE_SET_NONE;
389 return ss->face_sets[ss->active_face_index];
390 case PBVH_GRIDS: {
391 if (!ss->face_sets) {
392 return SCULPT_FACE_SET_NONE;
394 const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss->subdiv_ccg,
395 ss->active_grid_index);
396 return ss->face_sets[face_index];
398 case PBVH_BMESH:
399 return SCULPT_FACE_SET_NONE;
401 return SCULPT_FACE_SET_NONE;
404 } // namespace face_set
406 namespace hide {
408 bool vert_visible_get(const SculptSession *ss, PBVHVertRef vertex)
410 switch (BKE_pbvh_type(ss->pbvh)) {
411 case PBVH_FACES: {
412 const Mesh *mesh = BKE_pbvh_get_mesh(ss->pbvh);
413 const bke::AttributeAccessor attributes = mesh->attributes();
414 const VArray hide_vert = *attributes.lookup_or_default<bool>(
415 ".hide_vert", bke::AttrDomain::Point, false);
416 return !hide_vert[vertex.i];
418 case PBVH_BMESH:
419 return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN);
420 case PBVH_GRIDS: {
421 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
422 const int grid_index = vertex.i / key->grid_area;
423 const int index_in_grid = vertex.i - grid_index * key->grid_area;
424 if (!ss->subdiv_ccg->grid_hidden.is_empty()) {
425 return !ss->subdiv_ccg->grid_hidden[grid_index][index_in_grid];
429 return true;
432 bool vert_any_face_visible_get(const SculptSession *ss, PBVHVertRef vertex)
434 switch (BKE_pbvh_type(ss->pbvh)) {
435 case PBVH_FACES: {
436 if (!ss->hide_poly) {
437 return true;
439 for (const int face : ss->vert_to_face_map[vertex.i]) {
440 if (!ss->hide_poly[face]) {
441 return true;
444 return false;
446 case PBVH_BMESH:
447 return true;
448 case PBVH_GRIDS:
449 return true;
451 return true;
454 bool vert_all_faces_visible_get(const SculptSession *ss, PBVHVertRef vertex)
456 switch (BKE_pbvh_type(ss->pbvh)) {
457 case PBVH_FACES: {
458 if (!ss->hide_poly) {
459 return true;
461 for (const int face : ss->vert_to_face_map[vertex.i]) {
462 if (ss->hide_poly[face]) {
463 return false;
466 return true;
468 case PBVH_BMESH: {
469 BMVert *v = (BMVert *)vertex.i;
470 BMEdge *e = v->e;
472 if (!e) {
473 return true;
476 do {
477 BMLoop *l = e->l;
479 if (!l) {
480 continue;
483 do {
484 if (BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) {
485 return false;
487 } while ((l = l->radial_next) != e->l);
488 } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
490 return true;
492 case PBVH_GRIDS: {
493 if (!ss->hide_poly) {
494 return true;
496 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
497 const int grid_index = vertex.i / key->grid_area;
498 const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss->subdiv_ccg, grid_index);
499 return !ss->hide_poly[face_index];
502 return true;
505 } // namespace hide
507 namespace face_set {
509 int vert_face_set_get(const SculptSession *ss, PBVHVertRef vertex)
511 switch (BKE_pbvh_type(ss->pbvh)) {
512 case PBVH_FACES: {
513 if (!ss->face_sets) {
514 return SCULPT_FACE_SET_NONE;
516 int face_set = 0;
517 for (const int face_index : ss->vert_to_face_map[vertex.i]) {
518 if (ss->face_sets[face_index] > face_set) {
519 face_set = ss->face_sets[face_index];
522 return face_set;
524 case PBVH_BMESH:
525 return 0;
526 case PBVH_GRIDS: {
527 if (!ss->face_sets) {
528 return SCULPT_FACE_SET_NONE;
530 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
531 const int grid_index = vertex.i / key->grid_area;
532 const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss->subdiv_ccg, grid_index);
533 return ss->face_sets[face_index];
536 return 0;
539 bool vert_has_face_set(const SculptSession *ss, PBVHVertRef vertex, int face_set)
541 switch (BKE_pbvh_type(ss->pbvh)) {
542 case PBVH_FACES: {
543 if (!ss->face_sets) {
544 return face_set == SCULPT_FACE_SET_NONE;
546 for (const int face_index : ss->vert_to_face_map[vertex.i]) {
547 if (ss->face_sets[face_index] == face_set) {
548 return true;
551 return false;
553 case PBVH_BMESH:
554 return true;
555 case PBVH_GRIDS: {
556 if (!ss->face_sets) {
557 return face_set == SCULPT_FACE_SET_NONE;
559 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
560 const int grid_index = vertex.i / key->grid_area;
561 const int face_index = BKE_subdiv_ccg_grid_to_face_index(*ss->subdiv_ccg, grid_index);
562 return ss->face_sets[face_index] == face_set;
565 return true;
568 static bool sculpt_check_unique_face_set_in_base_mesh(const SculptSession *ss, int index)
570 if (!ss->face_sets) {
571 return true;
573 int face_set = -1;
574 for (const int face_index : ss->vert_to_face_map[index]) {
575 if (face_set == -1) {
576 face_set = ss->face_sets[face_index];
578 else {
579 if (ss->face_sets[face_index] != face_set) {
580 return false;
584 return true;
588 * Checks if the face sets of the adjacent faces to the edge between \a v1 and \a v2
589 * in the base mesh are equal.
591 static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(const SculptSession *ss,
592 int v1,
593 int v2)
595 const Span<int> vert_map = ss->vert_to_face_map[v1];
596 int p1 = -1, p2 = -1;
597 for (int i = 0; i < vert_map.size(); i++) {
598 const int face_i = vert_map[i];
599 for (const int corner : ss->faces[face_i]) {
600 if (ss->corner_verts[corner] == v2) {
601 if (p1 == -1) {
602 p1 = vert_map[i];
603 break;
606 if (p2 == -1) {
607 p2 = vert_map[i];
608 break;
614 if (p1 != -1 && p2 != -1) {
615 return ss->face_sets[p1] == ss->face_sets[p2];
617 return true;
620 bool vert_has_unique_face_set(const SculptSession *ss, PBVHVertRef vertex)
622 switch (BKE_pbvh_type(ss->pbvh)) {
623 case PBVH_FACES: {
624 return sculpt_check_unique_face_set_in_base_mesh(ss, vertex.i);
626 case PBVH_BMESH:
627 return true;
628 case PBVH_GRIDS: {
629 if (!ss->face_sets) {
630 return true;
632 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
633 const int grid_index = vertex.i / key->grid_area;
634 const int index_in_grid = vertex.i - grid_index * key->grid_area;
635 SubdivCCGCoord coord{};
636 coord.grid_index = grid_index;
637 coord.x = index_in_grid % key->grid_size;
638 coord.y = index_in_grid / key->grid_size;
639 int v1, v2;
640 const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
641 *ss->subdiv_ccg, coord, ss->corner_verts, ss->faces, v1, v2);
642 switch (adjacency) {
643 case SUBDIV_CCG_ADJACENT_VERTEX:
644 return sculpt_check_unique_face_set_in_base_mesh(ss, v1);
645 case SUBDIV_CCG_ADJACENT_EDGE:
646 return sculpt_check_unique_face_set_for_edge_in_base_mesh(ss, v1, v2);
647 case SUBDIV_CCG_ADJACENT_NONE:
648 return true;
652 return false;
655 } // namespace face_set
657 /* Sculpt Neighbor Iterators */
659 #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256
661 static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter,
662 PBVHVertRef neighbor,
663 int neighbor_index)
665 for (int i = 0; i < iter->size; i++) {
666 if (iter->neighbors[i].i == neighbor.i) {
667 return;
671 if (iter->size >= iter->capacity) {
672 iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
674 if (iter->neighbors == iter->neighbors_fixed) {
675 iter->neighbors = static_cast<PBVHVertRef *>(
676 MEM_mallocN(iter->capacity * sizeof(PBVHVertRef), "neighbor array"));
677 memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(PBVHVertRef) * iter->size);
679 else {
680 iter->neighbors = static_cast<PBVHVertRef *>(MEM_reallocN_id(
681 iter->neighbors, iter->capacity * sizeof(PBVHVertRef), "neighbor array"));
684 if (iter->neighbor_indices == iter->neighbor_indices_fixed) {
685 iter->neighbor_indices = static_cast<int *>(
686 MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"));
687 memcpy(iter->neighbor_indices, iter->neighbor_indices_fixed, sizeof(int) * iter->size);
689 else {
690 iter->neighbor_indices = static_cast<int *>(
691 MEM_reallocN_id(iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array"));
695 iter->neighbors[iter->size] = neighbor;
696 iter->neighbor_indices[iter->size] = neighbor_index;
697 iter->size++;
700 static void sculpt_vertex_neighbors_get_bmesh(PBVHVertRef vertex, SculptVertexNeighborIter *iter)
702 BMVert *v = (BMVert *)vertex.i;
703 BMIter liter;
704 BMLoop *l;
705 iter->size = 0;
706 iter->num_duplicates = 0;
707 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
708 iter->neighbors = iter->neighbors_fixed;
709 iter->neighbor_indices = iter->neighbor_indices_fixed;
711 BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
712 const BMVert *adj_v[2] = {l->prev->v, l->next->v};
713 for (int i = 0; i < ARRAY_SIZE(adj_v); i++) {
714 const BMVert *v_other = adj_v[i];
715 if (v_other != v) {
716 sculpt_vertex_neighbor_add(
717 iter, BKE_pbvh_make_vref(intptr_t(v_other)), BM_elem_index_get(v_other));
723 static void sculpt_vertex_neighbors_get_faces(const SculptSession *ss,
724 PBVHVertRef vertex,
725 SculptVertexNeighborIter *iter)
727 iter->size = 0;
728 iter->num_duplicates = 0;
729 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
730 iter->neighbors = iter->neighbors_fixed;
731 iter->neighbor_indices = iter->neighbor_indices_fixed;
733 for (const int face_i : ss->vert_to_face_map[vertex.i]) {
734 if (ss->hide_poly && ss->hide_poly[face_i]) {
735 /* Skip connectivity from hidden faces. */
736 continue;
738 const IndexRange face = ss->faces[face_i];
739 const int2 f_adj_v = bke::mesh::face_find_adjacent_verts(face, ss->corner_verts, vertex.i);
740 for (int j = 0; j < 2; j++) {
741 if (f_adj_v[j] != vertex.i) {
742 sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(f_adj_v[j]), f_adj_v[j]);
747 if (ss->fake_neighbors.use_fake_neighbors) {
748 BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr);
749 if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) {
750 sculpt_vertex_neighbor_add(
751 iter,
752 BKE_pbvh_make_vref(ss->fake_neighbors.fake_neighbor_index[vertex.i]),
753 ss->fake_neighbors.fake_neighbor_index[vertex.i]);
758 static void sculpt_vertex_neighbors_get_grids(const SculptSession *ss,
759 const PBVHVertRef vertex,
760 const bool include_duplicates,
761 SculptVertexNeighborIter *iter)
763 /* TODO: optimize this. We could fill #SculptVertexNeighborIter directly,
764 * maybe provide coordinate and mask pointers directly rather than converting
765 * back and forth between #CCGElem and global index. */
766 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
767 const int grid_index = vertex.i / key->grid_area;
768 const int index_in_grid = vertex.i - grid_index * key->grid_area;
770 SubdivCCGCoord coord{};
771 coord.grid_index = grid_index;
772 coord.x = index_in_grid % key->grid_size;
773 coord.y = index_in_grid / key->grid_size;
775 SubdivCCGNeighbors neighbors;
776 BKE_subdiv_ccg_neighbor_coords_get(*ss->subdiv_ccg, coord, include_duplicates, neighbors);
778 iter->size = 0;
779 iter->num_duplicates = neighbors.num_duplicates;
780 iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY;
781 iter->neighbors = iter->neighbors_fixed;
782 iter->neighbor_indices = iter->neighbor_indices_fixed;
784 for (const int i : neighbors.coords.index_range()) {
785 int v = neighbors.coords[i].grid_index * key->grid_area +
786 neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x;
788 sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v);
791 if (ss->fake_neighbors.use_fake_neighbors) {
792 BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr);
793 if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) {
794 int v = ss->fake_neighbors.fake_neighbor_index[vertex.i];
795 sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v);
800 } // namespace blender::ed::sculpt_paint
802 void SCULPT_vertex_neighbors_get(const SculptSession *ss,
803 const PBVHVertRef vertex,
804 const bool include_duplicates,
805 SculptVertexNeighborIter *iter)
807 using namespace blender::ed::sculpt_paint;
808 switch (BKE_pbvh_type(ss->pbvh)) {
809 case PBVH_FACES:
810 sculpt_vertex_neighbors_get_faces(ss, vertex, iter);
811 return;
812 case PBVH_BMESH:
813 sculpt_vertex_neighbors_get_bmesh(vertex, iter);
814 return;
815 case PBVH_GRIDS:
816 sculpt_vertex_neighbors_get_grids(ss, vertex, include_duplicates, iter);
817 return;
821 static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss, const int index)
823 return ss->vertex_info.boundary[index];
826 bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex)
828 using namespace blender::ed::sculpt_paint;
829 switch (BKE_pbvh_type(ss->pbvh)) {
830 case PBVH_FACES: {
831 if (!hide::vert_all_faces_visible_get(ss, vertex)) {
832 return true;
834 return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex.i);
836 case PBVH_BMESH: {
837 BMVert *v = (BMVert *)vertex.i;
838 return BM_vert_is_boundary(v);
840 case PBVH_GRIDS: {
841 const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
842 const int grid_index = vertex.i / key->grid_area;
843 const int index_in_grid = vertex.i - grid_index * key->grid_area;
844 SubdivCCGCoord coord{};
845 coord.grid_index = grid_index;
846 coord.x = index_in_grid % key->grid_size;
847 coord.y = index_in_grid / key->grid_size;
848 int v1, v2;
849 const SubdivCCGAdjacencyType adjacency = BKE_subdiv_ccg_coarse_mesh_adjacency_info_get(
850 *ss->subdiv_ccg, coord, ss->corner_verts, ss->faces, v1, v2);
851 switch (adjacency) {
852 case SUBDIV_CCG_ADJACENT_VERTEX:
853 return sculpt_check_boundary_vertex_in_base_mesh(ss, v1);
854 case SUBDIV_CCG_ADJACENT_EDGE:
855 return sculpt_check_boundary_vertex_in_base_mesh(ss, v1) &&
856 sculpt_check_boundary_vertex_in_base_mesh(ss, v2);
857 case SUBDIV_CCG_ADJACENT_NONE:
858 return false;
863 return false;
866 /* Utilities */
868 bool SCULPT_stroke_is_main_symmetry_pass(blender::ed::sculpt_paint::StrokeCache *cache)
870 return cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
871 cache->tile_pass == 0;
874 bool SCULPT_stroke_is_first_brush_step(blender::ed::sculpt_paint::StrokeCache *cache)
876 return cache->first_time && cache->mirror_symmetry_pass == 0 &&
877 cache->radial_symmetry_pass == 0 && cache->tile_pass == 0;
880 bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(
881 blender::ed::sculpt_paint::StrokeCache *cache)
883 return cache->first_time;
886 bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
888 bool is_in_symmetry_area = true;
889 for (int i = 0; i < 3; i++) {
890 char symm_it = 1 << i;
891 if (symm & symm_it) {
892 if (pco[i] == 0.0f) {
893 if (vco[i] > 0.0f) {
894 is_in_symmetry_area = false;
897 if (vco[i] * pco[i] < 0.0f) {
898 is_in_symmetry_area = false;
902 return is_in_symmetry_area;
905 struct NearestVertexData {
906 PBVHVertRef nearest_vertex;
907 float nearest_vertex_distance_sq;
910 static void nearest_vertex_get_node(PBVH *pbvh,
911 const float nearest_vertex_search_co[3],
912 const float max_distance_sq,
913 PBVHNode *node,
914 NearestVertexData *nvtd)
916 PBVHVertexIter vd;
917 BKE_pbvh_vertex_iter_begin (pbvh, node, vd, PBVH_ITER_UNIQUE) {
918 float distance_squared = len_squared_v3v3(vd.co, nearest_vertex_search_co);
919 if (distance_squared < nvtd->nearest_vertex_distance_sq && distance_squared < max_distance_sq)
921 nvtd->nearest_vertex = vd.vertex;
922 nvtd->nearest_vertex_distance_sq = distance_squared;
925 BKE_pbvh_vertex_iter_end;
928 PBVHVertRef SCULPT_nearest_vertex_get(Object *ob,
929 const float co[3],
930 float max_distance,
931 bool use_original)
933 using namespace blender;
934 using namespace blender::ed::sculpt_paint;
935 SculptSession *ss = ob->sculpt;
937 const float max_distance_sq = max_distance * max_distance;
939 Vector<PBVHNode *> nodes = bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
940 return node_in_sphere(node, co, max_distance_sq, use_original);
942 if (nodes.is_empty()) {
943 return BKE_pbvh_make_vref(PBVH_REF_NONE);
946 return threading::parallel_reduce(
947 nodes.index_range(),
949 NearestVertexData{{PBVH_REF_NONE}, FLT_MAX},
950 [&](const IndexRange range, NearestVertexData nearest) {
951 for (const int i : range) {
952 nearest_vertex_get_node(ss->pbvh, co, max_distance_sq, nodes[i], &nearest);
954 return nearest;
956 [](const NearestVertexData a, const NearestVertexData b) {
957 return a.nearest_vertex_distance_sq < b.nearest_vertex_distance_sq ? a : b;
959 .nearest_vertex;
962 bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
964 return i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || !ELEM(i, 3, 5)));
967 bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3],
968 const float br_co[3],
969 float radius,
970 char symm)
972 for (char i = 0; i <= symm; ++i) {
973 if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
974 continue;
976 float location[3];
977 flip_v3_v3(location, br_co, ePaintSymmetryFlags(i));
978 if (len_squared_v3v3(location, vertex) < radius * radius) {
979 return true;
982 return false;
985 void SCULPT_tag_update_overlays(bContext *C)
987 ARegion *region = CTX_wm_region(C);
988 ED_region_tag_redraw(region);
990 Object *ob = CTX_data_active_object(C);
991 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
993 DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
995 RegionView3D *rv3d = CTX_wm_region_view3d(C);
996 if (!BKE_sculptsession_use_pbvh_draw(ob, rv3d)) {
997 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
1001 /** \} */
1003 /* -------------------------------------------------------------------- */
1004 /** \name Sculpt Flood Fill API
1006 * Iterate over connected vertices, starting from one or more initial vertices.
1007 * \{ */
1009 namespace blender::ed::sculpt_paint {
1011 namespace flood_fill {
1013 FillData init_fill(SculptSession *ss)
1015 SCULPT_vertex_random_access_ensure(ss);
1016 FillData data;
1017 data.visited_verts.resize(SCULPT_vertex_count_get(ss));
1018 return data;
1021 void add_initial(FillData *flood, PBVHVertRef vertex)
1023 flood->queue.push(vertex);
1026 void add_and_skip_initial(FillData *flood, PBVHVertRef vertex)
1028 flood->queue.push(vertex);
1029 flood->visited_verts[vertex.i].set(vertex.i);
1032 void add_initial_with_symmetry(
1033 Object *ob, SculptSession *ss, FillData *flood, PBVHVertRef vertex, float radius)
1035 /* Add active vertex and symmetric vertices to the queue. */
1036 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1037 for (char i = 0; i <= symm; ++i) {
1038 if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
1039 continue;
1041 PBVHVertRef v = {PBVH_REF_NONE};
1043 if (i == 0) {
1044 v = vertex;
1046 else if (radius > 0.0f) {
1047 float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius;
1048 float location[3];
1049 flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), ePaintSymmetryFlags(i));
1050 v = SCULPT_nearest_vertex_get(ob, location, radius_squared, false);
1053 if (v.i != PBVH_REF_NONE) {
1054 add_initial(flood, v);
1059 void add_active(Object *ob, SculptSession *ss, FillData *flood, float radius)
1061 /* Add active vertex and symmetric vertices to the queue. */
1062 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
1063 for (char i = 0; i <= symm; ++i) {
1064 if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
1065 continue;
1068 PBVHVertRef v = {PBVH_REF_NONE};
1070 if (i == 0) {
1071 v = SCULPT_active_vertex_get(ss);
1073 else if (radius > 0.0f) {
1074 float location[3];
1075 flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), ePaintSymmetryFlags(i));
1076 v = SCULPT_nearest_vertex_get(ob, location, radius, false);
1079 if (v.i != PBVH_REF_NONE) {
1080 add_initial(flood, v);
1085 void execute(SculptSession *ss,
1086 FillData *flood,
1087 FunctionRef<bool(PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate)> func)
1089 while (!flood->queue.empty()) {
1090 PBVHVertRef from_v = flood->queue.front();
1091 flood->queue.pop();
1093 SculptVertexNeighborIter ni;
1094 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
1095 const PBVHVertRef to_v = ni.vertex;
1096 int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v);
1098 if (flood->visited_verts[to_v_i]) {
1099 continue;
1102 if (!hide::vert_visible_get(ss, to_v)) {
1103 continue;
1106 flood->visited_verts[BKE_pbvh_vertex_to_index(ss->pbvh, to_v)].set();
1108 if (func(from_v, to_v, ni.is_duplicate)) {
1109 flood->queue.push(to_v);
1112 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
1116 } // namespace flood_fill
1118 /** \} */
1120 /* -------------------------------------------------------------------- */
1121 /** \name Tool Capabilities
1123 * Avoid duplicate checks, internal logic only,
1124 * share logic with #rna_def_sculpt_capabilities where possible.
1125 * \{ */
1127 static bool sculpt_tool_needs_original(const char sculpt_tool)
1129 return ELEM(sculpt_tool,
1130 SCULPT_TOOL_GRAB,
1131 SCULPT_TOOL_ROTATE,
1132 SCULPT_TOOL_THUMB,
1133 SCULPT_TOOL_LAYER,
1134 SCULPT_TOOL_DRAW_SHARP,
1135 SCULPT_TOOL_ELASTIC_DEFORM,
1136 SCULPT_TOOL_SMOOTH,
1137 SCULPT_TOOL_BOUNDARY,
1138 SCULPT_TOOL_POSE);
1141 static bool sculpt_tool_is_proxy_used(const char sculpt_tool)
1143 return ELEM(sculpt_tool,
1144 SCULPT_TOOL_SMOOTH,
1145 SCULPT_TOOL_LAYER,
1146 SCULPT_TOOL_POSE,
1147 SCULPT_TOOL_DISPLACEMENT_SMEAR,
1148 SCULPT_TOOL_BOUNDARY,
1149 SCULPT_TOOL_CLOTH,
1150 SCULPT_TOOL_PAINT,
1151 SCULPT_TOOL_SMEAR,
1152 SCULPT_TOOL_DRAW_FACE_SETS);
1155 static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush *brush)
1157 return SCULPT_TOOL_HAS_TOPOLOGY_RAKE(brush->sculpt_tool) &&
1158 (brush->topology_rake_factor > 0.0f) && (ss->bm != nullptr);
1162 * Test whether the #StrokeCache.sculpt_normal needs update in #do_brush_action
1164 static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const Brush *brush)
1166 using namespace blender::ed::sculpt_paint;
1167 const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
1168 return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) &&
1169 (ss->cache->normal_weight > 0.0f)) ||
1170 auto_mask::needs_normal(ss, sd, brush) ||
1171 ELEM(brush->sculpt_tool,
1172 SCULPT_TOOL_BLOB,
1173 SCULPT_TOOL_CREASE,
1174 SCULPT_TOOL_DRAW,
1175 SCULPT_TOOL_DRAW_SHARP,
1176 SCULPT_TOOL_CLOTH,
1177 SCULPT_TOOL_LAYER,
1178 SCULPT_TOOL_NUDGE,
1179 SCULPT_TOOL_ROTATE,
1180 SCULPT_TOOL_ELASTIC_DEFORM,
1181 SCULPT_TOOL_THUMB) ||
1183 (mask_tex->brush_map_mode == MTEX_MAP_MODE_AREA)) ||
1184 sculpt_brush_use_topology_rake(ss, brush) ||
1185 BKE_brush_has_cube_tip(brush, PaintMode::Sculpt);
1188 static bool sculpt_brush_needs_rake_rotation(const Brush *brush)
1190 return SCULPT_TOOL_HAS_RAKE(brush->sculpt_tool) && (brush->rake_factor != 0.0f);
1193 } // namespace blender::ed::sculpt_paint
1195 /** \} */
1197 /* -------------------------------------------------------------------- */
1198 /** \name Sculpt Init/Update
1199 * \{ */
1201 enum StrokeFlags {
1202 CLIP_X = 1,
1203 CLIP_Y = 2,
1204 CLIP_Z = 4,
1207 void SCULPT_orig_vert_data_unode_init(SculptOrigVertData *data,
1208 Object *ob,
1209 blender::ed::sculpt_paint::undo::Node *unode)
1211 SculptSession *ss = ob->sculpt;
1212 BMesh *bm = ss->bm;
1214 memset(data, 0, sizeof(*data));
1215 data->unode = unode;
1217 if (bm) {
1218 data->bm_log = ss->bm_log;
1220 else {
1221 data->coords = reinterpret_cast<float(*)[3]>(data->unode->position.data());
1222 data->normals = reinterpret_cast<float(*)[3]>(data->unode->normal.data());
1223 data->vmasks = data->unode->mask.data();
1224 data->colors = reinterpret_cast<float(*)[4]>(data->unode->col.data());
1228 void SCULPT_orig_vert_data_init(SculptOrigVertData *data,
1229 Object *ob,
1230 PBVHNode *node,
1231 blender::ed::sculpt_paint::undo::Type type)
1233 using namespace blender::ed::sculpt_paint;
1234 undo::Node *unode = undo::push_node(*ob, node, type);
1235 SCULPT_orig_vert_data_unode_init(data, ob, unode);
1238 void SCULPT_orig_vert_data_update(SculptOrigVertData *orig_data, PBVHVertexIter *iter)
1240 using namespace blender::ed::sculpt_paint;
1241 if (orig_data->unode->type == undo::Type::Position) {
1242 if (orig_data->bm_log) {
1243 BM_log_original_vert_data(orig_data->bm_log, iter->bm_vert, &orig_data->co, &orig_data->no);
1245 else {
1246 orig_data->co = orig_data->coords[iter->i];
1247 orig_data->no = orig_data->normals[iter->i];
1250 else if (orig_data->unode->type == undo::Type::Color) {
1251 orig_data->col = orig_data->colors[iter->i];
1253 else if (orig_data->unode->type == undo::Type::Mask) {
1254 if (orig_data->bm_log) {
1255 orig_data->mask = BM_log_original_mask(orig_data->bm_log, iter->bm_vert);
1257 else {
1258 orig_data->mask = orig_data->vmasks[iter->i];
1263 namespace blender::ed::sculpt_paint {
1265 static void sculpt_rake_data_update(SculptRakeData *srd, const float co[3])
1267 float rake_dist = len_v3v3(srd->follow_co, co);
1268 if (rake_dist > srd->follow_dist) {
1269 interp_v3_v3v3(srd->follow_co, srd->follow_co, co, rake_dist - srd->follow_dist);
1273 /** \} */
1275 /* -------------------------------------------------------------------- */
1276 /** \name Sculpt Dynamic Topology
1277 * \{ */
1279 namespace dyntopo {
1281 bool stroke_is_dyntopo(const SculptSession *ss, const Brush *brush)
1283 return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
1285 (!ss->cache || (!ss->cache->alt_smooth)) &&
1287 /* Requires mesh restore, which doesn't work with
1288 * dynamic-topology. */
1289 !(brush->flag & BRUSH_ANCHORED) && !(brush->flag & BRUSH_DRAG_DOT) &&
1291 SCULPT_TOOL_HAS_DYNTOPO(brush->sculpt_tool));
1294 } // namespace dyntopo
1296 /** \} */
1298 /* -------------------------------------------------------------------- */
1299 /** \name Sculpt Paint Mesh
1300 * \{ */
1302 static void restore_mask(Object &object, const Span<PBVHNode *> nodes)
1304 SculptSession *ss = object.sculpt;
1305 switch (BKE_pbvh_type(ss->pbvh)) {
1306 case PBVH_FACES: {
1307 Mesh &mesh = *static_cast<Mesh *>(object.data);
1308 bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
1309 bke::SpanAttributeWriter<float> mask = attributes.lookup_or_add_for_write_span<float>(
1310 ".sculpt_mask", bke::AttrDomain::Point);
1311 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1312 for (PBVHNode *node : nodes.slice(range)) {
1313 if (undo::Node *unode = undo::get_node(node, undo::Type::Mask)) {
1314 const Span<int> verts = bke::pbvh::node_unique_verts(*node);
1315 array_utils::scatter(unode->mask.as_span(), verts, mask.span);
1316 BKE_pbvh_node_mark_update_mask(node);
1320 mask.finish();
1321 break;
1323 case PBVH_BMESH: {
1324 const int offset = CustomData_get_offset_named(
1325 &ss->bm->vdata, CD_PROP_FLOAT, ".sculpt_mask");
1326 if (offset != -1) {
1327 for (PBVHNode *node : nodes) {
1328 if (undo::push_node(object, node, undo::Type::Mask)) {
1329 for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
1330 const float orig_mask = BM_log_original_mask(ss->bm_log, vert);
1331 BM_ELEM_CD_SET_FLOAT(vert, offset, orig_mask);
1333 BKE_pbvh_node_mark_update_mask(node);
1337 break;
1339 case PBVH_GRIDS: {
1340 SubdivCCG &subdiv_ccg = *ss->subdiv_ccg;
1341 const BitGroupVector<> grid_hidden = subdiv_ccg.grid_hidden;
1342 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1343 const Span<CCGElem *> grids = subdiv_ccg.grids;
1344 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1345 for (PBVHNode *node : nodes.slice(range)) {
1346 if (undo::Node *unode = undo::get_node(node, undo::Type::Mask)) {
1347 int index = 0;
1348 for (const int grid : unode->grids) {
1349 CCGElem *elem = grids[grid];
1350 for (const int i : IndexRange(key.grid_area)) {
1351 if (grid_hidden.is_empty() || !grid_hidden[grid][i]) {
1352 *CCG_elem_offset_mask(&key, elem, i) = unode->mask[index];
1354 index++;
1357 BKE_pbvh_node_mark_update_mask(node);
1361 break;
1366 static void restore_color(Object &object, const Span<PBVHNode *> nodes)
1368 SculptSession *ss = object.sculpt;
1369 const auto restore_generic = [&](PBVHNode *node, undo::Node *unode) {
1370 SculptOrigVertData orig_vert_data;
1371 SCULPT_orig_vert_data_unode_init(&orig_vert_data, &object, unode);
1372 PBVHVertexIter vd;
1373 BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
1374 SCULPT_orig_vert_data_update(&orig_vert_data, &vd);
1375 SCULPT_vertex_color_set(ss, vd.vertex, orig_vert_data.col);
1377 BKE_pbvh_vertex_iter_end;
1378 BKE_pbvh_node_mark_update_color(node);
1380 switch (BKE_pbvh_type(ss->pbvh)) {
1381 case PBVH_FACES: {
1382 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1383 for (PBVHNode *node : nodes.slice(range)) {
1384 if (undo::Node *unode = undo::get_node(node, undo::Type::Color)) {
1385 restore_generic(node, unode);
1389 break;
1391 case PBVH_BMESH: {
1392 for (PBVHNode *node : nodes) {
1393 if (undo::Node *unode = undo::push_node(object, node, undo::Type::Color)) {
1394 restore_generic(node, unode);
1397 break;
1399 case PBVH_GRIDS: {
1400 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1401 for (PBVHNode *node : nodes.slice(range)) {
1402 if (undo::Node *unode = undo::get_node(node, undo::Type::Color)) {
1403 restore_generic(node, unode);
1407 break;
1412 static void restore_face_set(Object &object, const Span<PBVHNode *> nodes)
1414 SculptSession *ss = object.sculpt;
1415 switch (BKE_pbvh_type(ss->pbvh)) {
1416 case PBVH_FACES:
1417 case PBVH_GRIDS: {
1418 bke::SpanAttributeWriter<int> attribute = face_set::ensure_face_sets_mesh(object);
1419 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1420 for (PBVHNode *node : nodes.slice(range)) {
1421 if (undo::Node *unode = undo::get_node(node, undo::Type::FaceSet)) {
1422 const Span<int> faces = unode->face_indices;
1423 const Span<int> face_sets = unode->face_sets;
1424 blender::array_utils::scatter(face_sets, faces, attribute.span);
1425 BKE_pbvh_node_mark_update_face_sets(node);
1429 attribute.finish();
1430 break;
1432 case PBVH_BMESH:
1433 break;
1437 static void restore_position(Object &object, const Span<PBVHNode *> nodes)
1439 SculptSession *ss = object.sculpt;
1440 switch (BKE_pbvh_type(ss->pbvh)) {
1441 case PBVH_FACES: {
1442 MutableSpan positions = BKE_pbvh_get_vert_positions(ss->pbvh);
1443 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1444 for (PBVHNode *node : nodes.slice(range)) {
1445 if (undo::Node *unode = undo::get_node(node, undo::Type::Position)) {
1446 const Span<int> verts = bke::pbvh::node_unique_verts(*node);
1447 array_utils::scatter(unode->position.as_span(), verts, positions);
1448 BKE_pbvh_node_mark_positions_update(node);
1452 break;
1454 case PBVH_BMESH: {
1455 for (PBVHNode *node : nodes) {
1456 if (undo::push_node(object, node, undo::Type::Position)) {
1457 for (BMVert *vert : BKE_pbvh_bmesh_node_unique_verts(node)) {
1458 copy_v3_v3(vert->co, BM_log_original_vert_co(ss->bm_log, vert));
1460 BKE_pbvh_node_mark_positions_update(node);
1463 break;
1465 case PBVH_GRIDS: {
1466 SubdivCCG &subdiv_ccg = *ss->subdiv_ccg;
1467 const BitGroupVector<> grid_hidden = subdiv_ccg.grid_hidden;
1468 const CCGKey key = BKE_subdiv_ccg_key_top_level(subdiv_ccg);
1469 const Span<CCGElem *> grids = subdiv_ccg.grids;
1470 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
1471 for (PBVHNode *node : nodes.slice(range)) {
1472 if (undo::Node *unode = undo::get_node(node, undo::Type::Position)) {
1473 int index = 0;
1474 for (const int grid : unode->grids) {
1475 CCGElem *elem = grids[grid];
1476 for (const int i : IndexRange(key.grid_area)) {
1477 if (grid_hidden.is_empty() || !grid_hidden[grid][i]) {
1478 copy_v3_v3(CCG_elem_offset_co(&key, elem, i), unode->position[index]);
1480 index++;
1483 BKE_pbvh_node_mark_positions_update(node);
1487 break;
1491 /* Update normals for potentially-changed positions. Theoretically this may be unnecessary if
1492 * the tool restoring to the initial state doesn't use the normals, but we have no easy way to
1493 * know that from here. */
1494 bke::pbvh::update_normals(*ss->pbvh, ss->subdiv_ccg);
1497 static void restore_from_undo_step(const Sculpt &sd, Object &object)
1499 SculptSession *ss = object.sculpt;
1500 const Brush *brush = BKE_paint_brush_for_read(&sd.paint);
1502 Vector<PBVHNode *> nodes = bke::pbvh::search_gather(ss->pbvh, {});
1504 switch (brush->sculpt_tool) {
1505 case SCULPT_TOOL_MASK:
1506 restore_mask(object, nodes);
1507 break;
1508 case SCULPT_TOOL_PAINT:
1509 case SCULPT_TOOL_SMEAR:
1510 restore_color(object, nodes);
1511 break;
1512 case SCULPT_TOOL_DRAW_FACE_SETS:
1513 if (ss->cache->alt_smooth) {
1514 restore_position(object, nodes);
1516 else {
1517 restore_face_set(object, nodes);
1519 break;
1520 default:
1521 restore_position(object, nodes);
1522 break;
1524 /* Disable multi-threading when dynamic-topology is enabled. Otherwise,
1525 * new entries might be inserted by #undo::push_node() into the #GHash
1526 * used internally by #BM_log_original_vert_co() by a different thread. See #33787. */
1528 BKE_pbvh_node_color_buffer_free(ss->pbvh);
1531 } // namespace blender::ed::sculpt_paint
1533 /*** BVH Tree ***/
1535 static void sculpt_extend_redraw_rect_previous(Object *ob, rcti *rect)
1537 /* Expand redraw \a rect with redraw \a rect from previous step to
1538 * prevent partial-redraw issues caused by fast strokes. This is
1539 * needed here (not in sculpt_flush_update) as it was before
1540 * because redraw rectangle should be the same in both of
1541 * optimized PBVH draw function and 3d view redraw, if not -- some
1542 * mesh parts could disappear from screen (sergey). */
1543 SculptSession *ss = ob->sculpt;
1545 if (!ss->cache) {
1546 return;
1549 if (BLI_rcti_is_empty(&ss->cache->previous_r)) {
1550 return;
1553 BLI_rcti_union(rect, &ss->cache->previous_r);
1556 bool SCULPT_get_redraw_rect(ARegion *region, RegionView3D *rv3d, Object *ob, rcti *rect)
1558 using namespace blender;
1559 PBVH *pbvh = ob->sculpt->pbvh;
1560 if (!pbvh) {
1561 return false;
1564 const Bounds<float3> bounds = BKE_pbvh_redraw_BB(pbvh);
1566 /* Convert 3D bounding box to screen space. */
1567 if (!paint_convert_bb_to_rect(rect, bounds.min, bounds.max, region, rv3d, ob)) {
1568 return false;
1571 return true;
1574 /************************ Brush Testing *******************/
1576 void SCULPT_brush_test_init(SculptSession *ss, SculptBrushTest *test)
1578 using namespace blender;
1579 RegionView3D *rv3d = ss->cache ? ss->cache->vc->rv3d : ss->rv3d;
1580 View3D *v3d = ss->cache ? ss->cache->vc->v3d : ss->v3d;
1582 test->radius_squared = ss->cache ? ss->cache->radius_squared :
1583 ss->cursor_radius * ss->cursor_radius;
1584 test->radius = std::sqrt(test->radius_squared);
1586 if (ss->cache) {
1587 test->location = ss->cache->location;
1588 test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass;
1589 test->radial_symmetry_pass = ss->cache->radial_symmetry_pass;
1590 test->symm_rot_mat_inv = ss->cache->symm_rot_mat_inv;
1592 else {
1593 test->location = ss->cursor_location;
1594 test->mirror_symmetry_pass = ePaintSymmetryFlags(0);
1595 test->radial_symmetry_pass = 0;
1597 test->symm_rot_mat_inv = float4x4::identity();
1600 /* Just for initialize. */
1601 test->dist = 0.0f;
1603 /* Only for 2D projection. */
1604 zero_v4(test->plane_view);
1605 zero_v4(test->plane_tool);
1607 if (RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
1608 test->clip_rv3d = rv3d;
1610 else {
1611 test->clip_rv3d = nullptr;
1615 BLI_INLINE bool sculpt_brush_test_clipping(const SculptBrushTest *test, const float co[3])
1617 RegionView3D *rv3d = test->clip_rv3d;
1618 if (!rv3d) {
1619 return false;
1621 float symm_co[3];
1622 flip_v3_v3(symm_co, co, test->mirror_symmetry_pass);
1623 if (test->radial_symmetry_pass) {
1624 mul_m4_v3(test->symm_rot_mat_inv.ptr(), symm_co);
1626 return ED_view3d_clipping_test(rv3d, symm_co, true);
1629 bool SCULPT_brush_test_sphere_sq(SculptBrushTest *test, const float co[3])
1631 float distsq = len_squared_v3v3(co, test->location);
1633 if (distsq > test->radius_squared) {
1634 return false;
1636 if (sculpt_brush_test_clipping(test, co)) {
1637 return false;
1639 test->dist = distsq;
1640 return true;
1643 bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3])
1645 float co_proj[3];
1646 closest_to_plane_normalized_v3(co_proj, test->plane_view, co);
1647 float distsq = len_squared_v3v3(co_proj, test->location);
1649 if (distsq > test->radius_squared) {
1650 return false;
1653 if (sculpt_brush_test_clipping(test, co)) {
1654 return false;
1657 test->dist = distsq;
1658 return true;
1661 bool SCULPT_brush_test_cube(SculptBrushTest *test,
1662 const float co[3],
1663 const float local[4][4],
1664 const float roundness,
1665 const float /*tip_scale_x*/)
1667 float side = 1.0f;
1668 float local_co[3];
1670 if (sculpt_brush_test_clipping(test, co)) {
1671 return false;
1674 mul_v3_m4v3(local_co, local, co);
1676 local_co[0] = fabsf(local_co[0]);
1677 local_co[1] = fabsf(local_co[1]);
1678 local_co[2] = fabsf(local_co[2]);
1680 /* Keep the square and circular brush tips the same size. */
1681 side += (1.0f - side) * roundness;
1683 const float hardness = 1.0f - roundness;
1684 const float constant_side = hardness * side;
1685 const float falloff_side = roundness * side;
1687 if (!(local_co[0] <= side && local_co[1] <= side && local_co[2] <= side)) {
1688 /* Outside the square. */
1689 return false;
1691 if (min_ff(local_co[0], local_co[1]) > constant_side) {
1692 /* Corner, distance to the center of the corner circle. */
1693 float r_point[3];
1694 copy_v3_fl(r_point, constant_side);
1695 test->dist = len_v2v2(r_point, local_co) / falloff_side;
1696 return true;
1698 if (max_ff(local_co[0], local_co[1]) > constant_side) {
1699 /* Side, distance to the square XY axis. */
1700 test->dist = (max_ff(local_co[0], local_co[1]) - constant_side) / falloff_side;
1701 return true;
1704 /* Inside the square, constant distance. */
1705 test->dist = 0.0f;
1706 return true;
1709 SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
1710 SculptBrushTest *test,
1711 char falloff_shape)
1713 if (!ss->cache && !ss->filter_cache) {
1714 falloff_shape = PAINT_FALLOFF_SHAPE_SPHERE;
1717 SCULPT_brush_test_init(ss, test);
1718 SculptBrushTestFn sculpt_brush_test_sq_fn;
1719 if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
1720 sculpt_brush_test_sq_fn = SCULPT_brush_test_sphere_sq;
1722 else {
1723 BLI_assert(falloff_shape == PAINT_FALLOFF_SHAPE_TUBE);
1724 const float3 view_normal = ss->cache ? ss->cache->view_normal : ss->filter_cache->view_normal;
1726 plane_from_point_normal_v3(test->plane_view, test->location, view_normal);
1727 sculpt_brush_test_sq_fn = SCULPT_brush_test_circle_sq;
1729 return sculpt_brush_test_sq_fn;
1732 const float *SCULPT_brush_frontface_normal_from_falloff_shape(SculptSession *ss,
1733 char falloff_shape)
1735 if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
1736 return ss->cache->sculpt_normal_symm;
1738 BLI_assert(falloff_shape == PAINT_FALLOFF_SHAPE_TUBE);
1739 return ss->cache->view_normal;
1742 static float frontface(const Brush &brush, const float3 &view_normal, const float3 &normal)
1744 using namespace blender;
1745 if (!(brush.flag & BRUSH_FRONTFACE)) {
1746 return 1.0f;
1748 return std::max(math::dot(normal, view_normal), 0.0f);
1751 #if 0
1753 static bool sculpt_brush_test_cyl(SculptBrushTest *test,
1754 float co[3],
1755 float location[3],
1756 const float area_no[3])
1758 if (sculpt_brush_test_sphere_fast(test, co)) {
1759 float t1[3], t2[3], t3[3], dist;
1761 sub_v3_v3v3(t1, location, co);
1762 sub_v3_v3v3(t2, x2, location);
1764 cross_v3_v3v3(t3, area_no, t1);
1766 dist = len_v3(t3) / len_v3(t2);
1768 test->dist = dist;
1770 return true;
1773 return false;
1776 #endif
1778 /* ===== Sculpting =====
1781 static float calc_overlap(blender::ed::sculpt_paint::StrokeCache *cache,
1782 const ePaintSymmetryFlags symm,
1783 const char axis,
1784 const float angle)
1786 float mirror[3];
1787 float distsq;
1789 flip_v3_v3(mirror, cache->true_location, symm);
1791 if (axis != 0) {
1792 float mat[3][3];
1793 axis_angle_to_mat3_single(mat, axis, angle);
1794 mul_m3_v3(mat, mirror);
1797 distsq = len_squared_v3v3(mirror, cache->true_location);
1799 if (distsq <= 4.0f * (cache->radius_squared)) {
1800 return (2.0f * (cache->radius) - sqrtf(distsq)) / (2.0f * (cache->radius));
1802 return 0.0f;
1805 static float calc_radial_symmetry_feather(Sculpt *sd,
1806 blender::ed::sculpt_paint::StrokeCache *cache,
1807 const ePaintSymmetryFlags symm,
1808 const char axis)
1810 float overlap = 0.0f;
1812 for (int i = 1; i < sd->radial_symm[axis - 'X']; i++) {
1813 const float angle = 2.0f * M_PI * i / sd->radial_symm[axis - 'X'];
1814 overlap += calc_overlap(cache, symm, axis, angle);
1817 return overlap;
1820 static float calc_symmetry_feather(Sculpt *sd, blender::ed::sculpt_paint::StrokeCache *cache)
1822 if (!(sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER)) {
1823 return 1.0f;
1825 float overlap;
1826 const int symm = cache->symmetry;
1828 overlap = 0.0f;
1829 for (int i = 0; i <= symm; i++) {
1830 if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
1831 continue;
1834 overlap += calc_overlap(cache, ePaintSymmetryFlags(i), 0, 0);
1836 overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'X');
1837 overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Y');
1838 overlap += calc_radial_symmetry_feather(sd, cache, ePaintSymmetryFlags(i), 'Z');
1840 return 1.0f / overlap;
1843 /** \} */
1845 /* -------------------------------------------------------------------- */
1846 /** \name Calculate Normal and Center
1848 * Calculate geometry surrounding the brush center.
1849 * (optionally using original coordinates).
1851 * Functions are:
1852 * - #SCULPT_calc_area_center
1853 * - #SCULPT_calc_area_normal
1854 * - #SCULPT_calc_area_normal_and_center
1856 * \note These are all _very_ similar, when changing one, check others.
1857 * \{ */
1859 struct AreaNormalCenterData {
1860 /* 0 = towards view, 1 = flipped */
1861 float area_cos[2][3];
1862 float area_nos[2][3];
1863 int count_no[2];
1864 int count_co[2];
1867 static void calc_area_normal_and_center_task(Object *ob,
1868 const Brush *brush,
1869 const bool use_area_nos,
1870 const bool use_area_cos,
1871 const bool has_bm_orco,
1872 PBVHNode *node,
1873 AreaNormalCenterData *anctd,
1874 bool &r_any_vertex_sampled)
1876 using namespace blender;
1877 using namespace blender::ed::sculpt_paint;
1878 SculptSession *ss = ob->sculpt;
1880 PBVHVertexIter vd;
1881 undo::Node *unode = nullptr;
1883 bool use_original = false;
1884 bool normal_test_r, area_test_r;
1886 if (ss->cache && !ss->cache->accum) {
1887 unode = undo::push_node(*ob, node, undo::Type::Position);
1888 use_original = (!unode->position.is_empty() || unode->bm_entry);
1891 SculptBrushTest normal_test;
1892 SculptBrushTestFn sculpt_brush_normal_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
1893 ss, &normal_test, brush->falloff_shape);
1895 /* Update the test radius to sample the normal using the normal radius of the brush. */
1896 if (brush->ob_mode == OB_MODE_SCULPT) {
1897 float test_radius = std::sqrt(normal_test.radius_squared);
1898 test_radius *= brush->normal_radius_factor;
1899 normal_test.radius = test_radius;
1900 normal_test.radius_squared = test_radius * test_radius;
1903 SculptBrushTest area_test;
1904 SculptBrushTestFn sculpt_brush_area_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
1905 ss, &area_test, brush->falloff_shape);
1907 if (brush->ob_mode == OB_MODE_SCULPT) {
1908 float test_radius = std::sqrt(area_test.radius_squared);
1909 /* Layer brush produces artifacts with normal and area radius */
1910 /* Enable area radius control only on Scrape for now */
1911 if (ELEM(brush->sculpt_tool, SCULPT_TOOL_SCRAPE, SCULPT_TOOL_FILL) &&
1912 brush->area_radius_factor > 0.0f)
1914 test_radius *= brush->area_radius_factor;
1915 if (ss->cache && brush->flag2 & BRUSH_AREA_RADIUS_PRESSURE) {
1916 test_radius *= ss->cache->pressure;
1919 else {
1920 test_radius *= brush->normal_radius_factor;
1922 area_test.radius = test_radius;
1923 area_test.radius_squared = test_radius * test_radius;
1926 /* When the mesh is edited we can't rely on original coords
1927 * (original mesh may not even have verts in brush radius). */
1928 if (use_original && has_bm_orco) {
1929 float(*orco_coords)[3];
1930 int(*orco_tris)[3];
1931 int orco_tris_num;
1933 BKE_pbvh_node_get_bm_orco_data(node, &orco_tris, &orco_tris_num, &orco_coords, nullptr);
1935 for (int i = 0; i < orco_tris_num; i++) {
1936 const float *co_tri[3] = {
1937 orco_coords[orco_tris[i][0]],
1938 orco_coords[orco_tris[i][1]],
1939 orco_coords[orco_tris[i][2]],
1941 float co[3];
1943 closest_on_tri_to_point_v3(co, normal_test.location, UNPACK3(co_tri));
1945 normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
1946 area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
1948 if (!normal_test_r && !area_test_r) {
1949 continue;
1952 float3 no;
1953 int flip_index;
1955 r_any_vertex_sampled = true;
1957 normal_tri_v3(no, UNPACK3(co_tri));
1959 flip_index = (math::dot(ss->cache->view_normal, no) <= 0.0f);
1960 if (use_area_cos && area_test_r) {
1961 /* Weight the coordinates towards the center. */
1962 float p = 1.0f - (std::sqrt(area_test.dist) / area_test.radius);
1963 const float afactor = std::clamp(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
1965 float disp[3];
1966 sub_v3_v3v3(disp, co, area_test.location);
1967 mul_v3_fl(disp, 1.0f - afactor);
1968 add_v3_v3v3(co, area_test.location, disp);
1969 add_v3_v3(anctd->area_cos[flip_index], co);
1971 anctd->count_co[flip_index] += 1;
1973 if (use_area_nos && normal_test_r) {
1974 /* Weight the normals towards the center. */
1975 float p = 1.0f - (std::sqrt(normal_test.dist) / normal_test.radius);
1976 const float nfactor = std::clamp(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
1977 mul_v3_fl(no, nfactor);
1979 add_v3_v3(anctd->area_nos[flip_index], no);
1980 anctd->count_no[flip_index] += 1;
1984 else {
1985 BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
1986 float co[3];
1988 /* For bm_vert only. */
1989 float no_s[3];
1991 if (use_original) {
1992 if (unode->bm_entry) {
1993 const float *temp_co;
1994 const float *temp_no_s;
1995 BM_log_original_vert_data(ss->bm_log, vd.bm_vert, &temp_co, &temp_no_s);
1996 copy_v3_v3(co, temp_co);
1997 copy_v3_v3(no_s, temp_no_s);
1999 else {
2000 copy_v3_v3(co, unode->position[vd.i]);
2001 copy_v3_v3(no_s, unode->normal[vd.i]);
2004 else {
2005 copy_v3_v3(co, vd.co);
2008 normal_test_r = sculpt_brush_normal_test_sq_fn(&normal_test, co);
2009 area_test_r = sculpt_brush_area_test_sq_fn(&area_test, co);
2011 if (!normal_test_r && !area_test_r) {
2012 continue;
2015 float no[3];
2016 int flip_index;
2018 r_any_vertex_sampled = true;
2020 if (use_original) {
2021 copy_v3_v3(no, no_s);
2023 else {
2024 if (vd.no) {
2025 copy_v3_v3(no, vd.no);
2027 else {
2028 copy_v3_v3(no, vd.fno);
2032 flip_index = (dot_v3v3(ss->cache ? ss->cache->view_normal : ss->cursor_view_normal, no) <=
2033 0.0f);
2035 if (use_area_cos && area_test_r) {
2036 /* Weight the coordinates towards the center. */
2037 float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius);
2038 const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2040 float disp[3];
2041 sub_v3_v3v3(disp, co, area_test.location);
2042 mul_v3_fl(disp, 1.0f - afactor);
2043 add_v3_v3v3(co, area_test.location, disp);
2045 add_v3_v3(anctd->area_cos[flip_index], co);
2046 anctd->count_co[flip_index] += 1;
2048 if (use_area_nos && normal_test_r) {
2049 /* Weight the normals towards the center. */
2050 float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius);
2051 const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f);
2052 mul_v3_fl(no, nfactor);
2054 add_v3_v3(anctd->area_nos[flip_index], no);
2055 anctd->count_no[flip_index] += 1;
2058 BKE_pbvh_vertex_iter_end;
2062 static AreaNormalCenterData calc_area_normal_and_center_reduce(const AreaNormalCenterData &a,
2063 const AreaNormalCenterData &b)
2065 AreaNormalCenterData joined{};
2067 /* For flatten center. */
2068 add_v3_v3v3(joined.area_cos[0], a.area_cos[0], b.area_cos[0]);
2069 add_v3_v3v3(joined.area_cos[1], a.area_cos[1], b.area_cos[1]);
2071 /* For area normal. */
2072 add_v3_v3v3(joined.area_nos[0], a.area_nos[0], b.area_nos[0]);
2073 add_v3_v3v3(joined.area_nos[1], a.area_nos[1], b.area_nos[1]);
2075 /* Weights. */
2076 add_v2_v2v2_int(joined.count_no, a.count_no, b.count_no);
2077 add_v2_v2v2_int(joined.count_co, a.count_co, b.count_co);
2079 return joined;
2082 void SCULPT_calc_area_center(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_co[3])
2084 using namespace blender;
2085 using namespace blender::ed::sculpt_paint;
2086 const Brush *brush = BKE_paint_brush(&sd->paint);
2087 SculptSession *ss = ob->sculpt;
2088 const bool has_bm_orco = ss->bm && dyntopo::stroke_is_dyntopo(ss, brush);
2089 int n;
2091 bool any_vertex_sampled = false;
2093 const AreaNormalCenterData anctd = threading::parallel_reduce(
2094 nodes.index_range(),
2096 AreaNormalCenterData{},
2097 [&](const IndexRange range, AreaNormalCenterData anctd) {
2098 for (const int i : range) {
2099 calc_area_normal_and_center_task(
2100 ob, brush, false, true, has_bm_orco, nodes[i], &anctd, any_vertex_sampled);
2102 return anctd;
2104 calc_area_normal_and_center_reduce);
2106 /* For flatten center. */
2107 for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
2108 if (anctd.count_co[n] == 0) {
2109 continue;
2112 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
2113 break;
2116 if (n == 2) {
2117 zero_v3(r_area_co);
2120 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
2121 if (ss->cache) {
2122 copy_v3_v3(r_area_co, ss->cache->location);
2127 std::optional<float3> SCULPT_calc_area_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
2129 const Brush *brush = BKE_paint_brush(&sd->paint);
2130 return SCULPT_pbvh_calc_area_normal(brush, ob, nodes);
2133 std::optional<float3> SCULPT_pbvh_calc_area_normal(const Brush *brush,
2134 Object *ob,
2135 Span<PBVHNode *> nodes)
2137 using namespace blender;
2138 using namespace blender::ed::sculpt_paint;
2139 SculptSession *ss = ob->sculpt;
2140 const bool has_bm_orco = ss->bm && dyntopo::stroke_is_dyntopo(ss, brush);
2142 bool any_vertex_sampled = false;
2144 const AreaNormalCenterData anctd = threading::parallel_reduce(
2145 nodes.index_range(),
2147 AreaNormalCenterData{},
2148 [&](const IndexRange range, AreaNormalCenterData anctd) {
2149 for (const int i : range) {
2150 calc_area_normal_and_center_task(
2151 ob, brush, true, false, has_bm_orco, nodes[i], &anctd, any_vertex_sampled);
2153 return anctd;
2155 calc_area_normal_and_center_reduce);
2157 if (!any_vertex_sampled) {
2158 return std::nullopt;
2161 /* For area normal. */
2162 float3 result;
2163 for (int i = 0; i < ARRAY_SIZE(anctd.area_nos); i++) {
2164 if (normalize_v3_v3(result, anctd.area_nos[i]) != 0.0f) {
2165 return result;
2168 return std::nullopt;
2171 void SCULPT_calc_area_normal_and_center(
2172 Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
2174 using namespace blender;
2175 using namespace blender::ed::sculpt_paint;
2176 const Brush *brush = BKE_paint_brush(&sd->paint);
2177 SculptSession *ss = ob->sculpt;
2178 const bool has_bm_orco = ss->bm && dyntopo::stroke_is_dyntopo(ss, brush);
2179 int n;
2181 bool any_vertex_sampled = false;
2183 const AreaNormalCenterData anctd = threading::parallel_reduce(
2184 nodes.index_range(),
2186 AreaNormalCenterData{},
2187 [&](const IndexRange range, AreaNormalCenterData anctd) {
2188 for (const int i : range) {
2189 calc_area_normal_and_center_task(
2190 ob, brush, true, true, has_bm_orco, nodes[i], &anctd, any_vertex_sampled);
2192 return anctd;
2194 calc_area_normal_and_center_reduce);
2196 /* For flatten center. */
2197 for (n = 0; n < ARRAY_SIZE(anctd.area_cos); n++) {
2198 if (anctd.count_co[n] == 0) {
2199 continue;
2202 mul_v3_v3fl(r_area_co, anctd.area_cos[n], 1.0f / anctd.count_co[n]);
2203 break;
2206 if (n == 2) {
2207 zero_v3(r_area_co);
2210 if (anctd.count_co[0] == 0 && anctd.count_co[1] == 0) {
2211 if (ss->cache) {
2212 copy_v3_v3(r_area_co, ss->cache->location);
2216 /* For area normal. */
2217 for (n = 0; n < ARRAY_SIZE(anctd.area_nos); n++) {
2218 if (normalize_v3_v3(r_area_no, anctd.area_nos[n]) != 0.0f) {
2219 break;
2224 /** \} */
2226 /* -------------------------------------------------------------------- */
2227 /** \name Generic Brush Utilities
2228 * \{ */
2231 * Return modified brush strength. Includes the direction of the brush, positive
2232 * values pull vertices, negative values push. Uses tablet pressure and a
2233 * special multiplier found experimentally to scale the strength factor.
2235 static float brush_strength(const Sculpt *sd,
2236 const blender::ed::sculpt_paint::StrokeCache *cache,
2237 const float feather,
2238 const UnifiedPaintSettings *ups,
2239 const PaintModeSettings * /*paint_mode_settings*/)
2241 const Scene *scene = cache->vc->scene;
2242 const Brush *brush = BKE_paint_brush((Paint *)&sd->paint);
2244 /* Primary strength input; square it to make lower values more sensitive. */
2245 const float root_alpha = BKE_brush_alpha_get(scene, brush);
2246 const float alpha = root_alpha * root_alpha;
2247 const float dir = (brush->flag & BRUSH_DIR_IN) ? -1.0f : 1.0f;
2248 const float pressure = BKE_brush_use_alpha_pressure(brush) ? cache->pressure : 1.0f;
2249 const float pen_flip = cache->pen_flip ? -1.0f : 1.0f;
2250 const float invert = cache->invert ? -1.0f : 1.0f;
2251 float overlap = ups->overlap_factor;
2252 /* Spacing is integer percentage of radius, divide by 50 to get
2253 * normalized diameter. */
2255 float flip = dir * invert * pen_flip;
2256 if (brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
2257 flip = 1.0f;
2260 /* Pressure final value after being tweaked depending on the brush. */
2261 float final_pressure;
2263 switch (brush->sculpt_tool) {
2264 case SCULPT_TOOL_CLAY:
2265 final_pressure = pow4f(pressure);
2266 overlap = (1.0f + overlap) / 2.0f;
2267 return 0.25f * alpha * flip * final_pressure * overlap * feather;
2268 case SCULPT_TOOL_DRAW:
2269 case SCULPT_TOOL_DRAW_SHARP:
2270 case SCULPT_TOOL_LAYER:
2271 return alpha * flip * pressure * overlap * feather;
2272 case SCULPT_TOOL_DISPLACEMENT_ERASER:
2273 return alpha * pressure * overlap * feather;
2274 case SCULPT_TOOL_CLOTH:
2275 if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) {
2276 /* Grab deform uses the same falloff as a regular grab brush. */
2277 return root_alpha * feather;
2279 else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) {
2280 return root_alpha * feather * pressure * overlap;
2282 else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_EXPAND) {
2283 /* Expand is more sensible to strength as it keeps expanding the cloth when sculpting over
2284 * the same vertices. */
2285 return 0.1f * alpha * flip * pressure * overlap * feather;
2287 else {
2288 /* Multiply by 10 by default to get a larger range of strength depending on the size of the
2289 * brush and object. */
2290 return 10.0f * alpha * flip * pressure * overlap * feather;
2292 case SCULPT_TOOL_DRAW_FACE_SETS:
2293 return alpha * pressure * overlap * feather;
2294 case SCULPT_TOOL_SLIDE_RELAX:
2295 return alpha * pressure * overlap * feather * 2.0f;
2296 case SCULPT_TOOL_PAINT:
2297 final_pressure = pressure * pressure;
2298 return final_pressure * overlap * feather;
2299 case SCULPT_TOOL_SMEAR:
2300 case SCULPT_TOOL_DISPLACEMENT_SMEAR:
2301 return alpha * pressure * overlap * feather;
2302 case SCULPT_TOOL_CLAY_STRIPS:
2303 /* Clay Strips needs less strength to compensate the curve. */
2304 final_pressure = powf(pressure, 1.5f);
2305 return alpha * flip * final_pressure * overlap * feather * 0.3f;
2306 case SCULPT_TOOL_CLAY_THUMB:
2307 final_pressure = pressure * pressure;
2308 return alpha * flip * final_pressure * overlap * feather * 1.3f;
2310 case SCULPT_TOOL_MASK:
2311 overlap = (1.0f + overlap) / 2.0f;
2312 switch ((BrushMaskTool)brush->mask_tool) {
2313 case BRUSH_MASK_DRAW:
2314 return alpha * flip * pressure * overlap * feather;
2315 case BRUSH_MASK_SMOOTH:
2316 return alpha * pressure * feather;
2318 BLI_assert_msg(0, "Not supposed to happen");
2319 return 0.0f;
2321 case SCULPT_TOOL_CREASE:
2322 case SCULPT_TOOL_BLOB:
2323 return alpha * flip * pressure * overlap * feather;
2325 case SCULPT_TOOL_INFLATE:
2326 if (flip > 0.0f) {
2327 return 0.250f * alpha * flip * pressure * overlap * feather;
2329 else {
2330 return 0.125f * alpha * flip * pressure * overlap * feather;
2333 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
2334 overlap = (1.0f + overlap) / 2.0f;
2335 return alpha * flip * pressure * overlap * feather;
2337 case SCULPT_TOOL_FILL:
2338 case SCULPT_TOOL_SCRAPE:
2339 case SCULPT_TOOL_FLATTEN:
2340 if (flip > 0.0f) {
2341 overlap = (1.0f + overlap) / 2.0f;
2342 return alpha * flip * pressure * overlap * feather;
2344 else {
2345 /* Reduce strength for DEEPEN, PEAKS, and CONTRAST. */
2346 return 0.5f * alpha * flip * pressure * overlap * feather;
2349 case SCULPT_TOOL_SMOOTH:
2350 return flip * alpha * pressure * feather;
2352 case SCULPT_TOOL_PINCH:
2353 if (flip > 0.0f) {
2354 return alpha * flip * pressure * overlap * feather;
2356 else {
2357 return 0.25f * alpha * flip * pressure * overlap * feather;
2360 case SCULPT_TOOL_NUDGE:
2361 overlap = (1.0f + overlap) / 2.0f;
2362 return alpha * pressure * overlap * feather;
2364 case SCULPT_TOOL_THUMB:
2365 return alpha * pressure * feather;
2367 case SCULPT_TOOL_SNAKE_HOOK:
2368 return root_alpha * feather;
2370 case SCULPT_TOOL_GRAB:
2371 return root_alpha * feather;
2373 case SCULPT_TOOL_ROTATE:
2374 return alpha * pressure * feather;
2376 case SCULPT_TOOL_ELASTIC_DEFORM:
2377 case SCULPT_TOOL_POSE:
2378 case SCULPT_TOOL_BOUNDARY:
2379 return root_alpha * feather;
2381 default:
2382 return 0.0f;
2386 static float sculpt_apply_hardness(const SculptSession *ss, const float input_len)
2388 const blender::ed::sculpt_paint::StrokeCache *cache = ss->cache;
2389 float final_len = input_len;
2390 const float hardness = cache->paint_brush.hardness;
2391 float p = input_len / cache->radius;
2392 if (p < hardness) {
2393 final_len = 0.0f;
2395 else if (hardness == 1.0f) {
2396 final_len = cache->radius;
2398 else {
2399 p = (p - hardness) / (1.0f - hardness);
2400 final_len = p * cache->radius;
2403 return final_len;
2406 static void sculpt_apply_texture(const SculptSession *ss,
2407 const Brush *brush,
2408 const float brush_point[3],
2409 const int thread_id,
2410 float *r_value,
2411 float r_rgba[4])
2413 blender::ed::sculpt_paint::StrokeCache *cache = ss->cache;
2414 const Scene *scene = cache->vc->scene;
2415 const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
2417 if (!mtex->tex) {
2418 *r_value = 1.0f;
2419 copy_v4_fl(r_rgba, 1.0f);
2420 return;
2423 float point[3];
2424 sub_v3_v3v3(point, brush_point, cache->plane_offset);
2426 if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
2427 /* Get strength by feeding the vertex location directly into a texture. */
2428 *r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point, r_rgba, 0, ss->tex_pool);
2430 else {
2431 float symm_point[3];
2433 /* If the active area is being applied for symmetry, flip it
2434 * across the symmetry axis and rotate it back to the original
2435 * position in order to project it. This insures that the
2436 * brush texture will be oriented correctly. */
2437 if (cache->radial_symmetry_pass) {
2438 mul_m4_v3(cache->symm_rot_mat_inv.ptr(), point);
2440 flip_v3_v3(symm_point, point, cache->mirror_symmetry_pass);
2442 /* Still no symmetry supported for other paint modes.
2443 * Sculpt does it DIY. */
2444 if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
2445 /* Similar to fixed mode, but projects from brush angle
2446 * rather than view direction. */
2448 mul_m4_v3(cache->brush_local_mat.ptr(), symm_point);
2450 float x = symm_point[0];
2451 float y = symm_point[1];
2453 x *= mtex->size[0];
2454 y *= mtex->size[1];
2456 x += mtex->ofs[0];
2457 y += mtex->ofs[1];
2459 paint_get_tex_pixel(mtex, x, y, ss->tex_pool, thread_id, r_value, r_rgba);
2461 add_v3_fl(r_rgba, brush->texture_sample_bias); // v3 -> Ignore alpha
2462 *r_value -= brush->texture_sample_bias;
2464 else {
2465 const blender::float2 point_2d = ED_view3d_project_float_v2_m4(
2466 cache->vc->region, symm_point, cache->projection_mat);
2467 const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
2468 *r_value = BKE_brush_sample_tex_3d(scene, brush, mtex, point_3d, r_rgba, 0, ss->tex_pool);
2473 float SCULPT_brush_strength_factor(
2474 SculptSession *ss,
2475 const Brush *brush,
2476 const float brush_point[3],
2477 float len,
2478 const float vno[3],
2479 const float fno[3],
2480 float mask,
2481 const PBVHVertRef vertex,
2482 int thread_id,
2483 const blender::ed::sculpt_paint::auto_mask::NodeData *automask_data)
2485 using namespace blender::ed::sculpt_paint;
2486 StrokeCache *cache = ss->cache;
2488 float avg = 1.0f;
2489 float rgba[4];
2490 sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, rgba);
2492 /* Hardness. */
2493 const float final_len = sculpt_apply_hardness(ss, len);
2495 /* Falloff curve. */
2496 avg *= BKE_brush_curve_strength(brush, final_len, cache->radius);
2497 avg *= frontface(*brush, cache->view_normal, vno ? vno : fno);
2499 /* Paint mask. */
2500 avg *= 1.0f - mask;
2502 /* Auto-masking. */
2503 avg *= auto_mask::factor_get(cache->automasking.get(), ss, vertex, automask_data);
2505 return avg;
2508 void SCULPT_brush_strength_color(
2509 SculptSession *ss,
2510 const Brush *brush,
2511 const float brush_point[3],
2512 float len,
2513 const float vno[3],
2514 const float fno[3],
2515 float mask,
2516 const PBVHVertRef vertex,
2517 int thread_id,
2518 const blender::ed::sculpt_paint::auto_mask::NodeData *automask_data,
2519 float r_rgba[4])
2521 using namespace blender::ed::sculpt_paint;
2522 StrokeCache *cache = ss->cache;
2524 float avg = 1.0f;
2525 sculpt_apply_texture(ss, brush, brush_point, thread_id, &avg, r_rgba);
2527 /* Hardness. */
2528 const float final_len = sculpt_apply_hardness(ss, len);
2530 /* Falloff curve. */
2531 const float falloff = BKE_brush_curve_strength(brush, final_len, cache->radius) *
2532 frontface(*brush, cache->view_normal, vno ? vno : fno);
2534 /* Paint mask. */
2535 const float paint_mask = 1.0f - mask;
2537 /* Auto-masking. */
2538 const float automasking_factor = auto_mask::factor_get(
2539 cache->automasking.get(), ss, vertex, automask_data);
2541 const float masks_combined = falloff * paint_mask * automasking_factor;
2543 mul_v4_fl(r_rgba, masks_combined);
2546 void SCULPT_calc_vertex_displacement(SculptSession *ss,
2547 const Brush *brush,
2548 float rgba[3],
2549 float r_offset[3])
2551 mul_v3_fl(rgba, ss->cache->bstrength);
2552 /* Handle brush inversion */
2553 if (ss->cache->bstrength < 0) {
2554 rgba[0] *= -1;
2555 rgba[1] *= -1;
2558 /* Apply texture size */
2559 for (int i = 0; i < 3; ++i) {
2560 rgba[i] *= blender::math::safe_divide(1.0f, pow2f(brush->mtex.size[i]));
2563 /* Transform vector to object space */
2564 mul_mat3_m4_v3(ss->cache->brush_local_mat_inv.ptr(), rgba);
2566 /* Handle symmetry */
2567 if (ss->cache->radial_symmetry_pass) {
2568 mul_m4_v3(ss->cache->symm_rot_mat.ptr(), rgba);
2570 flip_v3_v3(r_offset, rgba, ss->cache->mirror_symmetry_pass);
2573 namespace blender::ed::sculpt_paint {
2575 bool node_fully_masked_or_hidden(const PBVHNode &node)
2577 if (BKE_pbvh_node_fully_hidden_get(&node)) {
2578 return true;
2580 if (BKE_pbvh_node_fully_masked_get(&node)) {
2581 return true;
2583 return false;
2586 bool node_in_sphere(const PBVHNode &node,
2587 const float3 &location,
2588 const float radius_sq,
2589 const bool original)
2591 const Bounds<float3> bounds = original ? BKE_pbvh_node_get_original_BB(&node) :
2592 bke::pbvh::node_bounds(node);
2593 const float3 nearest = math::clamp(location, bounds.min, bounds.max);
2594 return math::distance_squared(location, nearest) < radius_sq;
2597 bool node_in_cylinder(const DistRayAABB_Precalc &ray_dist_precalc,
2598 const PBVHNode &node,
2599 const float radius_sq,
2600 const bool original)
2602 const Bounds<float3> bounds = (original) ? BKE_pbvh_node_get_original_BB(&node) :
2603 bke::pbvh::node_bounds(node);
2605 float dummy_co[3], dummy_depth;
2606 const float dist_sq = dist_squared_ray_to_aabb_v3(
2607 &ray_dist_precalc, bounds.min, bounds.max, dummy_co, &dummy_depth);
2609 /* TODO: Solve issues and enable distance check. */
2610 return dist_sq < radius_sq || true;
2613 } // namespace blender::ed::sculpt_paint
2615 void SCULPT_clip(Sculpt *sd, SculptSession *ss, float co[3], const float val[3])
2617 for (int i = 0; i < 3; i++) {
2618 if (sd->flags & (SCULPT_LOCK_X << i)) {
2619 continue;
2622 bool do_clip = false;
2623 float co_clip[3];
2624 if (ss->cache && (ss->cache->flag & (CLIP_X << i))) {
2625 /* Take possible mirror object into account. */
2626 mul_v3_m4v3(co_clip, ss->cache->clip_mirror_mtx.ptr(), co);
2628 if (fabsf(co_clip[i]) <= ss->cache->clip_tolerance[i]) {
2629 co_clip[i] = 0.0f;
2630 float imtx[4][4];
2631 invert_m4_m4(imtx, ss->cache->clip_mirror_mtx.ptr());
2632 mul_m4_v3(imtx, co_clip);
2633 do_clip = true;
2637 if (do_clip) {
2638 co[i] = co_clip[i];
2640 else {
2641 co[i] = val[i];
2646 namespace blender::ed::sculpt_paint {
2648 static Vector<PBVHNode *> sculpt_pbvh_gather_cursor_update(Object *ob, bool use_original)
2650 SculptSession *ss = ob->sculpt;
2651 const float3 center = ss->cache ? ss->cache->location : ss->cursor_location;
2652 return bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
2653 return node_in_sphere(node, center, ss->cursor_radius, use_original);
2657 /** \return All nodes that are potentially within the cursor or brush's area of influence. */
2658 static Vector<PBVHNode *> sculpt_pbvh_gather_generic_intern(
2659 Object *ob, const Brush *brush, bool use_original, float radius_scale, PBVHNodeFlags flag)
2661 SculptSession *ss = ob->sculpt;
2663 PBVHNodeFlags leaf_flag = PBVH_Leaf;
2664 if (flag & PBVH_TexLeaf) {
2665 leaf_flag = PBVH_TexLeaf;
2668 const float3 center = ss->cache->location;
2669 const float radius_sq = math::square(ss->cache->radius * radius_scale);
2670 const bool ignore_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK;
2671 switch (brush->falloff_shape) {
2672 case PAINT_FALLOFF_SHAPE_SPHERE: {
2673 return bke::pbvh::search_gather(
2674 ss->pbvh,
2675 [&](PBVHNode &node) {
2676 if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
2677 return false;
2679 return node_in_sphere(node, center, radius_sq, use_original);
2681 leaf_flag);
2684 case PAINT_FALLOFF_SHAPE_TUBE: {
2685 const DistRayAABB_Precalc ray_dist_precalc = dist_squared_ray_to_aabb_v3_precalc(
2686 center, ss->cache->view_normal);
2687 return bke::pbvh::search_gather(
2688 ss->pbvh,
2689 [&](PBVHNode &node) {
2690 if (ignore_ineffective && node_fully_masked_or_hidden(node)) {
2691 return false;
2693 return node_in_cylinder(ray_dist_precalc, node, radius_sq, use_original);
2695 leaf_flag);
2699 return {};
2702 static Vector<PBVHNode *> sculpt_pbvh_gather_generic(Object *ob,
2703 const Brush *brush,
2704 const bool use_original,
2705 const float radius_scale)
2707 return sculpt_pbvh_gather_generic_intern(ob, brush, use_original, radius_scale, PBVH_Leaf);
2710 static Vector<PBVHNode *> sculpt_pbvh_gather_texpaint(Object *ob,
2711 const Brush *brush,
2712 const bool use_original,
2713 const float radius_scale)
2715 return sculpt_pbvh_gather_generic_intern(ob, brush, use_original, radius_scale, PBVH_TexLeaf);
2718 /* Calculate primary direction of movement for many brushes. */
2719 static float3 calc_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
2721 const Brush *brush = BKE_paint_brush(&sd->paint);
2722 const SculptSession *ss = ob->sculpt;
2723 switch (brush->sculpt_plane) {
2724 case SCULPT_DISP_DIR_AREA:
2725 return SCULPT_calc_area_normal(sd, ob, nodes).value_or(float3(0));
2726 case SCULPT_DISP_DIR_VIEW:
2727 return ss->cache->true_view_normal;
2728 case SCULPT_DISP_DIR_X:
2729 return float3(1, 0, 0);
2730 case SCULPT_DISP_DIR_Y:
2731 return float3(0, 1, 0);
2732 case SCULPT_DISP_DIR_Z:
2733 return float3(0, 0, 1);
2735 BLI_assert_unreachable();
2736 return {};
2739 static void update_sculpt_normal(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes)
2741 const Brush *brush = BKE_paint_brush(&sd->paint);
2742 StrokeCache *cache = ob->sculpt->cache;
2743 /* Grab brush does not update the sculpt normal during a stroke. */
2744 const bool update_normal =
2745 !(brush->flag & BRUSH_ORIGINAL_NORMAL) && !(brush->sculpt_tool == SCULPT_TOOL_GRAB) &&
2746 !(brush->sculpt_tool == SCULPT_TOOL_THUMB && !(brush->flag & BRUSH_ANCHORED)) &&
2747 !(brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) &&
2748 !(brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK && cache->normal_weight > 0.0f);
2750 if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
2751 (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal))
2753 cache->sculpt_normal = calc_sculpt_normal(sd, ob, nodes);
2754 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
2755 project_plane_v3_v3v3(cache->sculpt_normal, cache->sculpt_normal, cache->view_normal);
2756 normalize_v3(cache->sculpt_normal);
2758 copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
2760 else {
2761 copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal);
2762 flip_v3(cache->sculpt_normal_symm, cache->mirror_symmetry_pass);
2763 mul_m4_v3(cache->symm_rot_mat.ptr(), cache->sculpt_normal_symm);
2767 static void calc_local_from_screen(ViewContext *vc,
2768 const float center[3],
2769 const float screen_dir[2],
2770 float r_local_dir[3])
2772 Object *ob = vc->obact;
2773 float loc[3];
2775 mul_v3_m4v3(loc, ob->object_to_world().ptr(), center);
2776 const float zfac = ED_view3d_calc_zfac(vc->rv3d, loc);
2778 ED_view3d_win_to_delta(vc->region, screen_dir, zfac, r_local_dir);
2779 normalize_v3(r_local_dir);
2781 add_v3_v3(r_local_dir, ob->loc);
2782 mul_m4_v3(ob->world_to_object().ptr(), r_local_dir);
2785 static void calc_brush_local_mat(const float rotation,
2786 Object *ob,
2787 float local_mat[4][4],
2788 float local_mat_inv[4][4])
2790 const StrokeCache *cache = ob->sculpt->cache;
2791 float tmat[4][4];
2792 float mat[4][4];
2793 float scale[4][4];
2794 float angle, v[3];
2796 /* Ensure `ob->world_to_object` is up to date. */
2797 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
2799 /* Initialize last column of matrix. */
2800 mat[0][3] = 0.0f;
2801 mat[1][3] = 0.0f;
2802 mat[2][3] = 0.0f;
2803 mat[3][3] = 1.0f;
2805 /* Read rotation (user angle, rake, etc.) to find the view's movement direction (negative X of
2806 * the brush). */
2807 angle = rotation + cache->special_rotation;
2808 /* By convention, motion direction points down the brush's Y axis, the angle represents the X
2809 * axis, normal is a 90 deg CCW rotation of the motion direction. */
2810 float motion_normal_screen[2];
2811 motion_normal_screen[0] = cosf(angle);
2812 motion_normal_screen[1] = sinf(angle);
2813 /* Convert view's brush transverse direction to object-space,
2814 * i.e. the normal of the plane described by the motion */
2815 float motion_normal_local[3];
2816 calc_local_from_screen(cache->vc, cache->location, motion_normal_screen, motion_normal_local);
2818 /* Calculate the movement direction for the local matrix.
2819 * Note that there is a deliberate prioritization here: Our calculations are
2820 * designed such that the _motion vector_ gets projected into the tangent space;
2821 * in most cases this will be more intuitive than projecting the transverse
2822 * direction (which is orthogonal to the motion direction and therefore less
2823 * apparent to the user).
2824 * The Y-axis of the brush-local frame has to lie in the intersection of the tangent plane
2825 * and the motion plane. */
2827 cross_v3_v3v3(v, cache->sculpt_normal, motion_normal_local);
2828 normalize_v3_v3(mat[1], v);
2830 /* Get other axes. */
2831 cross_v3_v3v3(mat[0], mat[1], cache->sculpt_normal);
2832 copy_v3_v3(mat[2], cache->sculpt_normal);
2834 /* Set location. */
2835 copy_v3_v3(mat[3], cache->location);
2837 /* Scale by brush radius. */
2838 float radius = cache->radius;
2840 normalize_m4(mat);
2841 scale_m4_fl(scale, radius);
2842 mul_m4_m4m4(tmat, mat, scale);
2844 /* Return tmat as is (for converting from local area coords to model-space coords). */
2845 copy_m4_m4(local_mat_inv, tmat);
2846 /* Return inverse (for converting from model-space coords to local area coords). */
2847 invert_m4_m4(local_mat, tmat);
2850 } // namespace blender::ed::sculpt_paint
2852 #define SCULPT_TILT_SENSITIVITY 0.7f
2853 void SCULPT_tilt_apply_to_normal(float r_normal[3],
2854 blender::ed::sculpt_paint::StrokeCache *cache,
2855 const float tilt_strength)
2857 if (!U.experimental.use_sculpt_tools_tilt) {
2858 return;
2860 const float rot_max = M_PI_2 * tilt_strength * SCULPT_TILT_SENSITIVITY;
2861 mul_v3_mat3_m4v3(r_normal, cache->vc->obact->object_to_world().ptr(), r_normal);
2862 float normal_tilt_y[3];
2863 rotate_v3_v3v3fl(normal_tilt_y, r_normal, cache->vc->rv3d->viewinv[0], cache->y_tilt * rot_max);
2864 float normal_tilt_xy[3];
2865 rotate_v3_v3v3fl(
2866 normal_tilt_xy, normal_tilt_y, cache->vc->rv3d->viewinv[1], cache->x_tilt * rot_max);
2867 mul_v3_mat3_m4v3(r_normal, cache->vc->obact->world_to_object().ptr(), normal_tilt_xy);
2868 normalize_v3(r_normal);
2871 void SCULPT_tilt_effective_normal_get(const SculptSession *ss, const Brush *brush, float r_no[3])
2873 copy_v3_v3(r_no, ss->cache->sculpt_normal_symm);
2874 SCULPT_tilt_apply_to_normal(r_no, ss->cache, brush->tilt_strength_factor);
2877 static void update_brush_local_mat(Sculpt *sd, Object *ob)
2879 using namespace blender::ed::sculpt_paint;
2880 StrokeCache *cache = ob->sculpt->cache;
2882 if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) {
2883 const Brush *brush = BKE_paint_brush(&sd->paint);
2884 const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
2885 calc_brush_local_mat(
2886 mask_tex->rot, ob, cache->brush_local_mat.ptr(), cache->brush_local_mat_inv.ptr());
2890 /** \} */
2892 /* -------------------------------------------------------------------- */
2893 /** \name Texture painting
2894 * \{ */
2896 static bool sculpt_needs_pbvh_pixels(PaintModeSettings *paint_mode_settings,
2897 const Brush *brush,
2898 Object *ob)
2900 if (brush->sculpt_tool == SCULPT_TOOL_PAINT && U.experimental.use_sculpt_texture_paint) {
2901 Image *image;
2902 ImageUser *image_user;
2903 return SCULPT_paint_image_canvas_get(paint_mode_settings, ob, &image, &image_user);
2906 return false;
2909 static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings,
2910 SculptSession *ss,
2911 Object *ob)
2913 using namespace blender;
2914 BLI_assert(ob->type == OB_MESH);
2915 Mesh *mesh = (Mesh *)ob->data;
2917 Image *image;
2918 ImageUser *image_user;
2919 if (!SCULPT_paint_image_canvas_get(paint_mode_settings, ob, &image, &image_user)) {
2920 return;
2923 bke::pbvh::build_pixels(ss->pbvh, mesh, image, image_user);
2926 /** \} */
2928 /* -------------------------------------------------------------------- */
2929 /** \name Generic Brush Plane & Symmetry Utilities
2930 * \{ */
2932 struct SculptRaycastData {
2933 SculptSession *ss;
2934 const float *ray_start;
2935 const float *ray_normal;
2936 bool hit;
2937 float depth;
2938 bool original;
2939 Span<int> corner_verts;
2940 blender::VArraySpan<bool> hide_poly;
2942 PBVHVertRef active_vertex;
2943 float *face_normal;
2945 int active_face_grid_index;
2947 IsectRayPrecalc isect_precalc;
2950 struct SculptFindNearestToRayData {
2951 SculptSession *ss;
2952 const float *ray_start, *ray_normal;
2953 bool hit;
2954 float depth;
2955 float dist_sq_to_ray;
2956 bool original;
2957 Span<int> corner_verts;
2958 blender::VArraySpan<bool> hide_poly;
2961 ePaintSymmetryAreas SCULPT_get_vertex_symm_area(const float co[3])
2963 ePaintSymmetryAreas symm_area = ePaintSymmetryAreas(PAINT_SYMM_AREA_DEFAULT);
2964 if (co[0] < 0.0f) {
2965 symm_area |= PAINT_SYMM_AREA_X;
2967 if (co[1] < 0.0f) {
2968 symm_area |= PAINT_SYMM_AREA_Y;
2970 if (co[2] < 0.0f) {
2971 symm_area |= PAINT_SYMM_AREA_Z;
2973 return symm_area;
2976 void SCULPT_flip_v3_by_symm_area(float v[3],
2977 const ePaintSymmetryFlags symm,
2978 const ePaintSymmetryAreas symmarea,
2979 const float pivot[3])
2981 for (int i = 0; i < 3; i++) {
2982 ePaintSymmetryFlags symm_it = ePaintSymmetryFlags(1 << i);
2983 if (!(symm & symm_it)) {
2984 continue;
2986 if (symmarea & symm_it) {
2987 flip_v3(v, symm_it);
2989 if (pivot[i] < 0.0f) {
2990 flip_v3(v, symm_it);
2995 void SCULPT_flip_quat_by_symm_area(float quat[4],
2996 const ePaintSymmetryFlags symm,
2997 const ePaintSymmetryAreas symmarea,
2998 const float pivot[3])
3000 for (int i = 0; i < 3; i++) {
3001 ePaintSymmetryFlags symm_it = ePaintSymmetryFlags(1 << i);
3002 if (!(symm & symm_it)) {
3003 continue;
3005 if (symmarea & symm_it) {
3006 flip_qt(quat, symm_it);
3008 if (pivot[i] < 0.0f) {
3009 flip_qt(quat, symm_it);
3014 bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
3016 if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) {
3017 /* Elastic deformations in any brush need all nodes to avoid artifacts as the effect
3018 * of the Kelvinlet is not constrained by the radius. */
3019 return true;
3022 if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
3023 /* Pose needs all nodes because it applies all symmetry iterations at the same time
3024 * and the IK chain can grow to any area of the model. */
3025 /* TODO: This can be optimized by filtering the nodes after calculating the chain. */
3026 return true;
3029 if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
3030 /* Boundary needs all nodes because it is not possible to know where the boundary
3031 * deformation is going to be propagated before calculating it. */
3032 /* TODO: after calculating the boundary info in the first iteration, it should be
3033 * possible to get the nodes that have vertices included in any boundary deformation
3034 * and cache them. */
3035 return true;
3038 if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
3039 brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC)
3041 /* Snake hook in elastic deform type has same requirements as the elastic deform tool. */
3042 return true;
3044 return false;
3047 void SCULPT_calc_brush_plane(
3048 Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float r_area_no[3], float r_area_co[3])
3050 SculptSession *ss = ob->sculpt;
3051 Brush *brush = BKE_paint_brush(&sd->paint);
3053 zero_v3(r_area_co);
3054 zero_v3(r_area_no);
3056 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache) &&
3057 (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
3058 !(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL)))
3060 switch (brush->sculpt_plane) {
3061 case SCULPT_DISP_DIR_VIEW:
3062 copy_v3_v3(r_area_no, ss->cache->true_view_normal);
3063 break;
3065 case SCULPT_DISP_DIR_X:
3066 ARRAY_SET_ITEMS(r_area_no, 1.0f, 0.0f, 0.0f);
3067 break;
3069 case SCULPT_DISP_DIR_Y:
3070 ARRAY_SET_ITEMS(r_area_no, 0.0f, 1.0f, 0.0f);
3071 break;
3073 case SCULPT_DISP_DIR_Z:
3074 ARRAY_SET_ITEMS(r_area_no, 0.0f, 0.0f, 1.0f);
3075 break;
3077 case SCULPT_DISP_DIR_AREA:
3078 SCULPT_calc_area_normal_and_center(sd, ob, nodes, r_area_no, r_area_co);
3079 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
3080 project_plane_v3_v3v3(r_area_no, r_area_no, ss->cache->view_normal);
3081 normalize_v3(r_area_no);
3083 break;
3085 default:
3086 break;
3089 /* For flatten center. */
3090 /* Flatten center has not been calculated yet if we are not using the area normal. */
3091 if (brush->sculpt_plane != SCULPT_DISP_DIR_AREA) {
3092 SCULPT_calc_area_center(sd, ob, nodes, r_area_co);
3095 /* For area normal. */
3096 if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
3097 (brush->flag & BRUSH_ORIGINAL_NORMAL))
3099 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
3101 else {
3102 copy_v3_v3(ss->cache->sculpt_normal, r_area_no);
3105 /* For flatten center. */
3106 if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) &&
3107 (brush->flag & BRUSH_ORIGINAL_PLANE))
3109 copy_v3_v3(r_area_co, ss->cache->last_center);
3111 else {
3112 copy_v3_v3(ss->cache->last_center, r_area_co);
3115 else {
3116 /* For area normal. */
3117 copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
3119 /* For flatten center. */
3120 copy_v3_v3(r_area_co, ss->cache->last_center);
3122 /* For area normal. */
3123 flip_v3(r_area_no, ss->cache->mirror_symmetry_pass);
3125 /* For flatten center. */
3126 flip_v3(r_area_co, ss->cache->mirror_symmetry_pass);
3128 /* For area normal. */
3129 mul_m4_v3(ss->cache->symm_rot_mat.ptr(), r_area_no);
3131 /* For flatten center. */
3132 mul_m4_v3(ss->cache->symm_rot_mat.ptr(), r_area_co);
3134 /* Shift the plane for the current tile. */
3135 add_v3_v3(r_area_co, ss->cache->plane_offset);
3139 int SCULPT_plane_trim(const blender::ed::sculpt_paint::StrokeCache *cache,
3140 const Brush *brush,
3141 const float val[3])
3143 return (!(brush->flag & BRUSH_PLANE_TRIM) ||
3144 (dot_v3v3(val, val) <= cache->radius_squared * cache->plane_trim_squared));
3147 int SCULPT_plane_point_side(const float co[3], const float plane[4])
3149 float d = plane_point_side_v3(plane, co);
3150 return d <= 0.0f;
3153 float SCULPT_brush_plane_offset_get(Sculpt *sd, SculptSession *ss)
3155 Brush *brush = BKE_paint_brush(&sd->paint);
3157 float rv = brush->plane_offset;
3159 if (brush->flag & BRUSH_OFFSET_PRESSURE) {
3160 rv *= ss->cache->pressure;
3163 return rv;
3166 /** \} */
3168 /* -------------------------------------------------------------------- */
3169 /** \name Sculpt Gravity Brush
3170 * \{ */
3172 static void do_gravity_task(SculptSession *ss,
3173 const Brush *brush,
3174 const float *offset,
3175 PBVHNode *node)
3177 PBVHVertexIter vd;
3178 const MutableSpan<float3> proxy = BKE_pbvh_node_add_proxy(*ss->pbvh, *node).co;
3180 SculptBrushTest test;
3181 SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape(
3182 ss, &test, brush->falloff_shape);
3183 const int thread_id = BLI_task_parallel_thread_id(nullptr);
3185 BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
3186 if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
3187 continue;
3189 const float fade = SCULPT_brush_strength_factor(
3190 ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, vd.mask, vd.vertex, thread_id, nullptr);
3192 mul_v3_v3fl(proxy[vd.i], offset, fade);
3194 BKE_pbvh_vertex_iter_end;
3197 static void do_gravity(Sculpt *sd, Object *ob, Span<PBVHNode *> nodes, float bstrength)
3199 using namespace blender;
3200 SculptSession *ss = ob->sculpt;
3201 Brush *brush = BKE_paint_brush(&sd->paint);
3203 float offset[3];
3204 float gravity_vector[3];
3206 mul_v3_v3fl(gravity_vector, ss->cache->gravity_direction, -ss->cache->radius_squared);
3208 /* Offset with as much as possible factored in already. */
3209 mul_v3_v3v3(offset, gravity_vector, ss->cache->scale);
3210 mul_v3_fl(offset, bstrength);
3212 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
3213 for (const int i : range) {
3214 do_gravity_task(ss, brush, offset, nodes[i]);
3219 /** \} */
3221 /* -------------------------------------------------------------------- */
3222 /** \name Sculpt Brush Utilities
3223 * \{ */
3225 void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const Span<float3> vertCos)
3227 Mesh *mesh = (Mesh *)ob->data;
3228 float(*ofs)[3] = nullptr;
3229 int a, currkey_i;
3230 const int kb_act_idx = ob->shapenr - 1;
3232 /* For relative keys editing of base should update other keys. */
3233 if (bool *dependent = BKE_keyblock_get_dependent_keys(mesh->key, kb_act_idx)) {
3234 ofs = BKE_keyblock_convert_to_vertcos(ob, kb);
3236 /* Calculate key coord offsets (from previous location). */
3237 for (a = 0; a < mesh->verts_num; a++) {
3238 sub_v3_v3v3(ofs[a], vertCos[a], ofs[a]);
3241 /* Apply offsets on other keys. */
3242 LISTBASE_FOREACH_INDEX (KeyBlock *, currkey, &mesh->key->block, currkey_i) {
3243 if ((currkey != kb) && dependent[currkey_i]) {
3244 BKE_keyblock_update_from_offset(ob, currkey, ofs);
3248 MEM_freeN(ofs);
3249 MEM_freeN(dependent);
3252 /* Modifying of basis key should update mesh. */
3253 if (kb == mesh->key->refkey) {
3254 mesh->vert_positions_for_write().copy_from(vertCos);
3255 mesh->tag_positions_changed();
3258 /* Apply new coords on active key block, no need to re-allocate kb->data here! */
3259 BKE_keyblock_update_from_vertcos(ob, kb, reinterpret_cast<const float(*)[3]>(vertCos.data()));
3262 namespace blender::ed::sculpt_paint {
3264 /* NOTE: we do the topology update before any brush actions to avoid
3265 * issues with the proxies. The size of the proxy can't change, so
3266 * topology must be updated first. */
3267 static void sculpt_topology_update(Sculpt *sd,
3268 Object *ob,
3269 Brush *brush,
3270 UnifiedPaintSettings * /*ups*/,
3271 PaintModeSettings * /*paint_mode_settings*/)
3273 SculptSession *ss = ob->sculpt;
3275 /* Build a list of all nodes that are potentially within the brush's area of influence. */
3276 const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
3277 !ss->cache->accum;
3278 const float radius_scale = 1.25f;
3279 Vector<PBVHNode *> nodes = sculpt_pbvh_gather_generic(ob, brush, use_original, radius_scale);
3281 /* Only act if some verts are inside the brush area. */
3282 if (nodes.is_empty()) {
3283 return;
3286 /* Free index based vertex info as it will become invalid after modifying the topology during the
3287 * stroke. */
3288 ss->vertex_info.boundary.clear();
3290 PBVHTopologyUpdateMode mode = PBVHTopologyUpdateMode(0);
3291 float location[3];
3293 if (!(sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL)) {
3294 if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
3295 mode |= PBVH_Subdivide;
3298 if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) {
3299 mode |= PBVH_Collapse;
3303 for (PBVHNode *node : nodes) {
3304 undo::push_node(*ob,
3305 node,
3306 brush->sculpt_tool == SCULPT_TOOL_MASK ? undo::Type::Mask :
3307 undo::Type::Position);
3308 BKE_pbvh_node_mark_update(node);
3310 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
3311 BKE_pbvh_node_mark_topology_update(node);
3312 BKE_pbvh_bmesh_node_save_orig(ss->bm, ss->bm_log, node, false);
3316 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
3317 bke::pbvh::bmesh_update_topology(ss->pbvh,
3318 mode,
3319 ss->cache->location,
3320 ss->cache->view_normal,
3321 ss->cache->radius,
3322 (brush->flag & BRUSH_FRONTFACE) != 0,
3323 (brush->falloff_shape != PAINT_FALLOFF_SHAPE_SPHERE));
3326 /* Update average stroke position. */
3327 copy_v3_v3(location, ss->cache->true_location);
3328 mul_m4_v3(ob->object_to_world().ptr(), location);
3331 static void do_brush_action_task(Object *ob, const Brush *brush, PBVHNode *node)
3333 SculptSession *ss = ob->sculpt;
3335 bool need_coords = ss->cache->supports_gravity;
3337 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) {
3338 BKE_pbvh_node_mark_update_face_sets(node);
3340 /* Draw face sets in smooth mode moves the vertices. */
3341 if (ss->cache->alt_smooth) {
3342 need_coords = true;
3344 else {
3345 undo::push_node(*ob, node, undo::Type::FaceSet);
3348 else if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
3349 undo::push_node(*ob, node, undo::Type::Mask);
3350 BKE_pbvh_node_mark_update_mask(node);
3352 else if (SCULPT_tool_is_paint(brush->sculpt_tool)) {
3353 undo::push_node(*ob, node, undo::Type::Color);
3354 BKE_pbvh_node_mark_update_color(node);
3356 else {
3357 need_coords = true;
3360 if (need_coords) {
3361 undo::push_node(*ob, node, undo::Type::Position);
3362 BKE_pbvh_node_mark_update(node);
3366 static void do_brush_action(Sculpt *sd,
3367 Object *ob,
3368 Brush *brush,
3369 UnifiedPaintSettings *ups,
3370 PaintModeSettings *paint_mode_settings)
3372 SculptSession *ss = ob->sculpt;
3373 Vector<PBVHNode *> nodes, texnodes;
3375 /* Check for unsupported features. */
3376 PBVHType type = BKE_pbvh_type(ss->pbvh);
3378 if (SCULPT_tool_is_paint(brush->sculpt_tool) && SCULPT_has_loop_colors(ob)) {
3379 if (type != PBVH_FACES) {
3380 return;
3383 BKE_pbvh_ensure_node_loops(ss->pbvh);
3386 const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true :
3387 !ss->cache->accum;
3388 const bool use_pixels = sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob);
3390 if (sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) {
3391 sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob);
3393 texnodes = sculpt_pbvh_gather_texpaint(ob, brush, use_original, 1.0f);
3395 if (texnodes.is_empty()) {
3396 return;
3400 /* Build a list of all nodes that are potentially within the brush's area of influence */
3402 if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
3403 /* These brushes need to update all nodes as they are not constrained by the brush radius */
3404 nodes = bke::pbvh::search_gather(ss->pbvh, {});
3406 else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
3407 nodes = cloth::brush_affected_nodes_gather(ss, brush);
3409 else {
3410 float radius_scale = 1.0f;
3412 /* Corners of square brushes can go outside the brush radius. */
3413 if (BKE_brush_has_cube_tip(brush, PaintMode::Sculpt)) {
3414 radius_scale = M_SQRT2;
3417 /* With these options enabled not all required nodes are inside the original brush radius, so
3418 * the brush can produce artifacts in some situations. */
3419 if (brush->sculpt_tool == SCULPT_TOOL_DRAW && brush->flag & BRUSH_ORIGINAL_NORMAL) {
3420 radius_scale = 2.0f;
3422 nodes = sculpt_pbvh_gather_generic(ob, brush, use_original, radius_scale);
3425 /* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the
3426 * vertices and uses regular coords undo. */
3427 /* It also assigns the paint_face_set here as it needs to be done regardless of the stroke type
3428 * and the number of nodes under the brush influence. */
3429 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS &&
3430 SCULPT_stroke_is_first_brush_step(ss->cache) && !ss->cache->alt_smooth)
3432 if (ss->cache->invert) {
3433 /* When inverting the brush, pick the paint face mask ID from the mesh. */
3434 ss->cache->paint_face_set = face_set::active_face_set_get(ss);
3436 else {
3437 /* By default create a new Face Sets. */
3438 ss->cache->paint_face_set = face_set::find_next_available_id(*ob);
3442 /* For anchored brushes with spherical falloff, we start off with zero radius, thus we have no
3443 * PBVH nodes on the first brush step. */
3444 if (!nodes.is_empty() ||
3445 ((brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) && (brush->flag & BRUSH_ANCHORED)))
3447 if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
3448 /* Initialize auto-masking cache. */
3449 if (auto_mask::is_enabled(sd, ss, brush)) {
3450 ss->cache->automasking = auto_mask::cache_init(sd, brush, ob);
3451 ss->last_automasking_settings_hash = auto_mask::settings_hash(*ob,
3452 *ss->cache->automasking);
3454 /* Initialize surface smooth cache. */
3455 if ((brush->sculpt_tool == SCULPT_TOOL_SMOOTH) &&
3456 (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE))
3458 BLI_assert(ss->cache->surface_smooth_laplacian_disp == nullptr);
3459 ss->cache->surface_smooth_laplacian_disp = static_cast<float(*)[3]>(
3460 MEM_callocN(sizeof(float[3]) * SCULPT_vertex_count_get(ss), "HC smooth laplacian b"));
3465 /* Only act if some verts are inside the brush area. */
3466 if (nodes.is_empty()) {
3467 return;
3469 float location[3];
3471 if (!use_pixels) {
3472 threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
3473 for (const int i : range) {
3474 do_brush_action_task(ob, brush, nodes[i]);
3479 if (sculpt_brush_needs_normal(ss, sd, brush)) {
3480 update_sculpt_normal(sd, ob, nodes);
3483 update_brush_local_mat(sd, ob);
3485 if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
3486 pose::pose_brush_init(ob, ss, brush);
3489 if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
3490 if (!ss->cache->cloth_sim) {
3491 ss->cache->cloth_sim = cloth::brush_simulation_create(ob, 1.0f, 0.0f, 0.0f, false, true);
3492 cloth::brush_simulation_init(ss, ss->cache->cloth_sim);
3494 cloth::brush_store_simulation_state(ss, ss->cache->cloth_sim);
3495 cloth::ensure_nodes_constraints(
3496 sd, ob, nodes, ss->cache->cloth_sim, ss->cache->location, FLT_MAX);
3499 bool invert = ss->cache->pen_flip || ss->cache->invert;
3500 if (brush->flag & BRUSH_DIR_IN) {
3501 invert = !invert;
3504 /* Apply one type of brush action. */
3505 switch (brush->sculpt_tool) {
3506 case SCULPT_TOOL_DRAW:
3507 SCULPT_do_draw_brush(sd, ob, nodes);
3508 break;
3509 case SCULPT_TOOL_SMOOTH:
3510 if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
3511 smooth::do_smooth_brush(sd, ob, nodes);
3513 else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
3514 smooth::do_surface_smooth_brush(sd, ob, nodes);
3516 break;
3517 case SCULPT_TOOL_CREASE:
3518 SCULPT_do_crease_brush(sd, ob, nodes);
3519 break;
3520 case SCULPT_TOOL_BLOB:
3521 SCULPT_do_crease_brush(sd, ob, nodes);
3522 break;
3523 case SCULPT_TOOL_PINCH:
3524 SCULPT_do_pinch_brush(sd, ob, nodes);
3525 break;
3526 case SCULPT_TOOL_INFLATE:
3527 SCULPT_do_inflate_brush(sd, ob, nodes);
3528 break;
3529 case SCULPT_TOOL_GRAB:
3530 SCULPT_do_grab_brush(sd, ob, nodes);
3531 break;
3532 case SCULPT_TOOL_ROTATE:
3533 SCULPT_do_rotate_brush(sd, ob, nodes);
3534 break;
3535 case SCULPT_TOOL_SNAKE_HOOK:
3536 SCULPT_do_snake_hook_brush(sd, ob, nodes);
3537 break;
3538 case SCULPT_TOOL_NUDGE:
3539 SCULPT_do_nudge_brush(sd, ob, nodes);
3540 break;
3541 case SCULPT_TOOL_THUMB:
3542 SCULPT_do_thumb_brush(sd, ob, nodes);
3543 break;
3544 case SCULPT_TOOL_LAYER:
3545 SCULPT_do_layer_brush(sd, ob, nodes);
3546 break;
3547 case SCULPT_TOOL_FLATTEN:
3548 SCULPT_do_flatten_brush(sd, ob, nodes);
3549 break;
3550 case SCULPT_TOOL_CLAY:
3551 SCULPT_do_clay_brush(sd, ob, nodes);
3552 break;
3553 case SCULPT_TOOL_CLAY_STRIPS:
3554 SCULPT_do_clay_strips_brush(sd, ob, nodes);
3555 break;
3556 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
3557 SCULPT_do_multiplane_scrape_brush(sd, ob, nodes);
3558 break;
3559 case SCULPT_TOOL_CLAY_THUMB:
3560 SCULPT_do_clay_thumb_brush(sd, ob, nodes);
3561 break;
3562 case SCULPT_TOOL_FILL:
3563 if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
3564 SCULPT_do_scrape_brush(sd, ob, nodes);
3566 else {
3567 SCULPT_do_fill_brush(sd, ob, nodes);
3569 break;
3570 case SCULPT_TOOL_SCRAPE:
3571 if (invert && brush->flag & BRUSH_INVERT_TO_SCRAPE_FILL) {
3572 SCULPT_do_fill_brush(sd, ob, nodes);
3574 else {
3575 SCULPT_do_scrape_brush(sd, ob, nodes);
3577 break;
3578 case SCULPT_TOOL_MASK:
3579 SCULPT_do_mask_brush(sd, ob, nodes);
3580 break;
3581 case SCULPT_TOOL_POSE:
3582 pose::do_pose_brush(sd, ob, nodes);
3583 break;
3584 case SCULPT_TOOL_DRAW_SHARP:
3585 SCULPT_do_draw_sharp_brush(sd, ob, nodes);
3586 break;
3587 case SCULPT_TOOL_ELASTIC_DEFORM:
3588 SCULPT_do_elastic_deform_brush(sd, ob, nodes);
3589 break;
3590 case SCULPT_TOOL_SLIDE_RELAX:
3591 SCULPT_do_slide_relax_brush(sd, ob, nodes);
3592 break;
3593 case SCULPT_TOOL_BOUNDARY:
3594 boundary::do_boundary_brush(sd, ob, nodes);
3595 break;
3596 case SCULPT_TOOL_CLOTH:
3597 cloth::do_cloth_brush(sd, ob, nodes);
3598 break;
3599 case SCULPT_TOOL_DRAW_FACE_SETS:
3600 face_set::do_draw_face_sets_brush(sd, ob, nodes);
3601 break;
3602 case SCULPT_TOOL_DISPLACEMENT_ERASER:
3603 SCULPT_do_displacement_eraser_brush(sd, ob, nodes);
3604 break;
3605 case SCULPT_TOOL_DISPLACEMENT_SMEAR:
3606 SCULPT_do_displacement_smear_brush(sd, ob, nodes);
3607 break;
3608 case SCULPT_TOOL_PAINT:
3609 color::do_paint_brush(paint_mode_settings, sd, ob, nodes, texnodes);
3610 break;
3611 case SCULPT_TOOL_SMEAR:
3612 color::do_smear_brush(sd, ob, nodes);
3613 break;
3616 if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
3617 brush->autosmooth_factor > 0)
3619 if (brush->flag & BRUSH_INVERSE_SMOOTH_PRESSURE) {
3620 smooth::do_smooth_brush(
3621 sd, ob, nodes, brush->autosmooth_factor * (1.0f - ss->cache->pressure));
3623 else {
3624 smooth::do_smooth_brush(sd, ob, nodes, brush->autosmooth_factor);
3628 if (sculpt_brush_use_topology_rake(ss, brush)) {
3629 SCULPT_bmesh_topology_rake(sd, ob, nodes, brush->topology_rake_factor);
3632 if (!auto_mask::tool_can_reuse_automask(brush->sculpt_tool) ||
3633 (ss->cache->supports_gravity && sd->gravity_factor > 0.0f))
3635 /* Clear cavity mask cache. */
3636 ss->last_automasking_settings_hash = 0;
3639 /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */
3640 if (ss->cache->supports_gravity &&
3641 !ELEM(
3642 brush->sculpt_tool, SCULPT_TOOL_CLOTH, SCULPT_TOOL_DRAW_FACE_SETS, SCULPT_TOOL_BOUNDARY))
3644 do_gravity(sd, ob, nodes, sd->gravity_factor);
3647 if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) {
3648 if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
3649 cloth::sim_activate_nodes(ss->cache->cloth_sim, nodes);
3650 cloth::do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes);
3654 /* Update average stroke position. */
3655 copy_v3_v3(location, ss->cache->true_location);
3656 mul_m4_v3(ob->object_to_world().ptr(), location);
3658 add_v3_v3(ups->average_stroke_accum, location);
3659 ups->average_stroke_counter++;
3660 /* Update last stroke position. */
3661 ups->last_stroke_valid = true;
3664 /* Flush displacement from deformed PBVH vertex to original mesh. */
3665 static void sculpt_flush_pbvhvert_deform(SculptSession &ss,
3666 const PBVHVertexIter &vd,
3667 MutableSpan<float3> positions)
3669 float disp[3], newco[3];
3670 int index = vd.vert_indices[vd.i];
3672 sub_v3_v3v3(disp, vd.co, ss.deform_cos[index]);
3673 mul_m3_v3(ss.deform_imats[index].ptr(), disp);
3674 add_v3_v3v3(newco, disp, ss.orig_cos[index]);
3676 ss.deform_cos[index] = vd.co;
3677 ss.orig_cos[index] = newco;
3679 if (!ss.shapekey_active) {
3680 copy_v3_v3(positions[index], newco);
3684 static void sculpt_combine_proxies_node(Object &object,
3685 Sculpt &sd,
3686 const bool use_orco,
3687 PBVHNode &node)
3689 SculptSession *ss = object.sculpt;
3691 float(*orco)[3] = nullptr;
3692 if (use_orco && !ss->bm) {
3693 orco = reinterpret_cast<float(*)[3]>(
3694 (undo::push_node(object, &node, undo::Type::Position)->position.data()));
3697 MutableSpan<PBVHProxyNode> proxies = BKE_pbvh_node_get_proxies(&node);
3699 Mesh &mesh = *static_cast<Mesh *>(object.data);
3700 MutableSpan<float3> positions = mesh.vert_positions_for_write();
3702 PBVHVertexIter vd;
3703 BKE_pbvh_vertex_iter_begin (ss->pbvh, &node, vd, PBVH_ITER_UNIQUE) {
3704 float val[3];
3706 if (use_orco) {
3707 if (ss->bm) {
3708 copy_v3_v3(val, BM_log_original_vert_co(ss->bm_log, vd.bm_vert));
3710 else {
3711 copy_v3_v3(val, orco[vd.i]);
3714 else {
3715 copy_v3_v3(val, vd.co);
3718 for (const PBVHProxyNode &proxy_node : proxies) {
3719 add_v3_v3(val, proxy_node.co[vd.i]);
3722 SCULPT_clip(&sd, ss, vd.co, val);
3724 if (ss->deform_modifiers_active) {
3725 sculpt_flush_pbvhvert_deform(*ss, vd, positions);
3728 BKE_pbvh_vertex_iter_end;
3730 BKE_pbvh_node_free_proxies(&node);
3733 static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
3735 SculptSession *ss = ob->sculpt;
3736 Brush *brush = BKE_paint_brush(&sd->paint);
3738 if (!ss->cache->supports_gravity && sculpt_tool_is_proxy_used(brush->sculpt_tool)) {
3739 /* First line is tools that don't support proxies. */
3740 return;
3743 /* First line is tools that don't support proxies. */
3744 const bool use_orco = ELEM(brush->sculpt_tool,
3745 SCULPT_TOOL_GRAB,
3746 SCULPT_TOOL_ROTATE,
3747 SCULPT_TOOL_THUMB,
3748 SCULPT_TOOL_ELASTIC_DEFORM,
3749 SCULPT_TOOL_BOUNDARY,
3750 SCULPT_TOOL_POSE);
3752 Vector<PBVHNode *> nodes = bke::pbvh::gather_proxies(ss->pbvh);
3754 threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
3755 for (const int i : range) {
3756 sculpt_combine_proxies_node(*ob, *sd, use_orco, *nodes[i]);
3761 } // namespace blender::ed::sculpt_paint
3763 void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob)
3765 using namespace blender;
3766 using namespace blender::ed::sculpt_paint;
3767 SculptSession *ss = ob->sculpt;
3769 Vector<PBVHNode *> nodes = bke::pbvh::gather_proxies(ss->pbvh);
3771 threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
3772 for (const int i : range) {
3773 sculpt_combine_proxies_node(*ob, *sd, false, *nodes[i]);
3779 * Copy the modified vertices from the #PBVH to the active key.
3781 static void sculpt_update_keyblock(Object *ob)
3783 SculptSession *ss = ob->sculpt;
3785 /* Key-block update happens after handling deformation caused by modifiers,
3786 * so ss->orig_cos would be updated with new stroke. */
3787 if (!ss->orig_cos.is_empty()) {
3788 SCULPT_vertcos_to_key(ob, ss->shapekey_active, ss->orig_cos);
3790 else {
3791 SCULPT_vertcos_to_key(ob, ss->shapekey_active, BKE_pbvh_get_vert_positions(ss->pbvh));
3795 void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used)
3797 using namespace blender;
3798 using namespace blender::ed::sculpt_paint;
3799 SculptSession *ss = ob->sculpt;
3801 if (is_proxy_used && ss->deform_modifiers_active) {
3802 /* This brushes aren't using proxies, so sculpt_combine_proxies() wouldn't propagate needed
3803 * deformation to original base. */
3805 Mesh *mesh = (Mesh *)ob->data;
3806 Vector<PBVHNode *> nodes;
3807 Array<float3> vertCos;
3809 if (ss->shapekey_active) {
3810 /* Mesh could have isolated verts which wouldn't be in BVH, to deal with this we copy old
3811 * coordinates over new ones and then update coordinates for all vertices from BVH. */
3812 vertCos = ss->orig_cos;
3815 nodes = bke::pbvh::search_gather(ss->pbvh, {});
3817 MutableSpan<float3> positions = mesh->vert_positions_for_write();
3819 threading::parallel_for(nodes.index_range(), 1, [&](IndexRange range) {
3820 for (const int i : range) {
3821 PBVHVertexIter vd;
3822 BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) {
3823 sculpt_flush_pbvhvert_deform(*ss, vd, positions);
3825 if (vertCos.is_empty()) {
3826 continue;
3829 int index = vd.vert_indices[vd.i];
3830 copy_v3_v3(vertCos[index], ss->orig_cos[index]);
3832 BKE_pbvh_vertex_iter_end;
3836 if (!vertCos.is_empty()) {
3837 SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
3840 else if (ss->shapekey_active) {
3841 sculpt_update_keyblock(ob);
3845 void SCULPT_cache_calc_brushdata_symm(blender::ed::sculpt_paint::StrokeCache *cache,
3846 const ePaintSymmetryFlags symm,
3847 const char axis,
3848 const float angle)
3850 using namespace blender;
3851 flip_v3_v3(cache->location, cache->true_location, symm);
3852 flip_v3_v3(cache->last_location, cache->true_last_location, symm);
3853 flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm);
3854 flip_v3_v3(cache->view_normal, cache->true_view_normal, symm);
3856 flip_v3_v3(cache->initial_location, cache->true_initial_location, symm);
3857 flip_v3_v3(cache->initial_normal, cache->true_initial_normal, symm);
3859 /* XXX This reduces the length of the grab delta if it approaches the line of symmetry
3860 * XXX However, a different approach appears to be needed. */
3861 #if 0
3862 if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) {
3863 float frac = 1.0f / max_overlap_count(sd);
3864 float reduce = (feather - frac) / (1.0f - frac);
3866 printf("feather: %f frac: %f reduce: %f\n", feather, frac, reduce);
3868 if (frac < 1.0f) {
3869 mul_v3_fl(cache->grab_delta_symmetry, reduce);
3872 #endif
3874 cache->symm_rot_mat = float4x4::identity();
3875 cache->symm_rot_mat_inv = float4x4::identity();
3876 zero_v3(cache->plane_offset);
3878 /* Expects XYZ. */
3879 if (axis) {
3880 rotate_m4(cache->symm_rot_mat.ptr(), axis, angle);
3881 rotate_m4(cache->symm_rot_mat_inv.ptr(), axis, -angle);
3884 mul_m4_v3(cache->symm_rot_mat.ptr(), cache->location);
3885 mul_m4_v3(cache->symm_rot_mat.ptr(), cache->grab_delta_symmetry);
3887 if (cache->supports_gravity) {
3888 flip_v3_v3(cache->gravity_direction, cache->true_gravity_direction, symm);
3889 mul_m4_v3(cache->symm_rot_mat.ptr(), cache->gravity_direction);
3892 if (cache->is_rake_rotation_valid) {
3893 flip_qt_qt(cache->rake_rotation_symmetry, cache->rake_rotation, symm);
3897 namespace blender::ed::sculpt_paint {
3899 using BrushActionFunc = void (*)(Sculpt *sd,
3900 Object *ob,
3901 Brush *brush,
3902 UnifiedPaintSettings *ups,
3903 PaintModeSettings *paint_mode_settings);
3905 static void do_tiled(Sculpt *sd,
3906 Object *ob,
3907 Brush *brush,
3908 UnifiedPaintSettings *ups,
3909 PaintModeSettings *paint_mode_settings,
3910 BrushActionFunc action)
3912 SculptSession *ss = ob->sculpt;
3913 StrokeCache *cache = ss->cache;
3914 const float radius = cache->radius;
3915 const Bounds<float3> bb = *BKE_object_boundbox_get(ob);
3916 const float *bbMin = bb.min;
3917 const float *bbMax = bb.max;
3918 const float *step = sd->paint.tile_offset;
3920 /* These are integer locations, for real location: multiply with step and add orgLoc.
3921 * So 0,0,0 is at orgLoc. */
3922 int start[3];
3923 int end[3];
3924 int cur[3];
3926 /* Position of the "prototype" stroke for tiling. */
3927 float orgLoc[3];
3928 float original_initial_location[3];
3929 copy_v3_v3(orgLoc, cache->location);
3930 copy_v3_v3(original_initial_location, cache->initial_location);
3932 for (int dim = 0; dim < 3; dim++) {
3933 if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
3934 start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
3935 end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
3937 else {
3938 start[dim] = end[dim] = 0;
3942 /* First do the "un-tiled" position to initialize the stroke for this location. */
3943 cache->tile_pass = 0;
3944 action(sd, ob, brush, ups, paint_mode_settings);
3946 /* Now do it for all the tiles. */
3947 copy_v3_v3_int(cur, start);
3948 for (cur[0] = start[0]; cur[0] <= end[0]; cur[0]++) {
3949 for (cur[1] = start[1]; cur[1] <= end[1]; cur[1]++) {
3950 for (cur[2] = start[2]; cur[2] <= end[2]; cur[2]++) {
3951 if (!cur[0] && !cur[1] && !cur[2]) {
3952 /* Skip tile at orgLoc, this was already handled before all others. */
3953 continue;
3956 ++cache->tile_pass;
3958 for (int dim = 0; dim < 3; dim++) {
3959 cache->location[dim] = cur[dim] * step[dim] + orgLoc[dim];
3960 cache->plane_offset[dim] = cur[dim] * step[dim];
3961 cache->initial_location[dim] = cur[dim] * step[dim] + original_initial_location[dim];
3963 action(sd, ob, brush, ups, paint_mode_settings);
3969 static void do_radial_symmetry(Sculpt *sd,
3970 Object *ob,
3971 Brush *brush,
3972 UnifiedPaintSettings *ups,
3973 PaintModeSettings *paint_mode_settings,
3974 BrushActionFunc action,
3975 const ePaintSymmetryFlags symm,
3976 const int axis,
3977 const float /*feather*/)
3979 SculptSession *ss = ob->sculpt;
3981 for (int i = 1; i < sd->radial_symm[axis - 'X']; i++) {
3982 const float angle = 2.0f * M_PI * i / sd->radial_symm[axis - 'X'];
3983 ss->cache->radial_symmetry_pass = i;
3984 SCULPT_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
3985 do_tiled(sd, ob, brush, ups, paint_mode_settings, action);
3990 * Noise texture gives different values for the same input coord; this
3991 * can tear a multi-resolution mesh during sculpting so do a stitch in this case.
3993 static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
3995 SculptSession *ss = ob->sculpt;
3996 Brush *brush = BKE_paint_brush(&sd->paint);
3997 const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
3999 if (ss->multires.active && mtex->tex && mtex->tex->type == TEX_NOISE) {
4000 multires_stitch_grids(ob);
4004 static void do_symmetrical_brush_actions(Sculpt *sd,
4005 Object *ob,
4006 BrushActionFunc action,
4007 UnifiedPaintSettings *ups,
4008 PaintModeSettings *paint_mode_settings)
4010 Brush *brush = BKE_paint_brush(&sd->paint);
4011 SculptSession *ss = ob->sculpt;
4012 StrokeCache *cache = ss->cache;
4013 const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
4015 float feather = calc_symmetry_feather(sd, ss->cache);
4017 cache->bstrength = brush_strength(sd, cache, feather, ups, paint_mode_settings);
4018 cache->symmetry = symm;
4020 /* `symm` is a bit combination of XYZ -
4021 * 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
4022 for (int i = 0; i <= symm; i++) {
4023 if (!SCULPT_is_symmetry_iteration_valid(i, symm)) {
4024 continue;
4026 const ePaintSymmetryFlags symm = ePaintSymmetryFlags(i);
4027 cache->mirror_symmetry_pass = symm;
4028 cache->radial_symmetry_pass = 0;
4030 SCULPT_cache_calc_brushdata_symm(cache, symm, 0, 0);
4031 do_tiled(sd, ob, brush, ups, paint_mode_settings, action);
4033 do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'X', feather);
4034 do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'Y', feather);
4035 do_radial_symmetry(sd, ob, brush, ups, paint_mode_settings, action, symm, 'Z', feather);
4039 } // namespace blender::ed::sculpt_paint
4041 bool SCULPT_mode_poll(bContext *C)
4043 Object *ob = CTX_data_active_object(C);
4044 return ob && ob->mode & OB_MODE_SCULPT;
4047 bool SCULPT_mode_poll_view3d(bContext *C)
4049 using namespace blender::ed::sculpt_paint;
4050 return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C) && !ED_gpencil_session_active());
4053 bool SCULPT_poll(bContext *C)
4055 using namespace blender::ed::sculpt_paint;
4056 return SCULPT_mode_poll(C) && blender::ed::sculpt_paint::paint_brush_tool_poll(C);
4059 static const char *sculpt_tool_name(Sculpt *sd)
4061 Brush *brush = BKE_paint_brush(&sd->paint);
4063 switch ((eBrushSculptTool)brush->sculpt_tool) {
4064 case SCULPT_TOOL_DRAW:
4065 return "Draw Brush";
4066 case SCULPT_TOOL_SMOOTH:
4067 return "Smooth Brush";
4068 case SCULPT_TOOL_CREASE:
4069 return "Crease Brush";
4070 case SCULPT_TOOL_BLOB:
4071 return "Blob Brush";
4072 case SCULPT_TOOL_PINCH:
4073 return "Pinch Brush";
4074 case SCULPT_TOOL_INFLATE:
4075 return "Inflate Brush";
4076 case SCULPT_TOOL_GRAB:
4077 return "Grab Brush";
4078 case SCULPT_TOOL_NUDGE:
4079 return "Nudge Brush";
4080 case SCULPT_TOOL_THUMB:
4081 return "Thumb Brush";
4082 case SCULPT_TOOL_LAYER:
4083 return "Layer Brush";
4084 case SCULPT_TOOL_FLATTEN:
4085 return "Flatten Brush";
4086 case SCULPT_TOOL_CLAY:
4087 return "Clay Brush";
4088 case SCULPT_TOOL_CLAY_STRIPS:
4089 return "Clay Strips Brush";
4090 case SCULPT_TOOL_CLAY_THUMB:
4091 return "Clay Thumb Brush";
4092 case SCULPT_TOOL_FILL:
4093 return "Fill Brush";
4094 case SCULPT_TOOL_SCRAPE:
4095 return "Scrape Brush";
4096 case SCULPT_TOOL_SNAKE_HOOK:
4097 return "Snake Hook Brush";
4098 case SCULPT_TOOL_ROTATE:
4099 return "Rotate Brush";
4100 case SCULPT_TOOL_MASK:
4101 return "Mask Brush";
4102 case SCULPT_TOOL_SIMPLIFY:
4103 return "Simplify Brush";
4104 case SCULPT_TOOL_DRAW_SHARP:
4105 return "Draw Sharp Brush";
4106 case SCULPT_TOOL_ELASTIC_DEFORM:
4107 return "Elastic Deform Brush";
4108 case SCULPT_TOOL_POSE:
4109 return "Pose Brush";
4110 case SCULPT_TOOL_MULTIPLANE_SCRAPE:
4111 return "Multi-plane Scrape Brush";
4112 case SCULPT_TOOL_SLIDE_RELAX:
4113 return "Slide/Relax Brush";
4114 case SCULPT_TOOL_BOUNDARY:
4115 return "Boundary Brush";
4116 case SCULPT_TOOL_CLOTH:
4117 return "Cloth Brush";
4118 case SCULPT_TOOL_DRAW_FACE_SETS:
4119 return "Draw Face Sets";
4120 case SCULPT_TOOL_DISPLACEMENT_ERASER:
4121 return "Multires Displacement Eraser";
4122 case SCULPT_TOOL_DISPLACEMENT_SMEAR:
4123 return "Multires Displacement Smear";
4124 case SCULPT_TOOL_PAINT:
4125 return "Paint Brush";
4126 case SCULPT_TOOL_SMEAR:
4127 return "Smear Brush";
4130 return "Sculpting";
4133 /* Operator for applying a stroke (various attributes including mouse path)
4134 * using the current brush. */
4136 void SCULPT_cache_free(blender::ed::sculpt_paint::StrokeCache *cache)
4138 using namespace blender::ed::sculpt_paint;
4139 MEM_SAFE_FREE(cache->dial);
4140 MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp);
4141 MEM_SAFE_FREE(cache->layer_displacement_factor);
4142 MEM_SAFE_FREE(cache->prev_colors);
4143 MEM_SAFE_FREE(cache->detail_directions);
4144 MEM_SAFE_FREE(cache->prev_displacement);
4145 MEM_SAFE_FREE(cache->limit_surface_co);
4147 for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
4148 if (cache->boundaries[i]) {
4149 boundary::data_free(cache->boundaries[i]);
4153 if (cache->cloth_sim) {
4154 cloth::simulation_free(cache->cloth_sim);
4157 MEM_delete(cache);
4160 namespace blender::ed::sculpt_paint {
4162 /* Initialize mirror modifier clipping. */
4163 static void sculpt_init_mirror_clipping(Object *ob, SculptSession *ss)
4165 ss->cache->clip_mirror_mtx = float4x4::identity();
4167 LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
4168 if (!(md->type == eModifierType_Mirror && (md->mode & eModifierMode_Realtime))) {
4169 continue;
4171 MirrorModifierData *mmd = (MirrorModifierData *)md;
4173 if (!(mmd->flag & MOD_MIR_CLIPPING)) {
4174 continue;
4176 /* Check each axis for mirroring. */
4177 for (int i = 0; i < 3; i++) {
4178 if (!(mmd->flag & (MOD_MIR_AXIS_X << i))) {
4179 continue;
4181 /* Enable sculpt clipping. */
4182 ss->cache->flag |= CLIP_X << i;
4184 /* Update the clip tolerance. */
4185 if (mmd->tolerance > ss->cache->clip_tolerance[i]) {
4186 ss->cache->clip_tolerance[i] = mmd->tolerance;
4189 /* Store matrix for mirror object clipping. */
4190 if (mmd->mirror_ob) {
4191 float imtx_mirror_ob[4][4];
4192 invert_m4_m4(imtx_mirror_ob, mmd->mirror_ob->object_to_world().ptr());
4193 mul_m4_m4m4(ss->cache->clip_mirror_mtx.ptr(), imtx_mirror_ob, ob->object_to_world().ptr());
4199 static void smooth_brush_toggle_on(const bContext *C, Paint *paint, StrokeCache *cache)
4201 Scene *scene = CTX_data_scene(C);
4202 Brush *cur_brush = paint->brush;
4204 if (cur_brush->sculpt_tool == SCULPT_TOOL_MASK) {
4205 cache->saved_mask_brush_tool = cur_brush->mask_tool;
4206 cur_brush->mask_tool = BRUSH_MASK_SMOOTH;
4207 return;
4210 if (ELEM(cur_brush->sculpt_tool,
4211 SCULPT_TOOL_SLIDE_RELAX,
4212 SCULPT_TOOL_DRAW_FACE_SETS,
4213 SCULPT_TOOL_PAINT,
4214 SCULPT_TOOL_SMEAR))
4216 /* Do nothing, this tool has its own smooth mode. */
4217 return;
4220 /* Switch to the smooth brush if possible. */
4221 Brush *smooth_brush = BKE_paint_toolslots_brush_get(paint, SCULPT_TOOL_SMOOTH);
4222 if (!smooth_brush) {
4223 CLOG_WARN(&LOG, "Switching to the smooth brush not possible, corresponding brush not");
4224 cache->saved_active_brush_name[0] = '\0';
4225 return;
4228 int cur_brush_size = BKE_brush_size_get(scene, cur_brush);
4230 STRNCPY(cache->saved_active_brush_name, cur_brush->id.name + 2);
4232 BKE_paint_brush_set(paint, smooth_brush);
4233 cache->saved_smooth_size = BKE_brush_size_get(scene, smooth_brush);
4234 BKE_brush_size_set(scene, smooth_brush, cur_brush_size);
4235 BKE_curvemapping_init(smooth_brush->curve);
4238 static void smooth_brush_toggle_off(const bContext *C, Paint *paint, StrokeCache *cache)
4240 Main *bmain = CTX_data_main(C);
4241 Brush *brush = BKE_paint_brush(paint);
4243 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
4244 brush->mask_tool = cache->saved_mask_brush_tool;
4245 return;
4248 if (ELEM(brush->sculpt_tool,
4249 SCULPT_TOOL_SLIDE_RELAX,
4250 SCULPT_TOOL_DRAW_FACE_SETS,
4251 SCULPT_TOOL_PAINT,
4252 SCULPT_TOOL_SMEAR))
4254 /* Do nothing. */
4255 return;
4258 /* If saved_active_brush_name is not set, brush was not switched/affected in
4259 * smooth_brush_toggle_on(). */
4260 Brush *saved_active_brush = (Brush *)BKE_libblock_find_name(
4261 bmain, ID_BR, cache->saved_active_brush_name);
4262 if (saved_active_brush) {
4263 Scene *scene = CTX_data_scene(C);
4264 BKE_brush_size_set(scene, brush, cache->saved_smooth_size);
4265 BKE_paint_brush_set(paint, saved_active_brush);
4269 /* Initialize the stroke cache invariants from operator properties. */
4270 static void sculpt_update_cache_invariants(
4271 bContext *C, Sculpt *sd, SculptSession *ss, wmOperator *op, const float mval[2])
4273 StrokeCache *cache = MEM_new<StrokeCache>(__func__);
4274 ToolSettings *tool_settings = CTX_data_tool_settings(C);
4275 UnifiedPaintSettings *ups = &tool_settings->unified_paint_settings;
4276 Brush *brush = BKE_paint_brush(&sd->paint);
4277 ViewContext *vc = paint_stroke_view_context(static_cast<PaintStroke *>(op->customdata));
4278 Object *ob = CTX_data_active_object(C);
4279 float mat[3][3];
4280 float viewDir[3] = {0.0f, 0.0f, 1.0f};
4281 float max_scale;
4282 int mode;
4284 ss->cache = cache;
4286 /* Set scaling adjustment. */
4287 max_scale = 0.0f;
4288 for (int i = 0; i < 3; i++) {
4289 max_scale = max_ff(max_scale, fabsf(ob->scale[i]));
4291 cache->scale[0] = max_scale / ob->scale[0];
4292 cache->scale[1] = max_scale / ob->scale[1];
4293 cache->scale[2] = max_scale / ob->scale[2];
4295 cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
4297 cache->flag = 0;
4299 sculpt_init_mirror_clipping(ob, ss);
4301 /* Initial mouse location. */
4302 if (mval) {
4303 copy_v2_v2(cache->initial_mouse, mval);
4305 else {
4306 zero_v2(cache->initial_mouse);
4309 copy_v3_v3(cache->initial_location, ss->cursor_location);
4310 copy_v3_v3(cache->true_initial_location, ss->cursor_location);
4312 copy_v3_v3(cache->initial_normal, ss->cursor_normal);
4313 copy_v3_v3(cache->true_initial_normal, ss->cursor_normal);
4315 mode = RNA_enum_get(op->ptr, "mode");
4316 cache->invert = mode == BRUSH_STROKE_INVERT;
4317 cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH;
4318 cache->normal_weight = brush->normal_weight;
4320 /* Interpret invert as following normal, for grab brushes. */
4321 if (SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool)) {
4322 if (cache->invert) {
4323 cache->invert = false;
4324 cache->normal_weight = (cache->normal_weight == 0.0f);
4328 /* Not very nice, but with current events system implementation
4329 * we can't handle brush appearance inversion hotkey separately (sergey). */
4330 if (cache->invert) {
4331 ups->draw_inverted = true;
4333 else {
4334 ups->draw_inverted = false;
4337 /* Alt-Smooth. */
4338 if (cache->alt_smooth) {
4339 smooth_brush_toggle_on(C, &sd->paint, cache);
4340 /* Refresh the brush pointer in case we switched brush in the toggle function. */
4341 brush = BKE_paint_brush(&sd->paint);
4344 copy_v2_v2(cache->mouse, cache->initial_mouse);
4345 copy_v2_v2(cache->mouse_event, cache->initial_mouse);
4346 copy_v2_v2(ups->tex_mouse, cache->initial_mouse);
4348 /* Truly temporary data that isn't stored in properties. */
4349 cache->vc = vc;
4350 cache->brush = brush;
4352 /* Cache projection matrix. */
4353 cache->projection_mat = ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob);
4355 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
4356 copy_m3_m4(mat, cache->vc->rv3d->viewinv);
4357 mul_m3_v3(mat, viewDir);
4358 copy_m3_m4(mat, ob->world_to_object().ptr());
4359 mul_m3_v3(mat, viewDir);
4360 normalize_v3_v3(cache->true_view_normal, viewDir);
4362 cache->supports_gravity = (!ELEM(brush->sculpt_tool,
4363 SCULPT_TOOL_MASK,
4364 SCULPT_TOOL_SMOOTH,
4365 SCULPT_TOOL_SIMPLIFY,
4366 SCULPT_TOOL_DISPLACEMENT_SMEAR,
4367 SCULPT_TOOL_DISPLACEMENT_ERASER) &&
4368 (sd->gravity_factor > 0.0f));
4369 /* Get gravity vector in world space. */
4370 if (cache->supports_gravity) {
4371 if (sd->gravity_object) {
4372 Object *gravity_object = sd->gravity_object;
4374 copy_v3_v3(cache->true_gravity_direction, gravity_object->object_to_world().ptr()[2]);
4376 else {
4377 cache->true_gravity_direction[0] = cache->true_gravity_direction[1] = 0.0f;
4378 cache->true_gravity_direction[2] = 1.0f;
4381 /* Transform to sculpted object space. */
4382 mul_m3_v3(mat, cache->true_gravity_direction);
4383 normalize_v3(cache->true_gravity_direction);
4386 cache->accum = true;
4388 /* Make copies of the mesh vertex locations and normals for some tools. */
4389 if (brush->flag & BRUSH_ANCHORED) {
4390 cache->accum = false;
4393 /* Draw sharp does not need the original coordinates to produce the accumulate effect, so it
4394 * should work the opposite way. */
4395 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_SHARP) {
4396 cache->accum = false;
4399 if (SCULPT_TOOL_HAS_ACCUMULATE(brush->sculpt_tool)) {
4400 if (!(brush->flag & BRUSH_ACCUMULATE)) {
4401 cache->accum = false;
4402 if (brush->sculpt_tool == SCULPT_TOOL_DRAW_SHARP) {
4403 cache->accum = true;
4408 /* Original coordinates require the sculpt undo system, which isn't used
4409 * for image brushes. It's also not necessary, just disable it. */
4410 if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
4411 SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob))
4413 cache->accum = true;
4416 cache->first_time = true;
4418 #define PIXEL_INPUT_THRESHHOLD 5
4419 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
4420 cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD);
4423 #undef PIXEL_INPUT_THRESHHOLD
4426 static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, float initial_size)
4428 switch (brush->sculpt_tool) {
4429 case SCULPT_TOOL_CLAY:
4430 return max_ff(initial_size * 0.20f, initial_size * pow3f(cache->pressure));
4431 case SCULPT_TOOL_CLAY_STRIPS:
4432 return max_ff(initial_size * 0.30f, initial_size * powf(cache->pressure, 1.5f));
4433 case SCULPT_TOOL_CLAY_THUMB: {
4434 float clay_stabilized_pressure = SCULPT_clay_thumb_get_stabilized_pressure(cache);
4435 return initial_size * clay_stabilized_pressure;
4437 default:
4438 return initial_size * cache->pressure;
4442 /* In these brushes the grab delta is calculated always from the initial stroke location, which is
4443 * generally used to create grab deformations. */
4444 static bool sculpt_needs_delta_from_anchored_origin(Brush *brush)
4446 if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && (brush->flag & BRUSH_ANCHORED)) {
4447 return true;
4450 if (ELEM(brush->sculpt_tool,
4451 SCULPT_TOOL_GRAB,
4452 SCULPT_TOOL_POSE,
4453 SCULPT_TOOL_BOUNDARY,
4454 SCULPT_TOOL_THUMB,
4455 SCULPT_TOOL_ELASTIC_DEFORM))
4457 return true;
4459 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
4460 brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB)
4462 return true;
4464 return false;
4467 /* In these brushes the grab delta is calculated from the previous stroke location, which is used
4468 * to calculate to orientate the brush tip and deformation towards the stroke direction. */
4469 static bool sculpt_needs_delta_for_tip_orientation(Brush *brush)
4471 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
4472 return brush->cloth_deform_type != BRUSH_CLOTH_DEFORM_GRAB;
4474 return ELEM(brush->sculpt_tool,
4475 SCULPT_TOOL_CLAY_STRIPS,
4476 SCULPT_TOOL_PINCH,
4477 SCULPT_TOOL_MULTIPLANE_SCRAPE,
4478 SCULPT_TOOL_CLAY_THUMB,
4479 SCULPT_TOOL_NUDGE,
4480 SCULPT_TOOL_SNAKE_HOOK);
4483 static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Brush *brush)
4485 SculptSession *ss = ob->sculpt;
4486 StrokeCache *cache = ss->cache;
4487 const float mval[2] = {
4488 cache->mouse_event[0],
4489 cache->mouse_event[1],
4491 int tool = brush->sculpt_tool;
4493 if (!ELEM(tool,
4494 SCULPT_TOOL_PAINT,
4495 SCULPT_TOOL_GRAB,
4496 SCULPT_TOOL_ELASTIC_DEFORM,
4497 SCULPT_TOOL_CLOTH,
4498 SCULPT_TOOL_NUDGE,
4499 SCULPT_TOOL_CLAY_STRIPS,
4500 SCULPT_TOOL_PINCH,
4501 SCULPT_TOOL_MULTIPLANE_SCRAPE,
4502 SCULPT_TOOL_CLAY_THUMB,
4503 SCULPT_TOOL_SNAKE_HOOK,
4504 SCULPT_TOOL_POSE,
4505 SCULPT_TOOL_BOUNDARY,
4506 SCULPT_TOOL_SMEAR,
4507 SCULPT_TOOL_THUMB) &&
4508 !sculpt_brush_use_topology_rake(ss, brush))
4510 return;
4512 float grab_location[3], imat[4][4], delta[3], loc[3];
4514 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
4515 if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
4516 copy_v3_v3(cache->orig_grab_location,
4517 SCULPT_vertex_co_for_grab_active_get(ss, SCULPT_active_vertex_get(ss)));
4519 else {
4520 copy_v3_v3(cache->orig_grab_location, cache->true_location);
4523 else if (tool == SCULPT_TOOL_SNAKE_HOOK ||
4524 (tool == SCULPT_TOOL_CLOTH &&
4525 brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK))
4527 add_v3_v3(cache->true_location, cache->grab_delta);
4530 /* Compute 3d coordinate at same z from original location + mval. */
4531 mul_v3_m4v3(loc, ob->object_to_world().ptr(), cache->orig_grab_location);
4532 ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mval, grab_location);
4534 /* Compute delta to move verts by. */
4535 if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
4536 if (sculpt_needs_delta_from_anchored_origin(brush)) {
4537 sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
4538 invert_m4_m4(imat, ob->object_to_world().ptr());
4539 mul_mat3_m4_v3(imat, delta);
4540 add_v3_v3(cache->grab_delta, delta);
4542 else if (sculpt_needs_delta_for_tip_orientation(brush)) {
4543 if (brush->flag & BRUSH_ANCHORED) {
4544 float orig[3];
4545 mul_v3_m4v3(orig, ob->object_to_world().ptr(), cache->orig_grab_location);
4546 sub_v3_v3v3(cache->grab_delta, grab_location, orig);
4548 else {
4549 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
4551 invert_m4_m4(imat, ob->object_to_world().ptr());
4552 mul_mat3_m4_v3(imat, cache->grab_delta);
4554 else {
4555 /* Use for 'Brush.topology_rake_factor'. */
4556 sub_v3_v3v3(cache->grab_delta, grab_location, cache->old_grab_location);
4559 else {
4560 zero_v3(cache->grab_delta);
4563 if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
4564 project_plane_v3_v3v3(cache->grab_delta, cache->grab_delta, ss->cache->true_view_normal);
4567 copy_v3_v3(cache->old_grab_location, grab_location);
4569 if (tool == SCULPT_TOOL_GRAB) {
4570 if (brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
4571 copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
4573 else {
4574 copy_v3_v3(cache->anchored_location, cache->true_location);
4577 else if (tool == SCULPT_TOOL_ELASTIC_DEFORM || cloth::is_cloth_deform_brush(brush)) {
4578 copy_v3_v3(cache->anchored_location, cache->true_location);
4580 else if (tool == SCULPT_TOOL_THUMB) {
4581 copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
4584 if (sculpt_needs_delta_from_anchored_origin(brush)) {
4585 /* Location stays the same for finding vertices in brush radius. */
4586 copy_v3_v3(cache->true_location, cache->orig_grab_location);
4588 ups->draw_anchored = true;
4589 copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
4590 ups->anchored_size = ups->pixel_radius;
4593 /* Handle 'rake' */
4594 cache->is_rake_rotation_valid = false;
4596 invert_m4_m4(imat, ob->object_to_world().ptr());
4597 mul_mat3_m4_v3(imat, grab_location);
4599 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
4600 copy_v3_v3(cache->rake_data.follow_co, grab_location);
4603 if (!sculpt_brush_needs_rake_rotation(brush)) {
4604 return;
4606 cache->rake_data.follow_dist = cache->radius * SCULPT_RAKE_BRUSH_FACTOR;
4608 if (!is_zero_v3(cache->grab_delta)) {
4609 const float eps = 0.00001f;
4611 float v1[3], v2[3];
4613 copy_v3_v3(v1, cache->rake_data.follow_co);
4614 copy_v3_v3(v2, cache->rake_data.follow_co);
4615 sub_v3_v3(v2, cache->grab_delta);
4617 sub_v3_v3(v1, grab_location);
4618 sub_v3_v3(v2, grab_location);
4620 if ((normalize_v3(v2) > eps) && (normalize_v3(v1) > eps) && (len_squared_v3v3(v1, v2) > eps)) {
4621 const float rake_dist_sq = len_squared_v3v3(cache->rake_data.follow_co, grab_location);
4622 const float rake_fade = (rake_dist_sq > square_f(cache->rake_data.follow_dist)) ?
4623 1.0f :
4624 sqrtf(rake_dist_sq) / cache->rake_data.follow_dist;
4626 float axis[3], angle;
4627 float tquat[4];
4629 rotation_between_vecs_to_quat(tquat, v1, v2);
4631 /* Use axis-angle to scale rotation since the factor may be above 1. */
4632 quat_to_axis_angle(axis, &angle, tquat);
4633 normalize_v3(axis);
4635 angle *= brush->rake_factor * rake_fade;
4636 axis_angle_normalized_to_quat(cache->rake_rotation, axis, angle);
4637 cache->is_rake_rotation_valid = true;
4640 sculpt_rake_data_update(&cache->rake_data, grab_location);
4643 static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *brush)
4645 cache->paint_brush.hardness = brush->hardness;
4646 if (brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE) {
4647 cache->paint_brush.hardness *= brush->paint_flags & BRUSH_PAINT_HARDNESS_PRESSURE_INVERT ?
4648 1.0f - cache->pressure :
4649 cache->pressure;
4652 cache->paint_brush.flow = brush->flow;
4653 if (brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE) {
4654 cache->paint_brush.flow *= brush->paint_flags & BRUSH_PAINT_FLOW_PRESSURE_INVERT ?
4655 1.0f - cache->pressure :
4656 cache->pressure;
4659 cache->paint_brush.wet_mix = brush->wet_mix;
4660 if (brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE) {
4661 cache->paint_brush.wet_mix *= brush->paint_flags & BRUSH_PAINT_WET_MIX_PRESSURE_INVERT ?
4662 1.0f - cache->pressure :
4663 cache->pressure;
4665 /* This makes wet mix more sensible in higher values, which allows to create brushes that have
4666 * a wider pressure range were they only blend colors without applying too much of the brush
4667 * color. */
4668 cache->paint_brush.wet_mix = 1.0f - pow2f(1.0f - cache->paint_brush.wet_mix);
4671 cache->paint_brush.wet_persistence = brush->wet_persistence;
4672 if (brush->paint_flags & BRUSH_PAINT_WET_PERSISTENCE_PRESSURE) {
4673 cache->paint_brush.wet_persistence = brush->paint_flags &
4674 BRUSH_PAINT_WET_PERSISTENCE_PRESSURE_INVERT ?
4675 1.0f - cache->pressure :
4676 cache->pressure;
4679 cache->paint_brush.density = brush->density;
4680 if (brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE) {
4681 cache->paint_brush.density = brush->paint_flags & BRUSH_PAINT_DENSITY_PRESSURE_INVERT ?
4682 1.0f - cache->pressure :
4683 cache->pressure;
4687 /* Initialize the stroke cache variants from operator properties. */
4688 static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr)
4690 Scene *scene = CTX_data_scene(C);
4691 UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
4692 SculptSession *ss = ob->sculpt;
4693 StrokeCache *cache = ss->cache;
4694 Brush *brush = BKE_paint_brush(&sd->paint);
4696 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
4697 !((brush->flag & BRUSH_ANCHORED) || (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) ||
4698 (brush->sculpt_tool == SCULPT_TOOL_ROTATE) || cloth::is_cloth_deform_brush(brush)))
4700 RNA_float_get_array(ptr, "location", cache->true_location);
4703 cache->pen_flip = RNA_boolean_get(ptr, "pen_flip");
4704 RNA_float_get_array(ptr, "mouse", cache->mouse);
4705 RNA_float_get_array(ptr, "mouse_event", cache->mouse_event);
4707 /* XXX: Use pressure value from first brush step for brushes which don't support strokes (grab,
4708 * thumb). They depends on initial state and brush coord/pressure/etc.
4709 * It's more an events design issue, which doesn't split coordinate/pressure/angle changing
4710 * events. We should avoid this after events system re-design. */
4711 if (paint_supports_dynamic_size(brush, PaintMode::Sculpt) || cache->first_time) {
4712 cache->pressure = RNA_float_get(ptr, "pressure");
4715 cache->x_tilt = RNA_float_get(ptr, "x_tilt");
4716 cache->y_tilt = RNA_float_get(ptr, "y_tilt");
4718 /* Truly temporary data that isn't stored in properties. */
4719 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
4720 cache->initial_radius = sculpt_calc_radius(cache->vc, brush, scene, cache->true_location);
4722 if (!BKE_brush_use_locked_size(scene, brush)) {
4723 BKE_brush_unprojected_radius_set(scene, brush, cache->initial_radius);
4727 /* Clay stabilized pressure. */
4728 if (brush->sculpt_tool == SCULPT_TOOL_CLAY_THUMB) {
4729 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
4730 for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
4731 ss->cache->clay_pressure_stabilizer[i] = 0.0f;
4733 ss->cache->clay_pressure_stabilizer_index = 0;
4735 else {
4736 cache->clay_pressure_stabilizer[cache->clay_pressure_stabilizer_index] = cache->pressure;
4737 cache->clay_pressure_stabilizer_index += 1;
4738 if (cache->clay_pressure_stabilizer_index >= SCULPT_CLAY_STABILIZER_LEN) {
4739 cache->clay_pressure_stabilizer_index = 0;
4744 if (BKE_brush_use_size_pressure(brush) && paint_supports_dynamic_size(brush, PaintMode::Sculpt))
4746 cache->radius = sculpt_brush_dynamic_size_get(brush, cache, cache->initial_radius);
4747 cache->dyntopo_pixel_radius = sculpt_brush_dynamic_size_get(
4748 brush, cache, ups->initial_pixel_radius);
4750 else {
4751 cache->radius = cache->initial_radius;
4752 cache->dyntopo_pixel_radius = ups->initial_pixel_radius;
4755 sculpt_update_cache_paint_variants(cache, brush);
4757 cache->radius_squared = cache->radius * cache->radius;
4759 if (brush->flag & BRUSH_ANCHORED) {
4760 /* True location has been calculated as part of the stroke system already here. */
4761 if (brush->flag & BRUSH_EDGE_TO_EDGE) {
4762 RNA_float_get_array(ptr, "location", cache->true_location);
4765 cache->radius = paint_calc_object_space_radius(
4766 cache->vc, cache->true_location, ups->pixel_radius);
4767 cache->radius_squared = cache->radius * cache->radius;
4769 copy_v3_v3(cache->anchored_location, cache->true_location);
4772 sculpt_update_brush_delta(ups, ob, brush);
4774 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) {
4775 cache->vertex_rotation = -BLI_dial_angle(cache->dial, cache->mouse) * cache->bstrength;
4777 ups->draw_anchored = true;
4778 copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
4779 copy_v3_v3(cache->anchored_location, cache->true_location);
4780 ups->anchored_size = ups->pixel_radius;
4783 cache->special_rotation = ups->brush_rotation;
4785 cache->iteration_count++;
4788 /* Returns true if any of the smoothing modes are active (currently
4789 * one of smooth brush, autosmooth, mask smooth, or shift-key
4790 * smooth). */
4791 static bool sculpt_needs_connectivity_info(const Sculpt *sd,
4792 const Brush *brush,
4793 SculptSession *ss,
4794 int stroke_mode)
4796 if (!brush) {
4797 return true;
4800 if (ss && ss->pbvh && auto_mask::is_enabled(sd, ss, brush)) {
4801 return true;
4803 return ((stroke_mode == BRUSH_STROKE_SMOOTH) || (ss && ss->cache && ss->cache->alt_smooth) ||
4804 (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) ||
4805 ((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) ||
4806 (brush->sculpt_tool == SCULPT_TOOL_POSE) ||
4807 (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) ||
4808 (brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) ||
4809 SCULPT_tool_is_paint(brush->sculpt_tool) || (brush->sculpt_tool == SCULPT_TOOL_CLOTH) ||
4810 (brush->sculpt_tool == SCULPT_TOOL_SMEAR) ||
4811 (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS) ||
4812 (brush->sculpt_tool == SCULPT_TOOL_DISPLACEMENT_SMEAR) ||
4813 (brush->sculpt_tool == SCULPT_TOOL_PAINT));
4816 } // namespace blender::ed::sculpt_paint
4818 void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush)
4820 using namespace blender::ed::sculpt_paint;
4821 SculptSession *ss = ob->sculpt;
4822 RegionView3D *rv3d = CTX_wm_region_view3d(C);
4823 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
4825 bool need_pmap = sculpt_needs_connectivity_info(sd, brush, ss, 0);
4826 if (ss->shapekey_active || ss->deform_modifiers_active ||
4827 (!BKE_sculptsession_use_pbvh_draw(ob, rv3d) && need_pmap))
4829 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
4830 BKE_sculpt_update_object_for_edit(depsgraph, ob, SCULPT_tool_is_paint(brush->sculpt_tool));
4834 static void sculpt_raycast_cb(PBVHNode &node, SculptRaycastData &srd, float *tmin)
4836 using namespace blender;
4837 using namespace blender::ed::sculpt_paint;
4838 if (BKE_pbvh_node_get_tmin(&node) >= *tmin) {
4839 return;
4841 float(*origco)[3] = nullptr;
4842 bool use_origco = false;
4844 if (srd.original && srd.ss->cache) {
4845 if (BKE_pbvh_type(srd.ss->pbvh) == PBVH_BMESH) {
4846 use_origco = true;
4848 else {
4849 /* Intersect with coordinates from before we started stroke. */
4850 undo::Node *unode = undo::get_node(&node, undo::Type::Position);
4851 origco = (unode) ? reinterpret_cast<float(*)[3]>(unode->position.data()) : nullptr;
4852 use_origco = origco ? true : false;
4856 if (bke::pbvh::raycast_node(srd.ss->pbvh,
4857 &node,
4858 origco,
4859 use_origco,
4860 srd.corner_verts,
4861 srd.hide_poly,
4862 srd.ray_start,
4863 srd.ray_normal,
4864 &srd.isect_precalc,
4865 &srd.depth,
4866 &srd.active_vertex,
4867 &srd.active_face_grid_index,
4868 srd.face_normal))
4870 srd.hit = true;
4871 *tmin = srd.depth;
4875 static void sculpt_find_nearest_to_ray_cb(PBVHNode &node,
4876 SculptFindNearestToRayData &srd,
4877 float *tmin)
4879 using namespace blender;
4880 using namespace blender::ed::sculpt_paint;
4881 if (BKE_pbvh_node_get_tmin(&node) >= *tmin) {
4882 return;
4884 float(*origco)[3] = nullptr;
4885 bool use_origco = false;
4887 if (srd.original && srd.ss->cache) {
4888 if (BKE_pbvh_type(srd.ss->pbvh) == PBVH_BMESH) {
4889 use_origco = true;
4891 else {
4892 /* Intersect with coordinates from before we started stroke. */
4893 undo::Node *unode = undo::get_node(&node, undo::Type::Position);
4894 origco = (unode) ? reinterpret_cast<float(*)[3]>(unode->position.data()) : nullptr;
4895 use_origco = origco ? true : false;
4899 if (bke::pbvh::find_nearest_to_ray_node(srd.ss->pbvh,
4900 &node,
4901 origco,
4902 use_origco,
4903 srd.corner_verts,
4904 srd.hide_poly,
4905 srd.ray_start,
4906 srd.ray_normal,
4907 &srd.depth,
4908 &srd.dist_sq_to_ray))
4910 srd.hit = true;
4911 *tmin = srd.dist_sq_to_ray;
4915 float SCULPT_raycast_init(ViewContext *vc,
4916 const float mval[2],
4917 float ray_start[3],
4918 float ray_end[3],
4919 float ray_normal[3],
4920 bool original)
4922 using namespace blender;
4923 float obimat[4][4];
4924 float dist;
4925 Object *ob = vc->obact;
4926 RegionView3D *rv3d = vc->rv3d;
4927 View3D *v3d = vc->v3d;
4929 /* TODO: what if the segment is totally clipped? (return == 0). */
4930 ED_view3d_win_to_segment_clipped(
4931 vc->depsgraph, vc->region, vc->v3d, mval, ray_start, ray_end, true);
4933 invert_m4_m4(obimat, ob->object_to_world().ptr());
4934 mul_m4_v3(obimat, ray_start);
4935 mul_m4_v3(obimat, ray_end);
4937 sub_v3_v3v3(ray_normal, ray_end, ray_start);
4938 dist = normalize_v3(ray_normal);
4940 /* If the ray is clipped, don't adjust its start/end. */
4941 if ((rv3d->is_persp == false) && !RV3D_CLIPPING_ENABLED(v3d, rv3d)) {
4942 /* Get the view origin without the addition
4943 * of -ray_normal * clip_start that
4944 * ED_view3d_win_to_segment_clipped gave us.
4945 * This is necessary to avoid floating point overflow.
4947 ED_view3d_win_to_origin(vc->region, mval, ray_start);
4948 mul_m4_v3(obimat, ray_start);
4950 bke::pbvh::clip_ray_ortho(ob->sculpt->pbvh, original, ray_start, ray_end, ray_normal);
4952 dist = len_v3v3(ray_start, ray_end);
4955 return dist;
4958 bool SCULPT_cursor_geometry_info_update(bContext *C,
4959 SculptCursorGeometryInfo *out,
4960 const float mval[2],
4961 bool use_sampled_normal)
4963 using namespace blender;
4964 using namespace blender::ed::sculpt_paint;
4965 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
4966 Scene *scene = CTX_data_scene(C);
4967 Object *ob;
4968 SculptSession *ss;
4969 const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
4970 float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3], mat[3][3];
4971 float viewDir[3] = {0.0f, 0.0f, 1.0f};
4972 bool original = false;
4974 ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
4976 ob = vc.obact;
4977 ss = ob->sculpt;
4979 const View3D *v3d = CTX_wm_view3d(C);
4980 const Base *base = CTX_data_active_base(C);
4982 if (!ss->pbvh || !vc.rv3d || !BKE_base_is_visible(v3d, base)) {
4983 zero_v3(out->location);
4984 zero_v3(out->normal);
4985 zero_v3(out->active_vertex_co);
4986 return false;
4989 /* PBVH raycast to get active vertex and face normal. */
4990 depth = SCULPT_raycast_init(&vc, mval, ray_start, ray_end, ray_normal, original);
4991 SCULPT_stroke_modifiers_check(C, ob, brush);
4993 SculptRaycastData srd{};
4994 srd.original = original;
4995 srd.ss = ob->sculpt;
4996 srd.hit = false;
4997 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
4998 const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
4999 srd.corner_verts = mesh.corner_verts();
5000 const bke::AttributeAccessor attributes = mesh.attributes();
5001 srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
5003 srd.ray_start = ray_start;
5004 srd.ray_normal = ray_normal;
5005 srd.depth = depth;
5006 srd.face_normal = face_normal;
5008 isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
5009 bke::pbvh::raycast(
5010 ss->pbvh,
5011 [&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
5012 ray_start,
5013 ray_normal,
5014 srd.original);
5016 /* Cursor is not over the mesh, return default values. */
5017 if (!srd.hit) {
5018 zero_v3(out->location);
5019 zero_v3(out->normal);
5020 zero_v3(out->active_vertex_co);
5021 return false;
5024 /* Update the active vertex of the SculptSession. */
5025 ss->active_vertex = srd.active_vertex;
5026 SCULPT_vertex_random_access_ensure(ss);
5027 copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss));
5029 switch (BKE_pbvh_type(ss->pbvh)) {
5030 case PBVH_FACES:
5031 ss->active_face_index = srd.active_face_grid_index;
5032 ss->active_grid_index = 0;
5033 break;
5034 case PBVH_GRIDS:
5035 ss->active_face_index = 0;
5036 ss->active_grid_index = srd.active_face_grid_index;
5037 break;
5038 case PBVH_BMESH:
5039 ss->active_face_index = 0;
5040 ss->active_grid_index = 0;
5041 break;
5044 copy_v3_v3(out->location, ray_normal);
5045 mul_v3_fl(out->location, srd.depth);
5046 add_v3_v3(out->location, ray_start);
5048 /* Option to return the face normal directly for performance o accuracy reasons. */
5049 if (!use_sampled_normal) {
5050 copy_v3_v3(out->normal, srd.face_normal);
5051 return srd.hit;
5054 /* Sampled normal calculation. */
5055 float radius;
5057 /* Update cursor data in SculptSession. */
5058 invert_m4_m4(ob->runtime->world_to_object.ptr(), ob->object_to_world().ptr());
5059 copy_m3_m4(mat, vc.rv3d->viewinv);
5060 mul_m3_v3(mat, viewDir);
5061 copy_m3_m4(mat, ob->world_to_object().ptr());
5062 mul_m3_v3(mat, viewDir);
5063 normalize_v3_v3(ss->cursor_view_normal, viewDir);
5064 copy_v3_v3(ss->cursor_normal, srd.face_normal);
5065 copy_v3_v3(ss->cursor_location, out->location);
5066 ss->rv3d = vc.rv3d;
5067 ss->v3d = vc.v3d;
5069 if (!BKE_brush_use_locked_size(scene, brush)) {
5070 radius = paint_calc_object_space_radius(&vc, out->location, BKE_brush_size_get(scene, brush));
5072 else {
5073 radius = BKE_brush_unprojected_radius_get(scene, brush);
5075 ss->cursor_radius = radius;
5077 Vector<PBVHNode *> nodes = sculpt_pbvh_gather_cursor_update(ob, original);
5079 /* In case there are no nodes under the cursor, return the face normal. */
5080 if (nodes.is_empty()) {
5081 copy_v3_v3(out->normal, srd.face_normal);
5082 return true;
5085 /* Calculate the sampled normal. */
5086 if (const std::optional<float3> sampled_normal = SCULPT_pbvh_calc_area_normal(brush, ob, nodes))
5088 copy_v3_v3(out->normal, *sampled_normal);
5089 copy_v3_v3(ss->cursor_sampled_normal, *sampled_normal);
5091 else {
5092 /* Use face normal when there are no vertices to sample inside the cursor radius. */
5093 copy_v3_v3(out->normal, srd.face_normal);
5095 return true;
5098 bool SCULPT_stroke_get_location(bContext *C,
5099 float out[3],
5100 const float mval[2],
5101 bool force_original)
5103 const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
5104 bool check_closest = brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE;
5106 return SCULPT_stroke_get_location_ex(C, out, mval, force_original, check_closest, true);
5109 bool SCULPT_stroke_get_location_ex(bContext *C,
5110 float out[3],
5111 const float mval[2],
5112 bool force_original,
5113 bool check_closest,
5114 bool limit_closest_radius)
5116 using namespace blender;
5117 using namespace blender::ed::sculpt_paint;
5118 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
5119 Object *ob;
5120 SculptSession *ss;
5121 StrokeCache *cache;
5122 float ray_start[3], ray_end[3], ray_normal[3], depth, face_normal[3];
5123 bool original;
5125 ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph);
5127 ob = vc.obact;
5129 ss = ob->sculpt;
5130 cache = ss->cache;
5131 original = force_original || ((cache) ? !cache->accum : false);
5133 const Brush *brush = BKE_paint_brush(BKE_paint_get_active_from_context(C));
5135 SCULPT_stroke_modifiers_check(C, ob, brush);
5137 depth = SCULPT_raycast_init(&vc, mval, ray_start, ray_end, ray_normal, original);
5139 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
5140 BM_mesh_elem_table_ensure(ss->bm, BM_VERT);
5141 BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
5144 bool hit = false;
5146 SculptRaycastData srd;
5147 srd.ss = ob->sculpt;
5148 srd.ray_start = ray_start;
5149 srd.ray_normal = ray_normal;
5150 srd.hit = false;
5151 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
5152 const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
5153 srd.corner_verts = mesh.corner_verts();
5154 const bke::AttributeAccessor attributes = mesh.attributes();
5155 srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
5157 srd.depth = depth;
5158 srd.original = original;
5159 srd.face_normal = face_normal;
5160 isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
5162 bke::pbvh::raycast(
5163 ss->pbvh,
5164 [&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
5165 ray_start,
5166 ray_normal,
5167 srd.original);
5168 if (srd.hit) {
5169 hit = true;
5170 copy_v3_v3(out, ray_normal);
5171 mul_v3_fl(out, srd.depth);
5172 add_v3_v3(out, ray_start);
5176 if (hit || !check_closest) {
5177 return hit;
5180 SculptFindNearestToRayData srd{};
5181 srd.original = original;
5182 srd.ss = ob->sculpt;
5183 srd.hit = false;
5184 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
5185 const Mesh &mesh = *static_cast<const Mesh *>(ob->data);
5186 srd.corner_verts = mesh.corner_verts();
5187 const bke::AttributeAccessor attributes = mesh.attributes();
5188 srd.hide_poly = *attributes.lookup<bool>(".hide_poly", bke::AttrDomain::Face);
5190 srd.ray_start = ray_start;
5191 srd.ray_normal = ray_normal;
5192 srd.depth = FLT_MAX;
5193 srd.dist_sq_to_ray = FLT_MAX;
5195 bke::pbvh::find_nearest_to_ray(
5196 ss->pbvh,
5197 [&](PBVHNode &node, float *tmin) { sculpt_find_nearest_to_ray_cb(node, srd, tmin); },
5198 ray_start,
5199 ray_normal,
5200 srd.original);
5201 if (srd.hit && srd.dist_sq_to_ray) {
5202 hit = true;
5203 copy_v3_v3(out, ray_normal);
5204 mul_v3_fl(out, srd.depth);
5205 add_v3_v3(out, ray_start);
5208 float closest_radius_sq = FLT_MAX;
5209 if (limit_closest_radius) {
5210 closest_radius_sq = sculpt_calc_radius(&vc, brush, CTX_data_scene(C), out);
5211 closest_radius_sq *= closest_radius_sq;
5214 return hit && srd.dist_sq_to_ray < closest_radius_sq;
5217 static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss)
5219 Brush *brush = BKE_paint_brush(&sd->paint);
5220 const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
5222 /* Init mtex nodes. */
5223 if (mask_tex->tex && mask_tex->tex->nodetree) {
5224 /* Has internal flag to detect it only does it once. */
5225 ntreeTexBeginExecTree(mask_tex->tex->nodetree);
5228 if (ss->tex_pool == nullptr) {
5229 ss->tex_pool = BKE_image_pool_new();
5233 static void sculpt_brush_stroke_init(bContext *C)
5235 Object *ob = CTX_data_active_object(C);
5236 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5237 Sculpt *sd = tool_settings->sculpt;
5238 SculptSession *ss = CTX_data_active_object(C)->sculpt;
5239 Brush *brush = BKE_paint_brush(&sd->paint);
5241 view3d_operator_needs_opengl(C);
5242 sculpt_brush_init_tex(sd, ss);
5244 const bool needs_colors = SCULPT_tool_is_paint(brush->sculpt_tool) &&
5245 !SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob);
5247 if (needs_colors) {
5248 BKE_sculpt_color_layer_create_if_needed(ob);
5251 /* CTX_data_ensure_evaluated_depsgraph should be used at the end to include the updates of
5252 * earlier steps modifying the data. */
5253 Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
5254 BKE_sculpt_update_object_for_edit(depsgraph, ob, SCULPT_tool_is_paint(brush->sculpt_tool));
5256 ED_paint_tool_update_sticky_shading_color(C, ob);
5259 static void sculpt_restore_mesh(Sculpt *sd, Object *ob)
5261 using namespace blender::ed::sculpt_paint;
5262 SculptSession *ss = ob->sculpt;
5263 Brush *brush = BKE_paint_brush(&sd->paint);
5265 /* For the cloth brush it makes more sense to not restore the mesh state to keep running the
5266 * simulation from the previous state. */
5267 if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
5268 return;
5271 /* Restore the mesh before continuing with anchored stroke. */
5272 if ((brush->flag & BRUSH_ANCHORED) ||
5273 (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ELASTIC_DEFORM) &&
5274 BKE_brush_use_size_pressure(brush)) ||
5275 (brush->flag & BRUSH_DRAG_DOT))
5278 restore_from_undo_step(*sd, *ob);
5280 if (ss->cache) {
5281 MEM_SAFE_FREE(ss->cache->layer_displacement_factor);
5286 void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
5288 using namespace blender;
5289 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
5290 Object *ob = CTX_data_active_object(C);
5291 SculptSession *ss = ob->sculpt;
5292 ARegion *region = CTX_wm_region(C);
5293 MultiresModifierData *mmd = ss->multires.modifier;
5294 RegionView3D *rv3d = CTX_wm_region_view3d(C);
5295 Mesh *mesh = static_cast<Mesh *>(ob->data);
5297 const bool use_pbvh_draw = BKE_sculptsession_use_pbvh_draw(ob, rv3d);
5299 if (rv3d) {
5300 /* Mark for faster 3D viewport redraws. */
5301 rv3d->rflag |= RV3D_PAINTING;
5304 if (mmd != nullptr) {
5305 multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
5308 if ((update_flags & SCULPT_UPDATE_IMAGE) != 0) {
5309 ED_region_tag_redraw(region);
5310 if (update_flags == SCULPT_UPDATE_IMAGE) {
5311 /* Early exit when only need to update the images. We don't want to tag any geometry updates
5312 * that would rebuilt the PBVH. */
5313 return;
5317 DEG_id_tag_update(&ob->id, ID_RECALC_SHADING);
5319 /* Only current viewport matters, slower update for all viewports will
5320 * be done in sculpt_flush_update_done. */
5321 if (!use_pbvh_draw) {
5322 /* Slow update with full dependency graph update and all that comes with it.
5323 * Needed when there are modifiers or full shading in the 3D viewport. */
5324 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
5325 ED_region_tag_redraw(region);
5327 else {
5328 /* Fast path where we just update the BVH nodes that changed, and redraw
5329 * only the part of the 3D viewport where changes happened. */
5330 rcti r;
5332 if (update_flags & SCULPT_UPDATE_COORDS) {
5333 bke::pbvh::update_bounds(*ss->pbvh, PBVH_UpdateBB);
5336 RegionView3D *rv3d = CTX_wm_region_view3d(C);
5337 if (rv3d && SCULPT_get_redraw_rect(region, rv3d, ob, &r)) {
5338 if (ss->cache) {
5339 ss->cache->current_r = r;
5342 /* previous is not set in the current cache else
5343 * the partial rect will always grow */
5344 sculpt_extend_redraw_rect_previous(ob, &r);
5346 r.xmin += region->winrct.xmin - 2;
5347 r.xmax += region->winrct.xmin + 2;
5348 r.ymin += region->winrct.ymin - 2;
5349 r.ymax += region->winrct.ymin + 2;
5350 ED_region_tag_redraw_partial(region, &r, true);
5354 if (update_flags & SCULPT_UPDATE_COORDS && !ss->shapekey_active) {
5355 if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
5356 /* Updating mesh positions without marking caches dirty is generally not good, but since
5357 * sculpt mode has special requirements and is expected to have sole ownership of the mesh it
5358 * modifies, it's generally okay. */
5359 if (use_pbvh_draw) {
5360 /* When drawing from PBVH is used, vertex and face normals are updated later in
5361 * #bke::pbvh::update_normals. However, we update the mesh's bounds eagerly here since they
5362 * are trivial to access from the PBVH. Updating the object's evaluated geometry bounding
5363 * box is necessary because sculpt strokes don't cause an object reevaluation. */
5364 mesh->tag_positions_changed_no_normals();
5365 /* Sculpt mode does node use or recalculate face corner normals, so they are cleared. */
5366 mesh->runtime->corner_normals_cache.tag_dirty();
5368 else {
5369 /* Drawing happens from the modifier stack evaluation result.
5370 * Tag both coordinates and normals as modified, as both needed for proper drawing and the
5371 * modifier stack is not guaranteed to tag normals for update. */
5372 mesh->tag_positions_changed();
5375 mesh->bounds_set_eager(bke::pbvh::bounds_get(*ob->sculpt->pbvh));
5376 if (ob->runtime->bounds_eval) {
5377 ob->runtime->bounds_eval = mesh->bounds_min_max();
5383 void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
5385 using namespace blender;
5386 /* After we are done drawing the stroke, check if we need to do a more
5387 * expensive depsgraph tag to update geometry. */
5388 wmWindowManager *wm = CTX_wm_manager(C);
5389 RegionView3D *current_rv3d = CTX_wm_region_view3d(C);
5390 SculptSession *ss = ob->sculpt;
5391 Mesh *mesh = static_cast<Mesh *>(ob->data);
5393 /* Always needed for linked duplicates. */
5394 bool need_tag = (ID_REAL_USERS(&mesh->id) > 1);
5396 if (current_rv3d) {
5397 current_rv3d->rflag &= ~RV3D_PAINTING;
5400 LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
5401 bScreen *screen = WM_window_get_active_screen(win);
5402 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5403 SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
5404 if (sl->spacetype != SPACE_VIEW3D) {
5405 continue;
5408 /* Tag all 3D viewports for redraw now that we are done. Others
5409 * viewports did not get a full redraw, and anti-aliasing for the
5410 * current viewport was deactivated. */
5411 LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
5412 if (region->regiontype == RGN_TYPE_WINDOW) {
5413 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
5414 if (rv3d != current_rv3d) {
5415 need_tag |= !BKE_sculptsession_use_pbvh_draw(ob, rv3d);
5418 ED_region_tag_redraw(region);
5423 if (update_flags & SCULPT_UPDATE_IMAGE) {
5424 LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
5425 SpaceLink *sl = static_cast<SpaceLink *>(area->spacedata.first);
5426 if (sl->spacetype != SPACE_IMAGE) {
5427 continue;
5429 ED_area_tag_redraw_regiontype(area, RGN_TYPE_WINDOW);
5434 if (update_flags & SCULPT_UPDATE_COORDS) {
5435 bke::pbvh::update_bounds(*ss->pbvh, PBVH_UpdateOriginalBB);
5437 /* Coordinates were modified, so fake neighbors are not longer valid. */
5438 SCULPT_fake_neighbors_free(ob);
5441 if (update_flags & SCULPT_UPDATE_MASK) {
5442 bke::pbvh::update_mask(*ss->pbvh);
5445 BKE_sculpt_attributes_destroy_temporary_stroke(ob);
5447 if (update_flags & SCULPT_UPDATE_COORDS) {
5448 if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
5449 BKE_pbvh_bmesh_after_stroke(ss->pbvh);
5452 /* Optimization: if there is locked key and active modifiers present in */
5453 /* the stack, keyblock is updating at each step. otherwise we could update */
5454 /* keyblock only when stroke is finished. */
5455 if (ss->shapekey_active && !ss->deform_modifiers_active) {
5456 sculpt_update_keyblock(ob);
5460 if (need_tag) {
5461 DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
5465 /* Returns whether the mouse/stylus is over the mesh (1)
5466 * or over the background (0). */
5467 static bool over_mesh(bContext *C, wmOperator * /*op*/, const float mval[2])
5469 float co_dummy[3];
5470 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5471 Brush *brush = BKE_paint_brush(&sd->paint);
5473 bool check_closest = brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE;
5475 return SCULPT_stroke_get_location_ex(C, co_dummy, mval, false, check_closest, true);
5478 static void sculpt_stroke_undo_begin(const bContext *C, wmOperator *op)
5480 using namespace blender::ed::sculpt_paint;
5481 Object *ob = CTX_data_active_object(C);
5482 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5483 Brush *brush = BKE_paint_brush(&sd->paint);
5484 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5486 /* Setup the correct undo system. Image painting and sculpting are mutual exclusive.
5487 * Color attributes are part of the sculpting undo system. */
5488 if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
5489 SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob))
5491 ED_image_undo_push_begin(op->type->name, PaintMode::Sculpt);
5493 else {
5494 undo::push_begin_ex(ob, sculpt_tool_name(sd));
5498 static void sculpt_stroke_undo_end(const bContext *C, Brush *brush)
5500 using namespace blender::ed::sculpt_paint;
5501 Object *ob = CTX_data_active_object(C);
5502 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5504 if (brush && brush->sculpt_tool == SCULPT_TOOL_PAINT &&
5505 SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob))
5507 ED_image_undo_push_end();
5509 else {
5510 undo::push_end(ob);
5514 bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports)
5516 switch (BKE_pbvh_type(ss->pbvh)) {
5517 case PBVH_FACES:
5518 return true;
5519 case PBVH_BMESH:
5520 BKE_report(reports, RPT_ERROR, "Not supported in dynamic topology mode");
5521 return false;
5522 case PBVH_GRIDS:
5523 BKE_report(reports, RPT_ERROR, "Not supported in multiresolution mode");
5524 return false;
5526 BLI_assert_unreachable();
5527 return false;
5530 namespace blender::ed::sculpt_paint {
5532 static bool sculpt_stroke_test_start(bContext *C, wmOperator *op, const float mval[2])
5534 /* Don't start the stroke until `mval` goes over the mesh.
5535 * NOTE: `mval` will only be null when re-executing the saved stroke.
5536 * We have exception for 'exec' strokes since they may not set `mval`,
5537 * only 'location', see: #52195. */
5538 if (((op->flag & OP_IS_INVOKE) == 0) || (mval == nullptr) || over_mesh(C, op, mval)) {
5539 Object *ob = CTX_data_active_object(C);
5540 SculptSession *ss = ob->sculpt;
5541 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5542 Brush *brush = BKE_paint_brush(&sd->paint);
5543 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5545 /* NOTE: This should be removed when paint mode is available. Paint mode can force based on the
5546 * canvas it is painting on. (ref. use_sculpt_texture_paint). */
5547 if (brush && SCULPT_tool_is_paint(brush->sculpt_tool) &&
5548 !SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob))
5550 View3D *v3d = CTX_wm_view3d(C);
5551 if (v3d->shading.type == OB_SOLID) {
5552 v3d->shading.color_type = V3D_SHADING_VERTEX_COLOR;
5556 ED_view3d_init_mats_rv3d(ob, CTX_wm_region_view3d(C));
5558 sculpt_update_cache_invariants(C, sd, ss, op, mval);
5560 SculptCursorGeometryInfo sgi;
5561 SCULPT_cursor_geometry_info_update(C, &sgi, mval, false);
5563 sculpt_stroke_undo_begin(C, op);
5565 SCULPT_stroke_id_next(ob);
5566 ss->cache->stroke_id = ss->stroke_id;
5568 return true;
5570 return false;
5573 static void sculpt_stroke_update_step(bContext *C,
5574 wmOperator * /*op*/,
5575 PaintStroke *stroke,
5576 PointerRNA *itemptr)
5578 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
5579 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5580 Object *ob = CTX_data_active_object(C);
5581 SculptSession *ss = ob->sculpt;
5582 const Brush *brush = BKE_paint_brush(&sd->paint);
5583 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5584 StrokeCache *cache = ss->cache;
5585 cache->stroke_distance = paint_stroke_distance_get(stroke);
5587 SCULPT_stroke_modifiers_check(C, ob, brush);
5588 sculpt_update_cache_variants(C, sd, ob, itemptr);
5589 sculpt_restore_mesh(sd, ob);
5591 if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
5592 BKE_pbvh_bmesh_detail_size_set(
5593 ss->pbvh, dyntopo::detail_size::constant_to_detail_size(sd->constant_detail, ob));
5595 else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
5596 BKE_pbvh_bmesh_detail_size_set(
5597 ss->pbvh,
5598 dyntopo::detail_size::brush_to_detail_size(sd->detail_percent, ss->cache->radius));
5600 else {
5601 BKE_pbvh_bmesh_detail_size_set(
5602 ss->pbvh,
5603 dyntopo::detail_size::relative_to_detail_size(
5604 sd->detail_size, ss->cache->radius, ss->cache->dyntopo_pixel_radius, U.pixelsize));
5607 if (dyntopo::stroke_is_dyntopo(ss, brush)) {
5608 do_symmetrical_brush_actions(sd, ob, sculpt_topology_update, ups, &tool_settings->paint_mode);
5611 do_symmetrical_brush_actions(sd, ob, do_brush_action, ups, &tool_settings->paint_mode);
5612 sculpt_combine_proxies(sd, ob);
5614 /* Hack to fix noise texture tearing mesh. */
5615 sculpt_fix_noise_tear(sd, ob);
5617 /* TODO(sergey): This is not really needed for the solid shading,
5618 * which does use pBVH drawing anyway, but texture and wireframe
5619 * requires this.
5621 * Could be optimized later, but currently don't think it's so
5622 * much common scenario.
5624 * Same applies to the DEG_id_tag_update() invoked from
5625 * sculpt_flush_update_step().
5627 if (ss->deform_modifiers_active) {
5628 SCULPT_flush_stroke_deform(sd, ob, sculpt_tool_is_proxy_used(brush->sculpt_tool));
5630 else if (ss->shapekey_active) {
5631 sculpt_update_keyblock(ob);
5634 ss->cache->first_time = false;
5635 copy_v3_v3(ss->cache->true_last_location, ss->cache->true_location);
5637 /* Cleanup. */
5638 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
5639 SCULPT_flush_update_step(C, SCULPT_UPDATE_MASK);
5641 else if (SCULPT_tool_is_paint(brush->sculpt_tool)) {
5642 if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
5643 SCULPT_flush_update_step(C, SCULPT_UPDATE_IMAGE);
5645 else {
5646 SCULPT_flush_update_step(C, SCULPT_UPDATE_COLOR);
5649 else {
5650 SCULPT_flush_update_step(C, SCULPT_UPDATE_COORDS);
5654 static void sculpt_brush_exit_tex(Sculpt *sd)
5656 Brush *brush = BKE_paint_brush(&sd->paint);
5657 const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT);
5659 if (mask_tex->tex && mask_tex->tex->nodetree) {
5660 ntreeTexEndExecTree(mask_tex->tex->nodetree->runtime->execdata);
5664 static void sculpt_stroke_done(const bContext *C, PaintStroke * /*stroke*/)
5666 Object *ob = CTX_data_active_object(C);
5667 SculptSession *ss = ob->sculpt;
5668 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5669 ToolSettings *tool_settings = CTX_data_tool_settings(C);
5671 /* Finished. */
5672 if (!ss->cache) {
5673 sculpt_brush_exit_tex(sd);
5674 return;
5676 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
5677 Brush *brush = BKE_paint_brush(&sd->paint);
5678 BLI_assert(brush == ss->cache->brush); /* const, so we shouldn't change. */
5679 ups->draw_inverted = false;
5681 SCULPT_stroke_modifiers_check(C, ob, brush);
5683 /* Alt-Smooth. */
5684 if (ss->cache->alt_smooth) {
5685 smooth_brush_toggle_off(C, &sd->paint, ss->cache);
5686 /* Refresh the brush pointer in case we switched brush in the toggle function. */
5687 brush = BKE_paint_brush(&sd->paint);
5690 BKE_pbvh_node_color_buffer_free(ss->pbvh);
5691 SCULPT_cache_free(ss->cache);
5692 ss->cache = nullptr;
5694 sculpt_stroke_undo_end(C, brush);
5696 if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
5697 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_MASK);
5699 else if (brush->sculpt_tool == SCULPT_TOOL_PAINT) {
5700 if (SCULPT_use_image_paint_brush(&tool_settings->paint_mode, ob)) {
5701 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_IMAGE);
5703 else {
5704 BKE_sculpt_attributes_destroy_temporary_stroke(ob);
5705 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COLOR);
5708 else {
5709 SCULPT_flush_update_done(C, ob, SCULPT_UPDATE_COORDS);
5712 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
5713 sculpt_brush_exit_tex(sd);
5716 static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
5718 PaintStroke *stroke;
5719 int ignore_background_click;
5720 int retval;
5721 Object *ob = CTX_data_active_object(C);
5723 const View3D *v3d = CTX_wm_view3d(C);
5724 const Base *base = CTX_data_active_base(C);
5725 /* Test that ob is visible; otherwise we won't be able to get evaluated data
5726 * from the depsgraph. We do this here instead of SCULPT_mode_poll
5727 * to avoid falling through to the translate operator in the
5728 * global view3d keymap. */
5729 if (!BKE_base_is_visible(v3d, base)) {
5730 return OPERATOR_CANCELLED;
5733 sculpt_brush_stroke_init(C);
5735 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5736 Brush *brush = BKE_paint_brush(&sd->paint);
5737 SculptSession *ss = ob->sculpt;
5739 if (SCULPT_tool_is_paint(brush->sculpt_tool) &&
5740 !SCULPT_handles_colors_report(ob->sculpt, op->reports))
5742 return OPERATOR_CANCELLED;
5744 if (SCULPT_tool_is_mask(brush->sculpt_tool)) {
5745 MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
5746 BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd);
5748 if (!SCULPT_tool_is_attribute_only(brush->sculpt_tool) &&
5749 ED_sculpt_report_if_shape_key_is_locked(ob, op->reports))
5751 return OPERATOR_CANCELLED;
5754 stroke = paint_stroke_new(C,
5756 SCULPT_stroke_get_location,
5757 sculpt_stroke_test_start,
5758 sculpt_stroke_update_step,
5759 nullptr,
5760 sculpt_stroke_done,
5761 event->type);
5763 op->customdata = stroke;
5765 /* For tablet rotation. */
5766 ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click");
5767 const float mval[2] = {float(event->mval[0]), float(event->mval[1])};
5768 if (ignore_background_click && !over_mesh(C, op, mval)) {
5769 paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata));
5770 return OPERATOR_PASS_THROUGH;
5773 retval = op->type->modal(C, op, event);
5774 if (ELEM(retval, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
5775 paint_stroke_free(C, op, static_cast<PaintStroke *>(op->customdata));
5776 return retval;
5778 /* Add modal handler. */
5779 WM_event_add_modal_handler(C, op);
5781 OPERATOR_RETVAL_CHECK(retval);
5782 BLI_assert(retval == OPERATOR_RUNNING_MODAL);
5784 return OPERATOR_RUNNING_MODAL;
5787 static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
5789 sculpt_brush_stroke_init(C);
5791 op->customdata = paint_stroke_new(C,
5793 SCULPT_stroke_get_location,
5794 sculpt_stroke_test_start,
5795 sculpt_stroke_update_step,
5796 nullptr,
5797 sculpt_stroke_done,
5800 /* Frees op->customdata. */
5801 paint_stroke_exec(C, op, static_cast<PaintStroke *>(op->customdata));
5803 return OPERATOR_FINISHED;
5806 static void sculpt_brush_stroke_cancel(bContext *C, wmOperator *op)
5808 using namespace blender::ed::sculpt_paint;
5809 Object *ob = CTX_data_active_object(C);
5810 SculptSession *ss = ob->sculpt;
5811 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
5812 const Brush *brush = BKE_paint_brush(&sd->paint);
5814 /* XXX Canceling strokes that way does not work with dynamic topology,
5815 * user will have to do real undo for now. See #46456. */
5816 if (ss->cache && !dyntopo::stroke_is_dyntopo(ss, brush)) {
5817 restore_from_undo_step(*sd, *ob);
5820 paint_stroke_cancel(C, op, static_cast<PaintStroke *>(op->customdata));
5822 if (ss->cache) {
5823 SCULPT_cache_free(ss->cache);
5824 ss->cache = nullptr;
5827 sculpt_brush_exit_tex(sd);
5830 static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
5832 return paint_stroke_modal(C, op, event, (PaintStroke **)&op->customdata);
5835 static void sculpt_redo_empty_ui(bContext * /*C*/, wmOperator * /*op*/) {}
5837 void SCULPT_OT_brush_stroke(wmOperatorType *ot)
5839 /* Identifiers. */
5840 ot->name = "Sculpt";
5841 ot->idname = "SCULPT_OT_brush_stroke";
5842 ot->description = "Sculpt a stroke into the geometry";
5844 /* API callbacks. */
5845 ot->invoke = sculpt_brush_stroke_invoke;
5846 ot->modal = sculpt_brush_stroke_modal;
5847 ot->exec = sculpt_brush_stroke_exec;
5848 ot->poll = SCULPT_poll;
5849 ot->cancel = sculpt_brush_stroke_cancel;
5850 ot->ui = sculpt_redo_empty_ui;
5852 /* Flags (sculpt does its own undo? (ton)). */
5853 ot->flag = OPTYPE_BLOCKING;
5855 /* Properties. */
5857 paint_stroke_operator_properties(ot);
5859 RNA_def_boolean(ot->srna,
5860 "ignore_background_click",
5861 false,
5862 "Ignore Background Click",
5863 "Clicks on the background do not start the stroke");
5866 /* Fake Neighbors. */
5867 /* This allows the sculpt tools to work on meshes with multiple connected components as they had
5868 * only one connected component. When initialized and enabled, the sculpt API will return extra
5869 * connectivity neighbors that are not in the real mesh. These neighbors are calculated for each
5870 * vertex using the minimum distance to a vertex that is in a different connected component. */
5872 /* The fake neighbors first need to be ensured to be initialized.
5873 * After that tools which needs fake neighbors functionality need to
5874 * temporarily enable it:
5876 * void my_awesome_sculpt_tool() {
5877 * SCULPT_fake_neighbors_ensure(object, brush->disconnected_distance_max);
5878 * SCULPT_fake_neighbors_enable(ob);
5880 * ... Logic of the tool ...
5881 * SCULPT_fake_neighbors_disable(ob);
5884 * Such approach allows to keep all the connectivity information ready for reuse
5885 * (without having lag prior to every stroke), but also makes it so the affect
5886 * is localized to a specific brushes and tools only. */
5888 enum {
5889 SCULPT_TOPOLOGY_ID_NONE,
5890 SCULPT_TOPOLOGY_ID_DEFAULT,
5893 static void fake_neighbor_init(SculptSession *ss, const float max_dist)
5895 const int totvert = SCULPT_vertex_count_get(ss);
5896 ss->fake_neighbors.fake_neighbor_index = static_cast<int *>(
5897 MEM_malloc_arrayN(totvert, sizeof(int), "fake neighbor"));
5898 for (int i = 0; i < totvert; i++) {
5899 ss->fake_neighbors.fake_neighbor_index[i] = FAKE_NEIGHBOR_NONE;
5902 ss->fake_neighbors.current_max_distance = max_dist;
5905 static void fake_neighbor_add(SculptSession *ss, PBVHVertRef v_a, PBVHVertRef v_b)
5907 int v_index_a = BKE_pbvh_vertex_to_index(ss->pbvh, v_a);
5908 int v_index_b = BKE_pbvh_vertex_to_index(ss->pbvh, v_b);
5910 if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) {
5911 ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b;
5912 ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a;
5916 static void sculpt_pose_fake_neighbors_free(SculptSession *ss)
5918 MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index);
5921 struct NearestVertexFakeNeighborData {
5922 PBVHVertRef nearest_vertex;
5923 float nearest_vertex_distance_sq;
5924 int current_topology_id;
5927 static void do_fake_neighbor_search_task(SculptSession *ss,
5928 const float nearest_vertex_search_co[3],
5929 const float max_distance_sq,
5930 PBVHNode *node,
5931 NearestVertexFakeNeighborData *nvtd)
5933 PBVHVertexIter vd;
5934 BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) {
5935 int vd_topology_id = SCULPT_vertex_island_get(ss, vd.vertex);
5936 if (vd_topology_id != nvtd->current_topology_id &&
5937 ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE)
5939 float distance_squared = len_squared_v3v3(vd.co, nearest_vertex_search_co);
5940 if (distance_squared < nvtd->nearest_vertex_distance_sq &&
5941 distance_squared < max_distance_sq)
5943 nvtd->nearest_vertex = vd.vertex;
5944 nvtd->nearest_vertex_distance_sq = distance_squared;
5948 BKE_pbvh_vertex_iter_end;
5951 static PBVHVertRef fake_neighbor_search(Object *ob, const PBVHVertRef vertex, float max_distance)
5953 SculptSession *ss = ob->sculpt;
5955 const float3 center = SCULPT_vertex_co_get(ss, vertex);
5956 const float max_distance_sq = max_distance * max_distance;
5958 Vector<PBVHNode *> nodes = bke::pbvh::search_gather(ss->pbvh, [&](PBVHNode &node) {
5959 return node_in_sphere(node, center, max_distance_sq, false);
5961 if (nodes.is_empty()) {
5962 return BKE_pbvh_make_vref(PBVH_REF_NONE);
5965 const float3 nearest_vertex_search_co = SCULPT_vertex_co_get(ss, vertex);
5967 NearestVertexFakeNeighborData nvtd;
5968 nvtd.nearest_vertex.i = -1;
5969 nvtd.nearest_vertex_distance_sq = FLT_MAX;
5970 nvtd.current_topology_id = SCULPT_vertex_island_get(ss, vertex);
5972 nvtd = threading::parallel_reduce(
5973 nodes.index_range(),
5975 nvtd,
5976 [&](const IndexRange range, NearestVertexFakeNeighborData nvtd) {
5977 for (const int i : range) {
5978 do_fake_neighbor_search_task(
5979 ss, nearest_vertex_search_co, max_distance_sq, nodes[i], &nvtd);
5981 return nvtd;
5983 [](const NearestVertexFakeNeighborData &a, const NearestVertexFakeNeighborData &b) {
5984 NearestVertexFakeNeighborData joined = a;
5985 if (joined.nearest_vertex.i == PBVH_REF_NONE) {
5986 joined.nearest_vertex = b.nearest_vertex;
5987 joined.nearest_vertex_distance_sq = b.nearest_vertex_distance_sq;
5989 else if (b.nearest_vertex_distance_sq < joined.nearest_vertex_distance_sq) {
5990 joined.nearest_vertex = b.nearest_vertex;
5991 joined.nearest_vertex_distance_sq = b.nearest_vertex_distance_sq;
5993 return joined;
5996 return nvtd.nearest_vertex;
5999 struct SculptTopologyIDFloodFillData {
6000 int next_id;
6003 } // namespace blender::ed::sculpt_paint
6005 void SCULPT_boundary_info_ensure(Object *object)
6007 using namespace blender;
6008 SculptSession *ss = object->sculpt;
6009 if (!ss->vertex_info.boundary.is_empty()) {
6010 return;
6013 Mesh *base_mesh = BKE_mesh_from_object(object);
6015 ss->vertex_info.boundary.resize(base_mesh->verts_num);
6016 Array<int> adjacent_faces_edge_count(base_mesh->edges_num, 0);
6017 array_utils::count_indices(base_mesh->corner_edges(), adjacent_faces_edge_count);
6019 const blender::Span<int2> edges = base_mesh->edges();
6020 for (const int e : edges.index_range()) {
6021 if (adjacent_faces_edge_count[e] < 2) {
6022 const int2 &edge = edges[e];
6023 ss->vertex_info.boundary[edge[0]].set();
6024 ss->vertex_info.boundary[edge[1]].set();
6029 void SCULPT_fake_neighbors_ensure(Object *ob, const float max_dist)
6031 using namespace blender::ed::sculpt_paint;
6032 SculptSession *ss = ob->sculpt;
6033 const int totvert = SCULPT_vertex_count_get(ss);
6035 /* Fake neighbors were already initialized with the same distance, so no need to be
6036 * recalculated.
6038 if (ss->fake_neighbors.fake_neighbor_index &&
6039 ss->fake_neighbors.current_max_distance == max_dist)
6041 return;
6044 SCULPT_topology_islands_ensure(ob);
6045 fake_neighbor_init(ss, max_dist);
6047 for (int i = 0; i < totvert; i++) {
6048 const PBVHVertRef from_v = BKE_pbvh_index_to_vertex(ss->pbvh, i);
6050 /* This vertex does not have a fake neighbor yet, search one for it. */
6051 if (ss->fake_neighbors.fake_neighbor_index[i] == FAKE_NEIGHBOR_NONE) {
6052 const PBVHVertRef to_v = fake_neighbor_search(ob, from_v, max_dist);
6053 if (to_v.i != PBVH_REF_NONE) {
6054 /* Add the fake neighbor if available. */
6055 fake_neighbor_add(ss, from_v, to_v);
6061 void SCULPT_fake_neighbors_enable(Object *ob)
6063 SculptSession *ss = ob->sculpt;
6064 BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr);
6065 ss->fake_neighbors.use_fake_neighbors = true;
6068 void SCULPT_fake_neighbors_disable(Object *ob)
6070 SculptSession *ss = ob->sculpt;
6071 BLI_assert(ss->fake_neighbors.fake_neighbor_index != nullptr);
6072 ss->fake_neighbors.use_fake_neighbors = false;
6075 void SCULPT_fake_neighbors_free(Object *ob)
6077 using namespace blender::ed::sculpt_paint;
6078 SculptSession *ss = ob->sculpt;
6079 sculpt_pose_fake_neighbors_free(ss);
6082 namespace blender::ed::sculpt_paint::auto_mask {
6084 NodeData node_begin(Object &object, const Cache *automasking, PBVHNode &node)
6086 if (!automasking) {
6087 return {};
6090 NodeData automask_data;
6091 automask_data.have_orig_data = automasking->settings.flags &
6092 (BRUSH_AUTOMASKING_BRUSH_NORMAL | BRUSH_AUTOMASKING_VIEW_NORMAL);
6094 if (automask_data.have_orig_data) {
6095 SCULPT_orig_vert_data_init(&automask_data.orig_data, &object, &node, undo::Type::Position);
6097 else {
6098 memset(&automask_data.orig_data, 0, sizeof(automask_data.orig_data));
6100 return automask_data;
6103 void node_update(auto_mask::NodeData &automask_data, PBVHVertexIter &vd)
6105 if (automask_data.have_orig_data) {
6106 SCULPT_orig_vert_data_update(&automask_data.orig_data, &vd);
6110 } // namespace blender::ed::sculpt_paint::auto_mask
6112 bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool original)
6114 using namespace blender;
6115 float ray_start[3], ray_end[3], ray_normal[3], face_normal[3];
6116 float co[3];
6118 copy_v3_v3(co, SCULPT_vertex_co_get(ss, vertex));
6120 ViewContext *vc = ss->cache ? ss->cache->vc : &ss->filter_cache->vc;
6122 const blender::float2 mouse = ED_view3d_project_float_v2_m4(
6123 vc->region, co, ss->cache ? ss->cache->projection_mat : ss->filter_cache->viewmat);
6125 int depth = SCULPT_raycast_init(vc, mouse, ray_end, ray_start, ray_normal, original);
6127 negate_v3(ray_normal);
6129 copy_v3_v3(ray_start, SCULPT_vertex_co_get(ss, vertex));
6130 madd_v3_v3fl(ray_start, ray_normal, 0.002);
6132 SculptRaycastData srd = {nullptr};
6133 srd.original = original;
6134 srd.ss = ss;
6135 srd.hit = false;
6136 srd.ray_start = ray_start;
6137 srd.ray_normal = ray_normal;
6138 srd.depth = depth;
6139 srd.face_normal = face_normal;
6140 srd.corner_verts = ss->corner_verts;
6142 isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal);
6143 bke::pbvh::raycast(
6144 ss->pbvh,
6145 [&](PBVHNode &node, float *tmin) { sculpt_raycast_cb(node, srd, tmin); },
6146 ray_start,
6147 ray_normal,
6148 srd.original);
6150 return srd.hit;
6153 void SCULPT_stroke_id_next(Object *ob)
6155 /* Manually wrap in int32 space to avoid tripping up undefined behavior
6156 * sanitizers.
6158 ob->sculpt->stroke_id = uchar((int(ob->sculpt->stroke_id) + 1) & 255);
6161 void SCULPT_stroke_id_ensure(Object *ob)
6163 using namespace blender;
6164 SculptSession *ss = ob->sculpt;
6166 if (!ss->attrs.automasking_stroke_id) {
6167 SculptAttributeParams params = {0};
6168 ss->attrs.automasking_stroke_id = BKE_sculpt_attribute_ensure(
6170 bke::AttrDomain::Point,
6171 CD_PROP_INT8,
6172 SCULPT_ATTRIBUTE_NAME(automasking_stroke_id),
6173 &params);
6177 int SCULPT_vertex_island_get(const SculptSession *ss, PBVHVertRef vertex)
6179 if (ss->attrs.topology_island_key) {
6180 return *static_cast<uint8_t *>(SCULPT_vertex_attr_get(vertex, ss->attrs.topology_island_key));
6183 return -1;
6186 void SCULPT_topology_islands_invalidate(SculptSession *ss)
6188 ss->islands_valid = false;
6191 void SCULPT_topology_islands_ensure(Object *ob)
6193 using namespace blender;
6194 using namespace blender::ed::sculpt_paint;
6195 SculptSession *ss = ob->sculpt;
6197 if (ss->attrs.topology_island_key && ss->islands_valid && BKE_pbvh_type(ss->pbvh) != PBVH_BMESH)
6199 return;
6202 SculptAttributeParams params;
6203 params.permanent = params.stroke_only = params.simple_array = false;
6205 ss->attrs.topology_island_key = BKE_sculpt_attribute_ensure(
6207 bke::AttrDomain::Point,
6208 CD_PROP_INT8,
6209 SCULPT_ATTRIBUTE_NAME(topology_island_key),
6210 &params);
6211 SCULPT_vertex_random_access_ensure(ss);
6213 int totvert = SCULPT_vertex_count_get(ss);
6214 Set<PBVHVertRef> visit;
6215 Vector<PBVHVertRef> stack;
6216 uint8_t island_nr = 0;
6218 for (int i = 0; i < totvert; i++) {
6219 PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i);
6221 if (visit.contains(vertex)) {
6222 continue;
6225 stack.clear();
6226 stack.append(vertex);
6227 visit.add(vertex);
6229 while (stack.size()) {
6230 PBVHVertRef vertex2 = stack.pop_last();
6231 SculptVertexNeighborIter ni;
6233 *static_cast<uint8_t *>(
6234 SCULPT_vertex_attr_get(vertex2, ss->attrs.topology_island_key)) = island_nr;
6236 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, vertex2, ni) {
6237 if (visit.add(ni.vertex) && hide::vert_any_face_visible_get(ss, ni.vertex)) {
6238 stack.append(ni.vertex);
6241 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
6244 island_nr++;
6247 ss->islands_valid = true;
6250 void SCULPT_cube_tip_init(Sculpt * /*sd*/, Object *ob, Brush *brush, float mat[4][4])
6252 using namespace blender::ed::sculpt_paint;
6253 SculptSession *ss = ob->sculpt;
6254 float scale[4][4];
6255 float tmat[4][4];
6256 float unused[4][4];
6258 zero_m4(mat);
6259 calc_brush_local_mat(0.0, ob, unused, mat);
6261 /* Note: we ignore the radius scaling done inside of calc_brush_local_mat to
6262 * duplicate prior behavior.
6264 * TODO: try disabling this and check that all edge cases work properly.
6266 normalize_m4(mat);
6268 scale_m4_fl(scale, ss->cache->radius);
6269 mul_m4_m4m4(tmat, mat, scale);
6270 mul_v3_fl(tmat[1], brush->tip_scale_x);
6271 invert_m4_m4(mat, tmat);
6273 /** \} */