Blender  V2.93
sculpt_mask_expand.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_math.h"
28 #include "BLI_task.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "DNA_brush_types.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_meshdata_types.h"
35 #include "DNA_object_types.h"
36 
37 #include "BKE_brush.h"
38 #include "BKE_ccg.h"
39 #include "BKE_colortools.h"
40 #include "BKE_context.h"
41 #include "BKE_mesh.h"
42 #include "BKE_multires.h"
43 #include "BKE_node.h"
44 #include "BKE_object.h"
45 #include "BKE_paint.h"
46 #include "BKE_pbvh.h"
47 #include "BKE_scene.h"
48 
49 #include "DEG_depsgraph.h"
50 
51 #include "WM_api.h"
52 #include "WM_message.h"
53 #include "WM_toolsystem.h"
54 #include "WM_types.h"
55 
56 #include "RNA_access.h"
57 #include "RNA_define.h"
58 
59 #include "ED_object.h"
60 #include "ED_screen.h"
61 #include "ED_sculpt.h"
62 #include "ED_view3d.h"
63 #include "paint_intern.h"
64 #include "sculpt_intern.h"
65 
66 #include "bmesh.h"
67 
68 #include <math.h>
69 #include <stdlib.h>
70 
72 {
74  SculptSession *ss = ob->sculpt;
75  const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
76 
77  MEM_freeN(op->customdata);
78 
79  for (int n = 0; n < ss->filter_cache->totnode; n++) {
80  PBVHNode *node = ss->filter_cache->nodes[n];
81  if (create_face_set) {
82  for (int i = 0; i < ss->totfaces; i++) {
83  ss->face_sets[i] = ss->filter_cache->prev_face_set[i];
84  }
85  }
86  else {
87  PBVHVertexIter vd;
89  *vd.mask = ss->filter_cache->prev_mask[vd.index];
90  }
92  }
93 
95  }
96 
97  if (!create_face_set) {
99  }
104 }
105 
106 static void sculpt_expand_task_cb(void *__restrict userdata,
107  const int i,
108  const TaskParallelTLS *__restrict UNUSED(tls))
109 {
110  SculptThreadedTaskData *data = userdata;
111  SculptSession *ss = data->ob->sculpt;
112  PBVHNode *node = data->nodes[i];
113  PBVHVertexIter vd;
114  int update_it = data->mask_expand_update_it;
115 
117  int vi = vd.index;
118  float final_mask = *vd.mask;
119  if (data->mask_expand_use_normals) {
121  ss->filter_cache->normal_factor[vd.index]) {
122  final_mask = 1.0f;
123  }
124  else {
125  final_mask = 0.0f;
126  }
127  }
128  else {
129  if (ss->filter_cache->mask_update_it[vi] <= update_it &&
130  ss->filter_cache->mask_update_it[vi] != 0) {
131  final_mask = 1.0f;
132  }
133  else {
134  final_mask = 0.0f;
135  }
136  }
137 
138  if (data->mask_expand_create_face_set) {
139  if (final_mask == 1.0f) {
141  }
143  }
144  else {
145 
146  if (data->mask_expand_keep_prev_mask) {
147  final_mask = MAX2(ss->filter_cache->prev_mask[vd.index], final_mask);
148  }
149 
150  if (data->mask_expand_invert_mask) {
151  final_mask = 1.0f - final_mask;
152  }
153 
154  if (*vd.mask != final_mask) {
155  if (vd.mvert) {
157  }
158  *vd.mask = final_mask;
160  }
161  }
162  }
164 }
165 
166 static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *event)
167 {
170  SculptSession *ss = ob->sculpt;
172  ARegion *region = CTX_wm_region(C);
173  float prevclick_f[2];
174  copy_v2_v2(prevclick_f, op->customdata);
175  const int prevclick[2] = {(int)prevclick_f[0], (int)prevclick_f[1]};
176  int len = (int)len_v2v2_int(prevclick, event->mval);
177  len = abs(len);
178  int mask_speed = RNA_int_get(op->ptr, "mask_speed");
179  int mask_expand_update_it = len / mask_speed;
180  mask_expand_update_it = mask_expand_update_it + 1;
181 
182  const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
183 
184  if (RNA_boolean_get(op->ptr, "use_cursor")) {
186  float mouse[2];
187  mouse[0] = event->mval[0];
188  mouse[1] = event->mval[1];
189  if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) {
190  /* The cursor is over the mesh, get the update iteration from the updated active vertex. */
191  mask_expand_update_it = ss->filter_cache->mask_update_it[(int)SCULPT_active_vertex_get(ss)];
192  }
193  else {
194  /* When the cursor is outside the mesh, affect the entire connected component. */
195  mask_expand_update_it = ss->filter_cache->mask_update_last_it - 1;
196  }
197  }
198 
199  if ((event->type == EVT_ESCKEY && event->val == KM_PRESS) ||
200  (event->type == RIGHTMOUSE && event->val == KM_PRESS)) {
201  /* Returning OPERATOR_CANCELLED will leak memory due to not finishing
202  * undo. Better solution could be to make paint_mesh_restore_co work
203  * for this case. */
205  return OPERATOR_FINISHED;
206  }
207 
208  if ((event->type == LEFTMOUSE && event->val == KM_RELEASE) ||
209  (event->type == EVT_RETKEY && event->val == KM_PRESS) ||
210  (event->type == EVT_PADENTER && event->val == KM_PRESS)) {
211 
212  /* Smooth iterations. */
213  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
214  const int smooth_iterations = RNA_int_get(op->ptr, "smooth_iterations");
216  sd, ob, ss->filter_cache->nodes, ss->filter_cache->totnode, smooth_iterations);
217 
218  /* Pivot position. */
219  if (RNA_boolean_get(op->ptr, "update_pivot")) {
220  const char symm = SCULPT_mesh_symmetry_xyz_get(ob);
221  const float threshold = 0.2f;
222  float avg[3];
223  int total = 0;
224  zero_v3(avg);
225 
226  for (int n = 0; n < ss->filter_cache->totnode; n++) {
227  PBVHVertexIter vd;
229  const float mask = (vd.mask) ? *vd.mask : 0.0f;
230  if (mask < (0.5f + threshold) && mask > (0.5f - threshold)) {
232  vd.co, ss->filter_cache->mask_expand_initial_co, symm)) {
233  add_v3_v3(avg, vd.co);
234  total++;
235  }
236  }
237  }
239  }
240 
241  if (total > 0) {
242  mul_v3_fl(avg, 1.0f / total);
243  copy_v3_v3(ss->pivot_pos, avg);
244  }
246  }
247 
248  MEM_freeN(op->customdata);
249 
250  for (int i = 0; i < ss->filter_cache->totnode; i++) {
252  }
253 
255 
259  return OPERATOR_FINISHED;
260  }
261 
262  /* When pressing Ctrl, expand directly to the max number of iterations. This allows to flood fill
263  * mask and face sets by connectivity directly. */
264  if (event->ctrl) {
265  mask_expand_update_it = ss->filter_cache->mask_update_last_it - 1;
266  }
267 
269  return OPERATOR_RUNNING_MODAL;
270  }
271 
272  if (mask_expand_update_it == ss->filter_cache->mask_update_current_it) {
273  ED_region_tag_redraw(region);
274  return OPERATOR_RUNNING_MODAL;
275  }
276 
277  if (mask_expand_update_it < ss->filter_cache->mask_update_last_it) {
278 
279  if (create_face_set) {
280  for (int i = 0; i < ss->totfaces; i++) {
281  ss->face_sets[i] = ss->filter_cache->prev_face_set[i];
282  }
283  }
285  .sd = sd,
286  .ob = ob,
287  .nodes = ss->filter_cache->nodes,
288  .mask_expand_update_it = mask_expand_update_it,
289  .mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"),
290  .mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"),
291  .mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"),
292  .mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
293  };
294  TaskParallelSettings settings;
297  ss->filter_cache->mask_update_current_it = mask_expand_update_it;
298  }
299 
301 
302  return OPERATOR_RUNNING_MODAL;
303 }
304 
305 typedef struct MaskExpandFloodFillData {
306  float original_normal[3];
310 
312  SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
313 {
314  MaskExpandFloodFillData *data = userdata;
315 
316  if (!is_duplicate) {
317  int to_it = ss->filter_cache->mask_update_it[from_v] + 1;
318  ss->filter_cache->mask_update_it[to_v] = to_it;
319  if (to_it > ss->filter_cache->mask_update_last_it) {
320  ss->filter_cache->mask_update_last_it = to_it;
321  }
322 
323  if (data->use_normals) {
324  float current_normal[3], prev_normal[3];
325  SCULPT_vertex_normal_get(ss, to_v, current_normal);
326  SCULPT_vertex_normal_get(ss, from_v, prev_normal);
327  const float from_edge_factor = ss->filter_cache->edge_factor[from_v];
328  ss->filter_cache->edge_factor[to_v] = dot_v3v3(current_normal, prev_normal) *
329  from_edge_factor;
330  ss->filter_cache->normal_factor[to_v] = dot_v3v3(data->original_normal, current_normal) *
331  powf(from_edge_factor, data->edge_sensitivity);
332  CLAMP(ss->filter_cache->normal_factor[to_v], 0.0f, 1.0f);
333  }
334  }
335  else {
336  /* PBVH_GRIDS duplicate handling. */
337  ss->filter_cache->mask_update_it[to_v] = ss->filter_cache->mask_update_it[from_v];
338  if (data->use_normals) {
339  ss->filter_cache->edge_factor[to_v] = ss->filter_cache->edge_factor[from_v];
340  ss->filter_cache->normal_factor[to_v] = ss->filter_cache->normal_factor[from_v];
341  }
342  }
343 
344  return true;
345 }
346 
347 static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event)
348 {
351  SculptSession *ss = ob->sculpt;
353  PBVH *pbvh = ob->sculpt->pbvh;
354 
355  const bool use_normals = RNA_boolean_get(op->ptr, "use_normals");
356  const bool create_face_set = RNA_boolean_get(op->ptr, "create_face_set");
357 
359  float mouse[2];
360  mouse[0] = event->mval[0];
361  mouse[1] = event->mval[1];
362 
364 
365  op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position");
366  copy_v2_v2(op->customdata, mouse);
367 
368  SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
369 
370  BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
371 
372  int vertex_count = SCULPT_vertex_count_get(ss);
373 
374  ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
375 
377 
378  SCULPT_undo_push_begin(ob, "Mask Expand");
379 
380  if (create_face_set) {
382  for (int i = 0; i < ss->filter_cache->totnode; i++) {
384  }
385  }
386  else {
387  for (int i = 0; i < ss->filter_cache->totnode; i++) {
390  }
391  }
392 
393  ss->filter_cache->mask_update_it = MEM_callocN(sizeof(int) * vertex_count,
394  "mask update iteration");
395  if (use_normals) {
396  ss->filter_cache->normal_factor = MEM_callocN(sizeof(float) * vertex_count,
397  "mask update normal factor");
398  ss->filter_cache->edge_factor = MEM_callocN(sizeof(float) * vertex_count,
399  "mask update normal factor");
400  for (int i = 0; i < vertex_count; i++) {
401  ss->filter_cache->edge_factor[i] = 1.0f;
402  }
403  }
404 
405  if (create_face_set) {
406  ss->filter_cache->prev_face_set = MEM_callocN(sizeof(float) * ss->totfaces, "prev face mask");
407  for (int i = 0; i < ss->totfaces; i++) {
408  ss->filter_cache->prev_face_set[i] = ss->face_sets[i];
409  }
411  }
412  else {
413  ss->filter_cache->prev_mask = MEM_callocN(sizeof(float) * vertex_count, "prev mask");
414  for (int i = 0; i < vertex_count; i++) {
416  }
417  }
418 
422 
424 
425  SculptFloodFill flood;
426  SCULPT_floodfill_init(ss, &flood);
427  SCULPT_floodfill_add_active(sd, ob, ss, &flood, FLT_MAX);
428 
429  MaskExpandFloodFillData fdata = {
430  .use_normals = use_normals,
431  .edge_sensitivity = RNA_int_get(op->ptr, "edge_sensitivity"),
432  };
435  SCULPT_floodfill_free(&flood);
436 
437  if (use_normals) {
438  for (int repeat = 0; repeat < 2; repeat++) {
439  for (int i = 0; i < vertex_count; i++) {
440  float avg = 0.0f;
443  avg += ss->filter_cache->normal_factor[ni.index];
444  }
446  ss->filter_cache->normal_factor[i] = avg / ni.size;
447  }
448  }
449 
451  }
452 
454  .sd = sd,
455  .ob = ob,
456  .nodes = ss->filter_cache->nodes,
457  .mask_expand_update_it = 0,
458  .mask_expand_use_normals = RNA_boolean_get(op->ptr, "use_normals"),
459  .mask_expand_invert_mask = RNA_boolean_get(op->ptr, "invert"),
460  .mask_expand_keep_prev_mask = RNA_boolean_get(op->ptr, "keep_previous_mask"),
461  .mask_expand_create_face_set = RNA_boolean_get(op->ptr, "create_face_set"),
462  };
463  TaskParallelSettings settings;
466 
467  const char *status_str = TIP_(
468  "Move the mouse to expand the mask from the active vertex. LMB: confirm mask, ESC/RMB: "
469  "cancel");
470  ED_workspace_status_text(C, status_str);
471 
474  return OPERATOR_RUNNING_MODAL;
475 }
476 
478 {
479  /* Identifiers. */
480  ot->name = "Mask Expand";
481  ot->idname = "SCULPT_OT_mask_expand";
482  ot->description = "Expands a mask from the initial active vertex under the cursor";
483 
484  /* API callbacks. */
489 
491  ot->prop = RNA_def_boolean(ot->srna, "invert", true, "Invert", "Invert the new mask");
493  ot->srna, "use_cursor", true, "Use Cursor", "Expand the mask to the cursor position");
495  "update_pivot",
496  true,
497  "Update Pivot Position",
498  "Set the pivot position to the mask border after creating the mask");
499  ot->prop = RNA_def_int(ot->srna, "smooth_iterations", 2, 0, 10, "Smooth Iterations", "", 0, 10);
500  ot->prop = RNA_def_int(ot->srna, "mask_speed", 5, 1, 10, "Mask Speed", "", 1, 10);
501 
503  "use_normals",
504  true,
505  "Use Normals",
506  "Generate the mask using the normals and curvature of the model");
508  "keep_previous_mask",
509  false,
510  "Keep Previous Mask",
511  "Generate the new mask on top of the current one");
512  ot->prop = RNA_def_int(ot->srna,
513  "edge_sensitivity",
514  300,
515  0,
516  2000,
517  "Edge Detection Sensitivity",
518  "Sensitivity for expanding the mask across sculpted sharp edges when "
519  "using normals to generate the mask",
520  0,
521  2000);
523  "create_face_set",
524  false,
525  "Expand Face Mask",
526  "Expand a new Face Mask instead of the sculpt mask");
527 }
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1401
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1208
General operations, lookup, etc. for blender objects.
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
Definition: paint.c:1817
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:384
#define PBVH_ITER_ALL
Definition: BKE_pbvh.h:334
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:457
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:335
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3042
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1738
void BKE_pbvh_node_mark_redraw(PBVHNode *node)
Definition: pbvh.c:1759
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:843
MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define TIP_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ ME_VERT_PBVH_UPDATE
Object is a sort of wrapper for general info.
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
void ED_region_tag_redraw(struct ARegion *region)
Definition: area.c:667
void ED_workspace_status_text(struct bContext *C, const char *str)
Definition: area.c:840
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group RGB to Bright Vector Camera CLAMP
#define C
Definition: RandGen.cpp:39
#define NC_GEOM
Definition: WM_types.h:294
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define KM_PRESS
Definition: WM_types.h:242
#define ND_SELECT
Definition: WM_types.h:407
#define KM_RELEASE
Definition: WM_types.h:243
OperationNode * node
const Depsgraph * depsgraph
#define powf(x, y)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3585
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:120
int SCULPT_active_vertex_get(SculptSession *ss)
Definition: sculpt.c:277
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], bool use_sampled_normal)
Definition: sculpt.c:7452
void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
Definition: sculpt.c:1085
void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
Definition: sculpt.c:489
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
Definition: sculpt.c:285
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
Definition: sculpt.c:112
void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
Definition: sculpt.c:7819
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
Definition: sculpt.c:7759
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:172
void SCULPT_floodfill_free(SculptFloodFill *flood)
Definition: sculpt.c:1188
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:6601
void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3])
Definition: sculpt.c:290
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
Definition: sculpt.c:254
int SCULPT_face_set_next_available_get(SculptSession *ss)
Definition: sculpt.c:700
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:323
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
Definition: sculpt.c:940
void SCULPT_floodfill_add_active(Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
Definition: sculpt.c:1131
void SCULPT_floodfill_execute(SculptSession *ss, SculptFloodFill *flood, bool(*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), void *userdata)
Definition: sculpt.c:1157
void SCULPT_mask_filter_smooth_apply(Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations)
void SCULPT_filter_cache_free(SculptSession *ss)
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1383
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
@ SCULPT_UPDATE_MASK
Definition: sculpt_intern.h:59
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
void SCULPT_undo_push_end(void)
Definition: sculpt_undo.c:1400
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1292
@ SCULPT_UNDO_FACE_SETS
@ SCULPT_UNDO_MASK
static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool mask_expand_floodfill_cb(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
struct MaskExpandFloodFillData MaskExpandFloodFillData
static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void sculpt_expand_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
void SCULPT_OT_mask_expand(wmOperatorType *ot)
float * edge_factor
float * prev_mask
int * mask_update_it
float * normal_factor
int * prev_face_set
int mask_update_last_it
PBVHNode ** nodes
float mask_expand_initial_co[3]
int mask_update_current_it
struct SculptSession * sculpt
void * data
struct MVert * mvert
Definition: BKE_pbvh.h:372
float * co
Definition: BKE_pbvh.h:374
float * mask
Definition: BKE_pbvh.h:377
int * face_sets
Definition: BKE_paint.h:490
float pivot_pos[3]
Definition: BKE_paint.h:567
struct FilterCache * filter_cache
Definition: BKE_paint.h:519
struct PBVH * pbvh
Definition: BKE_paint.h:504
short ctrl
Definition: WM_types.h:618
short val
Definition: WM_types.h:579
int mval[2]
Definition: WM_types.h:583
short type
Definition: WM_types.h:577
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
PropertyRNA * prop
Definition: WM_types.h:814
struct PointerRNA * ptr
__forceinline const avxi abs(const avxi &a)
Definition: util_avxi.h:186
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
uint len
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ EVT_PADENTER
@ MOUSEMOVE
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_RETKEY
wmOperatorType * ot
Definition: wm_files.c:3156