1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2020 Blender Foundation.
17 * All rights reserved.
18 */
19
20 /** \file
21 * \ingroup edsculpt
22 */
23
24 #include "MEM_guardedalloc.h"
25
26 #include "BLI_blenlib.h"
27 #include "BLI_edgehash.h"
28 #include "BLI_math.h"
29 #include "BLI_task.h"
30
31 #include "DNA_brush_types.h"
32 #include "DNA_mesh_types.h"
33 #include "DNA_meshdata_types.h"
34 #include "DNA_object_types.h"
35
36 #include "BKE_brush.h"
37 #include "BKE_ccg.h"
38 #include "BKE_colortools.h"
39 #include "BKE_context.h"
40 #include "BKE_mesh.h"
41 #include "BKE_multires.h"
42 #include "BKE_node.h"
43 #include "BKE_object.h"
44 #include "BKE_paint.h"
45 #include "BKE_pbvh.h"
46 #include "BKE_scene.h"
47
48 #include "paint_intern.h"
49 #include "sculpt_intern.h"
50
51 #include "GPU_immediate.h"
52 #include "GPU_immediate_util.h"
53 #include "GPU_matrix.h"
54 #include "GPU_state.h"
55
56 #include "bmesh.h"
57
58 #include <math.h>
59 #include <stdlib.h>
60
61 #define BOUNDARY_VERTEX_NONE -1
62 #define BOUNDARY_STEPS_NONE -1
63
64 typedef struct BoundaryInitialVertexFloodFillData {
65 int initial_vertex;
66 int boundary_initial_vertex_steps;
67 int boundary_initial_vertex;
68 int *floodfill_steps;
69 float radius_sq;
70 } BoundaryInitialVertexFloodFillData;
71
boundary_initial_vertex_floodfill_cb(SculptSession * ss,int from_v,int to_v,bool is_duplicate,void * userdata)72 static bool boundary_initial_vertex_floodfill_cb(
73 SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
74 {
75 BoundaryInitialVertexFloodFillData *data = userdata;
76
77 if (!SCULPT_vertex_visible_get(ss, to_v)) {
78 return false;
79 }
80
81 if (!is_duplicate) {
82 data->floodfill_steps[to_v] = data->floodfill_steps[from_v] + 1;
83 }
84 else {
85 data->floodfill_steps[to_v] = data->floodfill_steps[from_v];
86 }
87
88 if (SCULPT_vertex_is_boundary(ss, to_v)) {
89 if (data->floodfill_steps[to_v] < data->boundary_initial_vertex_steps) {
90 data->boundary_initial_vertex_steps = data->floodfill_steps[to_v];
91 data->boundary_initial_vertex = to_v;
92 }
93 }
94
95 const float len_sq = len_squared_v3v3(SCULPT_vertex_co_get(ss, data->initial_vertex),
96 SCULPT_vertex_co_get(ss, to_v));
97 return len_sq < data->radius_sq;
98 }
99
100 /* From a vertex index anywhere in the mesh, returns the closest vertex in a mesh boundary inside
101 * the given radius, if it exists. */
sculpt_boundary_get_closest_boundary_vertex(SculptSession * ss,const int initial_vertex,const float radius)102 static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss,
103 const int initial_vertex,
104 const float radius)
105 {
106
107 if (SCULPT_vertex_is_boundary(ss, initial_vertex)) {
108 return initial_vertex;
109 }
110
111 SculptFloodFill flood;
112 SCULPT_floodfill_init(ss, &flood);
113 SCULPT_floodfill_add_initial(&flood, initial_vertex);
114
115 BoundaryInitialVertexFloodFillData fdata = {
116 .initial_vertex = initial_vertex,
117 .boundary_initial_vertex = BOUNDARY_VERTEX_NONE,
118 .boundary_initial_vertex_steps = INT_MAX,
119 .radius_sq = radius * radius,
120 };
121
122 fdata.floodfill_steps = MEM_calloc_arrayN(
123 SCULPT_vertex_count_get(ss), sizeof(int), "floodfill steps");
124
125 SCULPT_floodfill_execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata);
126 SCULPT_floodfill_free(&flood);
127
128 MEM_freeN(fdata.floodfill_steps);
129 return fdata.boundary_initial_vertex;
130 }
131
132 /* Used to allocate the memory of the boundary index arrays. This was decided considered the most
133 * common use cases for the brush deformers, taking into account how many vertices those
134 * deformations usually need in the boundary. */
135 static int BOUNDARY_INDICES_BLOCK_SIZE = 300;
136
sculpt_boundary_index_add(SculptBoundary * boundary,const int new_index,const float distance,GSet * included_vertices)137 static void sculpt_boundary_index_add(SculptBoundary *boundary,
138 const int new_index,
139 const float distance,
140 GSet *included_vertices)
141 {
142
143 boundary->vertices[boundary->num_vertices] = new_index;
144 if (boundary->distance) {
145 boundary->distance[new_index] = distance;
146 }
147 if (included_vertices) {
148 BLI_gset_add(included_vertices, POINTER_FROM_INT(new_index));
149 }
150 boundary->num_vertices++;
151 if (boundary->num_vertices >= boundary->vertices_capacity) {
152 boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
153 boundary->vertices = MEM_reallocN_id(
154 boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices");
155 }
156 };
157
sculpt_boundary_preview_edge_add(SculptBoundary * boundary,const int v1,const int v2)158 static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2)
159 {
160
161 boundary->edges[boundary->num_edges].v1 = v1;
162 boundary->edges[boundary->num_edges].v2 = v2;
163 boundary->num_edges++;
164
165 if (boundary->num_edges >= boundary->edges_capacity) {
166 boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
167 boundary->edges = MEM_reallocN_id(boundary->edges,
168 boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
169 "boundary edges");
170 }
171 };
172
173 /**
174 * This function is used to check where the propagation should stop when calculating the boundary,
175 * as well as to check if the initial vertex is valid.
176 */
sculpt_boundary_is_vertex_in_editable_boundary(SculptSession * ss,const int initial_vertex)177 static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss,
178 const int initial_vertex)
179 {
180
181 if (!SCULPT_vertex_visible_get(ss, initial_vertex)) {
182 return false;
183 }
184
185 int neighbor_count = 0;
186 int boundary_vertex_count = 0;
187 SculptVertexNeighborIter ni;
188 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, initial_vertex, ni) {
189 if (SCULPT_vertex_visible_get(ss, ni.index)) {
190 neighbor_count++;
191 if (SCULPT_vertex_is_boundary(ss, ni.index)) {
192 boundary_vertex_count++;
193 }
194 }
195 }
196 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
197
198 /* Corners are ambiguous as it can't be decide which boundary should be active. The flood fill
199 * should also stop at corners. */
200 if (neighbor_count <= 2) {
201 return false;
202 }
203
204 /* Non manifold geometry in the mesh boundary.
205 * The deformation result will be unpredictable and not very useful. */
206 if (boundary_vertex_count > 2) {
207 return false;
208 }
209
210 return true;
211 }
212
213 /* Flood fill that adds to the boundary data all the vertices from a boundary and its duplicates.
214 */
215
216 typedef struct BoundaryFloodFillData {
217 SculptBoundary *boundary;
218 GSet *included_vertices;
219 EdgeSet *preview_edges;
220
221 int last_visited_vertex;
222
223 } BoundaryFloodFillData;
224
boundary_floodfill_cb(SculptSession * ss,int from_v,int to_v,bool is_duplicate,void * userdata)225 static bool boundary_floodfill_cb(
226 SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
227 {
228 BoundaryFloodFillData *data = userdata;
229 SculptBoundary *boundary = data->boundary;
230 if (SCULPT_vertex_is_boundary(ss, to_v)) {
231 const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v),
232 SCULPT_vertex_co_get(ss, to_v));
233 const float distance_boundary_to_dst = boundary->distance ?
234 boundary->distance[from_v] + edge_len :
235 0.0f;
236 sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices);
237 if (!is_duplicate) {
238 sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
239 }
240 return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
241 }
242 return false;
243 }
244
sculpt_boundary_indices_init(SculptSession * ss,SculptBoundary * boundary,const bool init_boundary_distances,const int initial_boundary_index)245 static void sculpt_boundary_indices_init(SculptSession *ss,
246 SculptBoundary *boundary,
247 const bool init_boundary_distances,
248 const int initial_boundary_index)
249 {
250
251 const int totvert = SCULPT_vertex_count_get(ss);
252 boundary->vertices = MEM_malloc_arrayN(
253 BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices");
254 if (init_boundary_distances) {
255 boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
256 }
257 boundary->edges = MEM_malloc_arrayN(
258 BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges");
259
260 GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE);
261 SculptFloodFill flood;
262 SCULPT_floodfill_init(ss, &flood);
263
264 boundary->initial_vertex = initial_boundary_index;
265 copy_v3_v3(boundary->initial_vertex_position,
266 SCULPT_vertex_co_get(ss, boundary->initial_vertex));
267 sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices);
268 SCULPT_floodfill_add_initial(&flood, initial_boundary_index);
269
270 BoundaryFloodFillData fdata = {
271 .boundary = boundary,
272 .included_vertices = included_vertices,
273 .last_visited_vertex = BOUNDARY_VERTEX_NONE,
274
275 };
276
277 SCULPT_floodfill_execute(ss, &flood, boundary_floodfill_cb, &fdata);
278 SCULPT_floodfill_free(&flood);
279
280 /* Check if the boundary loops into itself and add the extra preview edge to close the loop. */
281 if (fdata.last_visited_vertex != BOUNDARY_VERTEX_NONE &&
282 sculpt_boundary_is_vertex_in_editable_boundary(ss, fdata.last_visited_vertex)) {
283 SculptVertexNeighborIter ni;
284 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) {
285 if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) &&
286 sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) {
287 sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index);
288 boundary->forms_loop = true;
289 }
290 }
291 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
292 }
293
294 BLI_gset_free(included_vertices, NULL);
295 }
296
297 /**
298 * This functions initializes all data needed to calculate falloffs and deformation from the
299 * boundary into the mesh into a #SculptBoundaryEditInfo array. This includes how many steps are
300 * needed to go from a boundary vertex to an interior vertex and which vertex of the boundary is
301 * the closest one.
302 */
sculpt_boundary_edit_data_init(SculptSession * ss,SculptBoundary * boundary,const int initial_vertex,const float radius)303 static void sculpt_boundary_edit_data_init(SculptSession *ss,
304 SculptBoundary *boundary,
305 const int initial_vertex,
306 const float radius)
307 {
308 const int totvert = SCULPT_vertex_count_get(ss);
309
310 const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
311
312 boundary->edit_info = MEM_malloc_arrayN(
313 totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info");
314
315 for (int i = 0; i < totvert; i++) {
316 boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE;
317 boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE;
318 }
319
320 GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int));
321 GSQueue *next_iteration = BLI_gsqueue_new(sizeof(int));
322
323 /* Initialized the first iteration with the vertices already in the boundary. This is propagation
324 * step 0. */
325 BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices");
326 for (int i = 0; i < boundary->num_vertices; i++) {
327 boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i];
328 boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0;
329
330 /* This ensures that all duplicate vertices in the boundary have the same original_vertex
331 * index, so the deformation for them will be the same. */
332 if (has_duplicates) {
333 SculptVertexNeighborIter ni_duplis;
334 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) {
335 if (ni_duplis.is_duplicate) {
336 boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i];
337 }
338 }
339 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
340 }
341
342 BLI_gsqueue_push(current_iteration, &boundary->vertices[i]);
343 }
344
345 int num_propagation_steps = 0;
346 float accum_distance = 0.0f;
347
348 while (true) {
349 /* Stop adding steps to edit info. This happens when a steps is further away from the boundary
350 * than the brush radius or when the entire mesh was already processed. */
351 if (accum_distance > radius || BLI_gsqueue_is_empty(current_iteration)) {
352 boundary->max_propagation_steps = num_propagation_steps;
353 break;
354 }
355
356 while (!BLI_gsqueue_is_empty(current_iteration)) {
357 int from_v;
358 BLI_gsqueue_pop(current_iteration, &from_v);
359
360 SculptVertexNeighborIter ni;
361 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) {
362 const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index);
363 if (is_visible &&
364 boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) {
365 boundary->edit_info[ni.index].original_vertex =
366 boundary->edit_info[from_v].original_vertex;
367
368 BLI_BITMAP_ENABLE(visited_vertices, ni.index);
369
370 if (ni.is_duplicate) {
371 /* Grids duplicates handling. */
372 boundary->edit_info[ni.index].num_propagation_steps =
373 boundary->edit_info[from_v].num_propagation_steps;
374 }
375 else {
376 boundary->edit_info[ni.index].num_propagation_steps =
377 boundary->edit_info[from_v].num_propagation_steps + 1;
378
379 BLI_gsqueue_push(next_iteration, &ni.index);
380
381 /* When copying the data to the neighbor for the next iteration, it has to be copied to
382 * all its duplicates too. This is because it is not possible to know if the updated
383 * neighbor or one if its uninitialized duplicates is going to come first in order to
384 * copy the data in the from_v neighbor iterator. */
385 if (has_duplicates) {
386 SculptVertexNeighborIter ni_duplis;
387 SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) {
388 if (ni_duplis.is_duplicate) {
389 boundary->edit_info[ni_duplis.index].original_vertex =
390 boundary->edit_info[from_v].original_vertex;
391 boundary->edit_info[ni_duplis.index].num_propagation_steps =
392 boundary->edit_info[from_v].num_propagation_steps + 1;
393 }
394 }
395 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis);
396 }
397
398 /* Check the distance using the vertex that was propagated from the initial vertex that
399 * was used to initialize the boundary. */
400 if (boundary->edit_info[from_v].original_vertex == initial_vertex) {
401 boundary->pivot_vertex = ni.index;
402 copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index));
403 accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v),
404 SCULPT_vertex_co_get(ss, ni.index));
405 }
406 }
407 }
408 }
409 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
410 }
411
412 /* Copy the new vertices to the queue to be processed in the next iteration. */
413 while (!BLI_gsqueue_is_empty(next_iteration)) {
414 int next_v;
415 BLI_gsqueue_pop(next_iteration, &next_v);
416 BLI_gsqueue_push(current_iteration, &next_v);
417 }
418
419 num_propagation_steps++;
420 }
421
422 MEM_SAFE_FREE(visited_vertices);
423
424 BLI_gsqueue_free(current_iteration);
425 BLI_gsqueue_free(next_iteration);
426 }
427
428 /* This functions assigns a falloff factor to each one of the SculptBoundaryEditInfo structs based
429 * on the brush curve and its propagation steps. The falloff goes from the boundary into the mesh.
430 */
sculpt_boundary_falloff_factor_init(SculptSession * ss,SculptBoundary * boundary,Brush * brush,const float radius)431 static void sculpt_boundary_falloff_factor_init(SculptSession *ss,
432 SculptBoundary *boundary,
433 Brush *brush,
434 const float radius)
435 {
436 const int totvert = SCULPT_vertex_count_get(ss);
437 BKE_curvemapping_init(brush->curve);
438
439 for (int i = 0; i < totvert; i++) {
440 if (boundary->edit_info[i].num_propagation_steps != -1) {
441 boundary->edit_info[i].strength_factor = BKE_brush_curve_strength(
442 brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps);
443 }
444
445 if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) {
446 /* All vertices that are propagated from the original vertex won't be affected by the
447 * boundary falloff, so there is no need to calculate anything else. */
448 continue;
449 }
450
451 if (!boundary->distance) {
452 /* There are falloff modes that do not require to modify the previously calculated falloff
453 * based on boundary distances. */
454 continue;
455 }
456
457 const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex];
458 float falloff_distance = 0.0f;
459 float direction = 1.0f;
460
461 switch (brush->boundary_falloff_type) {
462 case BRUSH_BOUNDARY_FALLOFF_RADIUS:
463 falloff_distance = boundary_distance;
464 break;
465 case BRUSH_BOUNDARY_FALLOFF_LOOP: {
466 const int div = boundary_distance / radius;
467 const float mod = fmodf(boundary_distance, radius);
468 falloff_distance = div % 2 == 0 ? mod : radius - mod;
469 } break;
470 case BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT: {
471 const int div = boundary_distance / radius;
472 const float mod = fmodf(boundary_distance, radius);
473 falloff_distance = div % 2 == 0 ? mod : radius - mod;
474 /* Inverts the faloff in the intervals 1 2 5 6 9 10 ... */
475 if (((div - 1) & 2) == 0) {
476 direction = -1.0f;
477 }
478 } break;
479 case BRUSH_BOUNDARY_FALLOFF_CONSTANT:
480 /* For constant falloff distances are not allocated, so this should never happen. */
481 BLI_assert(false);
482 }
483
484 boundary->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength(
485 brush, falloff_distance, radius);
486 }
487 }
488
489 /* Main function to get SculptBoundary data both for brush deformation and viewport preview. Can
490 * return NULL if there is no boundary from the given vertex using the given radius. */
SCULPT_boundary_data_init(Object * object,Brush * brush,const int initial_vertex,const float radius)491 SculptBoundary *SCULPT_boundary_data_init(Object *object,
492 Brush *brush,
493 const int initial_vertex,
494 const float radius)
495 {
496 SculptSession *ss = object->sculpt;
497
498 if (initial_vertex == BOUNDARY_VERTEX_NONE) {
499 return NULL;
500 }
501
502 SCULPT_vertex_random_access_ensure(ss);
503 SCULPT_boundary_info_ensure(object);
504
505 const int boundary_initial_vertex = sculpt_boundary_get_closest_boundary_vertex(
506 ss, initial_vertex, radius);
507
508 if (boundary_initial_vertex == BOUNDARY_VERTEX_NONE) {
509 return NULL;
510 }
511
512 /* Starting from a vertex that is the limit of a boundary is ambiguous, so return NULL instead of
513 * forcing a random active boundary from a corner. */
514 if (!sculpt_boundary_is_vertex_in_editable_boundary(ss, initial_vertex)) {
515 return NULL;
516 }
517
518 SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data");
519
520 const bool init_boundary_distances = brush->boundary_falloff_type !=
521 BRUSH_BOUNDARY_FALLOFF_CONSTANT;
522 sculpt_boundary_indices_init(ss, boundary, init_boundary_distances, boundary_initial_vertex);
523
524 const float boundary_radius = radius * (1.0f + brush->boundary_offset);
525 sculpt_boundary_edit_data_init(ss, boundary, boundary_initial_vertex, boundary_radius);
526
527 return boundary;
528 }
529
SCULPT_boundary_data_free(SculptBoundary * boundary)530 void SCULPT_boundary_data_free(SculptBoundary *boundary)
531 {
532 MEM_SAFE_FREE(boundary->vertices);
533 MEM_SAFE_FREE(boundary->distance);
534 MEM_SAFE_FREE(boundary->edit_info);
535 MEM_SAFE_FREE(boundary->bend.pivot_positions);
536 MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis);
537 MEM_SAFE_FREE(boundary->slide.directions);
538 MEM_SAFE_FREE(boundary);
539 }
540
541 /* These functions initialize the required vectors for the desired deformation using the
542 * SculptBoundaryEditInfo. They calculate the data using the vertices that have the
543 * max_propagation_steps value and them this data is copied to the rest of the vertices using the
544 * original vertex index. */
sculpt_boundary_bend_data_init(SculptSession * ss,SculptBoundary * boundary)545 static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary)
546 {
547 const int totvert = SCULPT_vertex_count_get(ss);
548 boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN(
549 totvert, 3 * sizeof(float), "pivot rotation axis");
550 boundary->bend.pivot_positions = MEM_calloc_arrayN(
551 totvert, 3 * sizeof(float), "pivot positions");
552
553 for (int i = 0; i < totvert; i++) {
554 if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
555 float dir[3];
556 float normal[3];
557 SCULPT_vertex_normal_get(ss, i, normal);
558 sub_v3_v3v3(dir,
559 SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
560 SCULPT_vertex_co_get(ss, i));
561 cross_v3_v3v3(
562 boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal);
563 normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
564 copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex],
565 SCULPT_vertex_co_get(ss, i));
566 }
567 }
568
569 for (int i = 0; i < totvert; i++) {
570 if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
571 copy_v3_v3(boundary->bend.pivot_positions[i],
572 boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]);
573 copy_v3_v3(boundary->bend.pivot_rotation_axis[i],
574 boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]);
575 }
576 }
577 }
578
sculpt_boundary_slide_data_init(SculptSession * ss,SculptBoundary * boundary)579 static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary)
580 {
581 const int totvert = SCULPT_vertex_count_get(ss);
582 boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions");
583
584 for (int i = 0; i < totvert; i++) {
585 if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) {
586 sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex],
587 SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex),
588 SCULPT_vertex_co_get(ss, i));
589 normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]);
590 }
591 }
592
593 for (int i = 0; i < totvert; i++) {
594 if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) {
595 copy_v3_v3(boundary->slide.directions[i],
596 boundary->slide.directions[boundary->edit_info[i].original_vertex]);
597 }
598 }
599 }
600
sculpt_boundary_twist_data_init(SculptSession * ss,SculptBoundary * boundary)601 static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary)
602 {
603 zero_v3(boundary->twist.pivot_position);
604 float(*poly_verts)[3] = MEM_malloc_arrayN(
605 boundary->num_vertices, sizeof(float) * 3, "poly verts");
606 for (int i = 0; i < boundary->num_vertices; i++) {
607 add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i]));
608 copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i]));
609 }
610 mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->num_vertices);
611 if (boundary->forms_loop) {
612 normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->num_vertices);
613 }
614 else {
615 sub_v3_v3v3(boundary->twist.rotation_axis,
616 SCULPT_vertex_co_get(ss, boundary->pivot_vertex),
617 SCULPT_vertex_co_get(ss, boundary->initial_vertex));
618 normalize_v3(boundary->twist.rotation_axis);
619 }
620 MEM_freeN(poly_verts);
621 }
622
sculpt_boundary_displacement_from_grab_delta_get(SculptSession * ss,SculptBoundary * boundary)623 static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss,
624 SculptBoundary *boundary)
625 {
626 float plane[4];
627 float pos[3];
628 float normal[3];
629 sub_v3_v3v3(normal, ss->cache->initial_location, boundary->initial_pivot_position);
630 normalize_v3(normal);
631 plane_from_point_normal_v3(plane, ss->cache->initial_location, normal);
632 add_v3_v3v3(pos, ss->cache->initial_location, ss->cache->grab_delta_symmetry);
633 return dist_signed_to_plane_v3(pos, plane);
634 }
635
636 /* Deformation tasks callbacks. */
do_boundary_brush_bend_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))637 static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata,
638 const int n,
639 const TaskParallelTLS *__restrict UNUSED(tls))
640 {
641 SculptThreadedTaskData *data = userdata;
642 SculptSession *ss = data->ob->sculpt;
643 const int symm_area = ss->cache->mirror_symmetry_pass;
644 SculptBoundary *boundary = ss->cache->boundaries[symm_area];
645 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
646 const Brush *brush = data->brush;
647
648 const float strength = ss->cache->bstrength;
649
650 PBVHVertexIter vd;
651 SculptOrigVertData orig_data;
652 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
653
654 const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
655 float angle_factor = disp / ss->cache->radius;
656 /* Angle Snapping when inverting the brush. */
657 if (ss->cache->invert) {
658 angle_factor = floorf(angle_factor * 10) / 10.0f;
659 }
660 const float angle = angle_factor * M_PI;
661
662 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
663 {
664
665 if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
666 SCULPT_orig_vert_data_update(&orig_data, &vd);
667 if (SCULPT_check_vertex_pivot_symmetry(
668 orig_data.co, boundary->initial_vertex_position, symm)) {
669 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
670 float t_orig_co[3];
671 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
672 sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]);
673 rotate_v3_v3v3fl(target_co,
674 t_orig_co,
675 boundary->bend.pivot_rotation_axis[vd.index],
676 angle * boundary->edit_info[vd.index].strength_factor * mask);
677 add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]);
678 }
679 }
680
681 if (vd.mvert) {
682 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
683 }
684 }
685 BKE_pbvh_vertex_iter_end;
686 }
687
do_boundary_brush_slide_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))688 static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata,
689 const int n,
690 const TaskParallelTLS *__restrict UNUSED(tls))
691 {
692 SculptThreadedTaskData *data = userdata;
693 SculptSession *ss = data->ob->sculpt;
694 const int symm_area = ss->cache->mirror_symmetry_pass;
695 SculptBoundary *boundary = ss->cache->boundaries[symm_area];
696 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
697 const Brush *brush = data->brush;
698
699 const float strength = ss->cache->bstrength;
700
701 PBVHVertexIter vd;
702 SculptOrigVertData orig_data;
703 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
704
705 const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
706
707 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
708 {
709
710 if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
711 SCULPT_orig_vert_data_update(&orig_data, &vd);
712 if (SCULPT_check_vertex_pivot_symmetry(
713 orig_data.co, boundary->initial_vertex_position, symm)) {
714 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
715 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
716 madd_v3_v3v3fl(target_co,
717 orig_data.co,
718 boundary->slide.directions[vd.index],
719 boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
720 }
721 }
722
723 if (vd.mvert) {
724 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
725 }
726 }
727 BKE_pbvh_vertex_iter_end;
728 }
729
do_boundary_brush_inflate_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))730 static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata,
731 const int n,
732 const TaskParallelTLS *__restrict UNUSED(tls))
733 {
734 SculptThreadedTaskData *data = userdata;
735 SculptSession *ss = data->ob->sculpt;
736 const int symm_area = ss->cache->mirror_symmetry_pass;
737 SculptBoundary *boundary = ss->cache->boundaries[symm_area];
738 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
739 const Brush *brush = data->brush;
740
741 const float strength = ss->cache->bstrength;
742
743 PBVHVertexIter vd;
744 SculptOrigVertData orig_data;
745 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
746
747 const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
748
749 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
750 {
751
752 if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
753 SCULPT_orig_vert_data_update(&orig_data, &vd);
754 if (SCULPT_check_vertex_pivot_symmetry(
755 orig_data.co, boundary->initial_vertex_position, symm)) {
756 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
757 float normal[3];
758 normal_short_to_float_v3(normal, orig_data.no);
759 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
760 madd_v3_v3v3fl(target_co,
761 orig_data.co,
762 normal,
763 boundary->edit_info[vd.index].strength_factor * disp * mask * strength);
764 }
765 }
766
767 if (vd.mvert) {
768 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
769 }
770 }
771 BKE_pbvh_vertex_iter_end;
772 }
773
do_boundary_brush_grab_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))774 static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata,
775 const int n,
776 const TaskParallelTLS *__restrict UNUSED(tls))
777 {
778 SculptThreadedTaskData *data = userdata;
779 SculptSession *ss = data->ob->sculpt;
780 const int symm_area = ss->cache->mirror_symmetry_pass;
781 SculptBoundary *boundary = ss->cache->boundaries[symm_area];
782 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
783 const Brush *brush = data->brush;
784
785 const float strength = ss->cache->bstrength;
786
787 PBVHVertexIter vd;
788 SculptOrigVertData orig_data;
789 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
790
791 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
792 {
793
794 if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
795 SCULPT_orig_vert_data_update(&orig_data, &vd);
796 if (SCULPT_check_vertex_pivot_symmetry(
797 orig_data.co, boundary->initial_vertex_position, symm)) {
798 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
799 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
800 madd_v3_v3v3fl(target_co,
801 orig_data.co,
802 ss->cache->grab_delta_symmetry,
803 boundary->edit_info[vd.index].strength_factor * mask * strength);
804 }
805 }
806
807 if (vd.mvert) {
808 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
809 }
810 }
811 BKE_pbvh_vertex_iter_end;
812 }
813
do_boundary_brush_twist_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))814 static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata,
815 const int n,
816 const TaskParallelTLS *__restrict UNUSED(tls))
817 {
818 SculptThreadedTaskData *data = userdata;
819 SculptSession *ss = data->ob->sculpt;
820 const int symm_area = ss->cache->mirror_symmetry_pass;
821 SculptBoundary *boundary = ss->cache->boundaries[symm_area];
822 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
823 const Brush *brush = data->brush;
824
825 const float strength = ss->cache->bstrength;
826
827 PBVHVertexIter vd;
828 SculptOrigVertData orig_data;
829 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
830
831 const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary);
832 float angle_factor = disp / ss->cache->radius;
833 /* Angle Snapping when inverting the brush. */
834 if (ss->cache->invert) {
835 angle_factor = floorf(angle_factor * 10) / 10.0f;
836 }
837 const float angle = angle_factor * M_PI;
838
839 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
840 {
841
842 if (boundary->edit_info[vd.index].num_propagation_steps != -1) {
843 SCULPT_orig_vert_data_update(&orig_data, &vd);
844 if (SCULPT_check_vertex_pivot_symmetry(
845 orig_data.co, boundary->initial_vertex_position, symm)) {
846 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
847 float t_orig_co[3];
848 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
849 sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position);
850 rotate_v3_v3v3fl(target_co,
851 t_orig_co,
852 boundary->twist.rotation_axis,
853 angle * mask * boundary->edit_info[vd.index].strength_factor);
854 add_v3_v3(target_co, boundary->twist.pivot_position);
855 }
856 }
857
858 if (vd.mvert) {
859 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
860 }
861 }
862 BKE_pbvh_vertex_iter_end;
863 }
864
do_boundary_brush_smooth_task_cb_ex(void * __restrict userdata,const int n,const TaskParallelTLS * __restrict UNUSED (tls))865 static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
866 const int n,
867 const TaskParallelTLS *__restrict UNUSED(tls))
868 {
869 SculptThreadedTaskData *data = userdata;
870 SculptSession *ss = data->ob->sculpt;
871 const int symmetry_pass = ss->cache->mirror_symmetry_pass;
872 const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass];
873 const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
874 const Brush *brush = data->brush;
875
876 const float strength = ss->cache->bstrength;
877
878 PBVHVertexIter vd;
879 SculptOrigVertData orig_data;
880 SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
881
882 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
883 {
884 if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
885 continue;
886 }
887
888 SCULPT_orig_vert_data_update(&orig_data, &vd);
889 if (!SCULPT_check_vertex_pivot_symmetry(
890 orig_data.co, boundary->initial_vertex_position, symm)) {
891 continue;
892 }
893
894 float coord_accum[3] = {0.0f, 0.0f, 0.0f};
895 int total_neighbors = 0;
896 const int current_propagation_steps = boundary->edit_info[vd.index].num_propagation_steps;
897 SculptVertexNeighborIter ni;
898 SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) {
899 if (current_propagation_steps == boundary->edit_info[ni.index].num_propagation_steps) {
900 add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.index));
901 total_neighbors++;
902 }
903 }
904 SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
905
906 if (total_neighbors == 0) {
907 continue;
908 }
909 float disp[3];
910 float avg[3];
911 const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
912 mul_v3_v3fl(avg, coord_accum, 1.0f / total_neighbors);
913 sub_v3_v3v3(disp, avg, vd.co);
914 float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
915 madd_v3_v3v3fl(
916 target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength);
917
918 if (vd.mvert) {
919 vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
920 }
921 }
922 BKE_pbvh_vertex_iter_end;
923 }
924
925 /* Main Brush Function. */
SCULPT_do_boundary_brush(Sculpt * sd,Object * ob,PBVHNode ** nodes,int totnode)926 void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
927 {
928 SculptSession *ss = ob->sculpt;
929 Brush *brush = BKE_paint_brush(&sd->paint);
930
931 const int symm_area = ss->cache->mirror_symmetry_pass;
932 if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
933
934 int initial_vertex;
935 if (ss->cache->mirror_symmetry_pass == 0) {
936 initial_vertex = SCULPT_active_vertex_get(ss);
937 }
938 else {
939 float location[3];
940 flip_v3_v3(location, SCULPT_active_vertex_co_get(ss), symm_area);
941 initial_vertex = SCULPT_nearest_vertex_get(
942 sd, ob, location, ss->cache->radius_squared, false);
943 }
944
945 ss->cache->boundaries[symm_area] = SCULPT_boundary_data_init(
946 ob, brush, initial_vertex, ss->cache->initial_radius);
947
948 if (ss->cache->boundaries[symm_area]) {
949
950 switch (brush->boundary_deform_type) {
951 case BRUSH_BOUNDARY_DEFORM_BEND:
952 sculpt_boundary_bend_data_init(ss, ss->cache->boundaries[symm_area]);
953 break;
954 case BRUSH_BOUNDARY_DEFORM_EXPAND:
955 sculpt_boundary_slide_data_init(ss, ss->cache->boundaries[symm_area]);
956 break;
957 case BRUSH_BOUNDARY_DEFORM_TWIST:
958 sculpt_boundary_twist_data_init(ss, ss->cache->boundaries[symm_area]);
959 break;
960 case BRUSH_BOUNDARY_DEFORM_INFLATE:
961 case BRUSH_BOUNDARY_DEFORM_GRAB:
962 /* Do nothing. These deform modes don't need any extra data to be precomputed. */
963 break;
964 }
965
966 sculpt_boundary_falloff_factor_init(
967 ss, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius);
968 }
969 }
970
971 /* No active boundary under the cursor. */
972 if (!ss->cache->boundaries[symm_area]) {
973 return;
974 }
975
976 SculptThreadedTaskData data = {
977 .sd = sd,
978 .ob = ob,
979 .brush = brush,
980 .nodes = nodes,
981 };
982
983 TaskParallelSettings settings;
984 BKE_pbvh_parallel_range_settings(&settings, true, totnode);
985
986 switch (brush->boundary_deform_type) {
987 case BRUSH_BOUNDARY_DEFORM_BEND:
988 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_bend_task_cb_ex, &settings);
989 break;
990 case BRUSH_BOUNDARY_DEFORM_EXPAND:
991 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_slide_task_cb_ex, &settings);
992 break;
993 case BRUSH_BOUNDARY_DEFORM_INFLATE:
994 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_inflate_task_cb_ex, &settings);
995 break;
996 case BRUSH_BOUNDARY_DEFORM_GRAB:
997 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_grab_task_cb_ex, &settings);
998 break;
999 case BRUSH_BOUNDARY_DEFORM_TWIST:
1000 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_twist_task_cb_ex, &settings);
1001 break;
1002 case BRUSH_BOUNDARY_DEFORM_SMOOTH:
1003 BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_smooth_task_cb_ex, &settings);
1004 break;
1005 }
1006 }
1007
SCULPT_boundary_edges_preview_draw(const uint gpuattr,SculptSession * ss,const float outline_col[3],const float outline_alpha)1008 void SCULPT_boundary_edges_preview_draw(const uint gpuattr,
1009 SculptSession *ss,
1010 const float outline_col[3],
1011 const float outline_alpha)
1012 {
1013 if (!ss->boundary_preview) {
1014 return;
1015 }
1016 immUniformColor3fvAlpha(outline_col, outline_alpha);
1017 GPU_line_width(2.0f);
1018 immBegin(GPU_PRIM_LINES, ss->boundary_preview->num_edges * 2);
1019 for (int i = 0; i < ss->boundary_preview->num_edges; i++) {
1020 immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss->boundary_preview->edges[i].v1));
1021 immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss->boundary_preview->edges[i].v2));
1022 }
1023 immEnd();
1024 }
1025
SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr,SculptSession * ss)1026 void SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr, SculptSession *ss)
1027 {
1028 if (!ss->boundary_preview) {
1029 return;
1030 }
1031 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.8f);
1032 GPU_line_width(2.0f);
1033 immBegin(GPU_PRIM_LINES, 2);
1034 immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss->boundary_preview->pivot_vertex));
1035 immVertex3fv(gpuattr, SCULPT_vertex_co_get(ss, ss->boundary_preview->initial_vertex));
1036 immEnd();
1037 }
1038