Blender  V3.3
paint_mask.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2012 by Nicholas Bishop. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_mesh_types.h"
11 #include "DNA_meshdata_types.h"
12 #include "DNA_modifier_types.h"
13 #include "DNA_object_types.h"
14 #include "DNA_vec_types.h"
15 
16 #include "BLI_alloca.h"
17 #include "BLI_bitmap_draw_2d.h"
18 #include "BLI_lasso_2d.h"
19 #include "BLI_math_geom.h"
20 #include "BLI_math_matrix.h"
21 #include "BLI_polyfill_2d.h"
22 #include "BLI_rect.h"
23 #include "BLI_task.h"
24 #include "BLI_utildefines.h"
25 
26 #include "BKE_brush.h"
27 #include "BKE_ccg.h"
28 #include "BKE_context.h"
29 #include "BKE_lib_id.h"
30 #include "BKE_mesh.h"
31 #include "BKE_multires.h"
32 #include "BKE_paint.h"
33 #include "BKE_pbvh.h"
34 #include "BKE_subsurf.h"
35 
36 #include "DEG_depsgraph.h"
37 
38 #include "RNA_access.h"
39 #include "RNA_define.h"
40 
41 #include "WM_api.h"
42 #include "WM_types.h"
43 
44 #include "ED_screen.h"
45 #include "ED_sculpt.h"
46 #include "ED_view3d.h"
47 
48 #include "bmesh.h"
49 #include "bmesh_tools.h"
50 #include "tools/bmesh_boolean.h"
51 
52 #include "paint_intern.h"
53 
54 /* For undo push. */
55 #include "sculpt_intern.h"
56 
57 #include <stdlib.h>
58 
59 static const EnumPropertyItem mode_items[] = {
61  "VALUE",
62  0,
63  "Value",
64  "Set mask to the level specified by the 'value' property"},
66  "VALUE_INVERSE",
67  0,
68  "Value Inverted",
69  "Set mask to the level specified by the inverted 'value' property"},
70  {PAINT_MASK_INVERT, "INVERT", 0, "Invert", "Invert the mask"},
71  {0}};
72 
73 static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float value)
74 {
75  switch (mode) {
77  (*elem) = value;
78  break;
80  (*elem) = 1.0f - value;
81  break;
82  case PAINT_MASK_INVERT:
83  (*elem) = 1.0f - (*elem);
84  break;
85  }
86 }
87 
88 typedef struct MaskTaskData {
92  bool multires;
93 
95  float value;
97 
99  float view_normal[3];
101 
102 static void mask_flood_fill_task_cb(void *__restrict userdata,
103  const int i,
104  const TaskParallelTLS *__restrict UNUSED(tls))
105 {
106  MaskTaskData *data = userdata;
107 
108  PBVHNode *node = data->nodes[i];
109 
110  const PaintMaskFloodMode mode = data->mode;
111  const float value = data->value;
112  bool redraw = false;
113 
114  PBVHVertexIter vi;
115 
117 
119  float prevmask = *vi.mask;
120  mask_flood_fill_set_elem(vi.mask, mode, value);
121  if (prevmask != *vi.mask) {
122  redraw = true;
123  }
124  }
126 
127  if (redraw) {
129  if (data->multires) {
131  }
132  }
133 }
134 
136 {
139  PaintMaskFloodMode mode;
140  float value;
141  PBVH *pbvh;
142  PBVHNode **nodes;
143  int totnode;
144  bool multires;
145 
146  mode = RNA_enum_get(op->ptr, "mode");
147  value = RNA_float_get(op->ptr, "value");
148 
149  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
150  pbvh = ob->sculpt->pbvh;
151  multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
152 
153  BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
154 
155  SCULPT_undo_push_begin(ob, "Mask flood fill");
156 
157  MaskTaskData data = {
158  .ob = ob,
159  .pbvh = pbvh,
160  .nodes = nodes,
161  .multires = multires,
162  .mode = mode,
163  .value = value,
164  };
165 
166  TaskParallelSettings settings;
167  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
168  BLI_task_parallel_range(0, totnode, &data, mask_flood_fill_task_cb, &settings);
169 
170  if (multires) {
172  }
173 
175 
177 
178  if (nodes) {
179  MEM_freeN(nodes);
180  }
181 
183 
184  return OPERATOR_FINISHED;
185 }
186 
188 {
189  /* Identifiers. */
190  ot->name = "Mask Flood Fill";
191  ot->idname = "PAINT_OT_mask_flood_fill";
192  ot->description = "Fill the whole mask with a given value, or invert its values";
193 
194  /* API callbacks. */
197 
199 
200  /* RNA. */
203  ot->srna,
204  "value",
205  0.0f,
206  0.0f,
207  1.0f,
208  "Value",
209  "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
210  0.0f,
211  1.0f);
212 }
213 
214 /* Sculpt Gesture Operators. */
215 
221 
222 typedef struct LassoGestureData {
223  float projviewobjmat[4][4];
224 
226  int width;
227 
228  /* 2D bitmap to test if a vertex is affected by the lasso shape. */
231 
232 typedef struct LineGestureData {
233  /* Plane aligned to the gesture line. */
234  float true_plane[4];
235  float plane[4];
236 
237  /* Planes to limit the action to the length of the gesture segment at both sides of the affected
238  * area. */
239  float side_plane[2][4];
240  float true_side_plane[2][4];
242 
243  bool flip;
245 
247 
248 typedef struct SculptGestureContext {
251 
252  /* Enabled and currently active symmetry. */
255 
256  /* Operation parameters. */
259 
261 
262  /* Gesture data. */
263  /* Screen space points that represent the gesture shape. */
266 
267  /* View parameters. */
269  float view_normal[3];
270 
272  float view_origin[3];
273 
274  float true_clip_planes[4][4];
275  float clip_planes[4][4];
276 
277  /* These store the view origin and normal in world space, which is used in some gestures to
278  * generate geometry aligned from the view directly in world space. */
279  /* World space view origin and normal are not affected by object symmetry when doing symmetry
280  * passes, so there is no separate variables with the `true_` prefix to store their original
281  * values without symmetry modifications. */
284 
285  /* Lasso Gesture. */
287 
288  /* Line Gesture. */
290 
291  /* Task Callback Data. */
293  int totnode;
295 
296 typedef struct SculptGestureOperation {
297  /* Initial setup (data updates, special undo push...). */
299 
300  /* Apply the gesture action for each symmetry pass. */
302 
303  /* Remaining actions after finishing the symmetry passes iterations
304  * (updating data-layers, tagging PBVH updates...). */
307 
309 {
311  "use_front_faces_only",
312  false,
313  "Front Faces Only",
314  "Affect only faces facing towards the view");
315 
317  "use_limit_to_segment",
318  false,
319  "Limit to Segment",
320  "Apply the gesture action only to the area that is contained within the "
321  "segment without extending its effect to the entire line");
322 }
323 
325  wmOperator *op,
326  SculptGestureContext *sgcontext)
327 {
329  ED_view3d_viewcontext_init(C, &sgcontext->vc, depsgraph);
330  Object *ob = sgcontext->vc.obact;
331 
332  /* Operator properties. */
333  sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
334  sgcontext->line.use_side_planes = RNA_boolean_get(op->ptr, "use_limit_to_segment");
335 
336  /* SculptSession */
337  sgcontext->ss = ob->sculpt;
338 
339  /* Symmetry. */
340  sgcontext->symm = SCULPT_mesh_symmetry_xyz_get(ob);
341 
342  /* View Normal. */
343  float mat[3][3];
344  float view_dir[3] = {0.0f, 0.0f, 1.0f};
345  copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv);
346  mul_m3_v3(mat, view_dir);
347  normalize_v3_v3(sgcontext->world_space_view_normal, view_dir);
348  copy_m3_m4(mat, ob->imat);
349  mul_m3_v3(mat, view_dir);
350  normalize_v3_v3(sgcontext->true_view_normal, view_dir);
351 
352  /* View Origin. */
353  copy_v3_v3(sgcontext->world_space_view_origin, sgcontext->vc.rv3d->viewinv[3]);
354  copy_v3_v3(sgcontext->true_view_origin, sgcontext->vc.rv3d->viewinv[3]);
355 }
356 
357 static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
358 {
359  SculptGestureContext *mcontext = user_data;
360  LassoGestureData *lasso = &mcontext->lasso;
361  int index = (y * lasso->width) + x;
362  int index_end = (y * lasso->width) + x_end;
363  do {
364  BLI_BITMAP_ENABLE(lasso->mask_px, index);
365  } while (++index != index_end);
366 }
367 
369 {
371  "sculpt gesture context lasso");
373 
374  sculpt_gesture_context_init_common(C, op, sgcontext);
375 
376  int mcoords_len;
377  const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
378 
379  if (!mcoords) {
380  return NULL;
381  }
382 
384  sgcontext->vc.rv3d, sgcontext->vc.obact, sgcontext->lasso.projviewobjmat);
385  BLI_lasso_boundbox(&sgcontext->lasso.boundbox, mcoords, mcoords_len);
386  const int lasso_width = 1 + sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin;
387  const int lasso_height = 1 + sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin;
388  sgcontext->lasso.width = lasso_width;
389  sgcontext->lasso.mask_px = BLI_BITMAP_NEW(lasso_width * lasso_height, __func__);
390 
392  sgcontext->lasso.boundbox.ymin,
393  sgcontext->lasso.boundbox.xmax,
394  sgcontext->lasso.boundbox.ymax,
395  mcoords,
396  mcoords_len,
398  sgcontext);
399 
400  BoundBox bb;
402  sgcontext->true_clip_planes,
403  sgcontext->vc.region,
404  sgcontext->vc.obact,
405  &sgcontext->lasso.boundbox);
406 
407  sgcontext->gesture_points = MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points");
408  sgcontext->tot_gesture_points = mcoords_len;
409  for (int i = 0; i < mcoords_len; i++) {
410  sgcontext->gesture_points[i][0] = mcoords[i][0];
411  sgcontext->gesture_points[i][1] = mcoords[i][1];
412  }
413 
414  MEM_freeN((void *)mcoords);
415 
416  return sgcontext;
417 }
418 
420 {
422  "sculpt gesture context box");
424 
425  sculpt_gesture_context_init_common(C, op, sgcontext);
426 
427  rcti rect;
429 
430  BoundBox bb;
432  &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect);
433 
434  sgcontext->gesture_points = MEM_calloc_arrayN(4, sizeof(float[2]), "trim points");
435  sgcontext->tot_gesture_points = 4;
436 
437  sgcontext->gesture_points[0][0] = rect.xmax;
438  sgcontext->gesture_points[0][1] = rect.ymax;
439 
440  sgcontext->gesture_points[1][0] = rect.xmax;
441  sgcontext->gesture_points[1][1] = rect.ymin;
442 
443  sgcontext->gesture_points[2][0] = rect.xmin;
444  sgcontext->gesture_points[2][1] = rect.ymin;
445 
446  sgcontext->gesture_points[3][0] = rect.xmin;
447  sgcontext->gesture_points[3][1] = rect.ymax;
448  return sgcontext;
449 }
450 
451 static void sculpt_gesture_line_plane_from_tri(float *r_plane,
452  SculptGestureContext *sgcontext,
453  const bool flip,
454  const float p1[3],
455  const float p2[3],
456  const float p3[3])
457 {
458  float normal[3];
459  normal_tri_v3(normal, p1, p2, p3);
460  mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
461  if (flip) {
462  mul_v3_fl(normal, -1.0f);
463  }
464  float plane_point_object_space[3];
465  mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1);
466  plane_from_point_normal_v3(r_plane, plane_point_object_space, normal);
467 }
468 
469 /* Creates 4 points in the plane defined by the line and 2 extra points with an offset relative to
470  * this plane. */
472  float line_points[2][2],
473  float r_plane_points[4][3],
474  float r_offset_plane_points[2][3])
475 {
476  float depth_point[3];
477  add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
479  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[0]);
481  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[3]);
482 
483  madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
485  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[1]);
487  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[2]);
488 
489  float normal[3];
490  normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]);
491  add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal);
492  add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal);
493 }
494 
496 {
498  "sculpt gesture context line");
500 
501  sculpt_gesture_context_init_common(C, op, sgcontext);
502 
503  float line_points[2][2];
504  line_points[0][0] = RNA_int_get(op->ptr, "xstart");
505  line_points[0][1] = RNA_int_get(op->ptr, "ystart");
506  line_points[1][0] = RNA_int_get(op->ptr, "xend");
507  line_points[1][1] = RNA_int_get(op->ptr, "yend");
508 
509  sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip");
510 
511  float plane_points[4][3];
512  float offset_plane_points[2][3];
514  sgcontext, line_points, plane_points, offset_plane_points);
515 
516  /* Calculate line plane and normal. */
517  const bool flip = sgcontext->line.flip ^ (!sgcontext->vc.rv3d->is_persp);
519  sgcontext,
520  flip,
521  plane_points[0],
522  plane_points[1],
523  plane_points[2]);
524 
525  /* Calculate the side planes. */
527  sgcontext,
528  false,
529  plane_points[1],
530  plane_points[0],
531  offset_plane_points[0]);
533  sgcontext,
534  false,
535  plane_points[3],
536  plane_points[2],
537  offset_plane_points[1]);
538 
539  return sgcontext;
540 }
541 
543 {
544  MEM_SAFE_FREE(sgcontext->lasso.mask_px);
545  MEM_SAFE_FREE(sgcontext->gesture_points);
546  MEM_SAFE_FREE(sgcontext->operation);
547  MEM_SAFE_FREE(sgcontext->nodes);
548  MEM_SAFE_FREE(sgcontext);
549 }
550 
551 static void flip_plane(float out[4], const float in[4], const char symm)
552 {
553  if (symm & PAINT_SYMM_X) {
554  out[0] = -in[0];
555  }
556  else {
557  out[0] = in[0];
558  }
559  if (symm & PAINT_SYMM_Y) {
560  out[1] = -in[1];
561  }
562  else {
563  out[1] = in[1];
564  }
565  if (symm & PAINT_SYMM_Z) {
566  out[2] = -in[2];
567  }
568  else {
569  out[2] = in[2];
570  }
571 
572  out[3] = in[3];
573 }
574 
576  const ePaintSymmetryFlags symmpass)
577 {
578  sgcontext->symmpass = symmpass;
579  for (int j = 0; j < 4; j++) {
580  flip_plane(sgcontext->clip_planes[j], sgcontext->true_clip_planes[j], symmpass);
581  }
582 
583  negate_m4(sgcontext->clip_planes);
584 
585  flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass);
586  flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass);
587  flip_plane(sgcontext->line.plane, sgcontext->line.true_plane, symmpass);
588  flip_plane(sgcontext->line.side_plane[0], sgcontext->line.true_side_plane[0], symmpass);
589  flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass);
590 }
591 
593 {
594  SculptSession *ss = sgcontext->ss;
595  float clip_planes[3][4];
596  copy_v4_v4(clip_planes[0], sgcontext->line.plane);
597  copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]);
598  copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]);
599 
600  const int num_planes = sgcontext->line.use_side_planes ? 3 : 1;
601  PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes};
604  &frustum,
605  &sgcontext->nodes,
606  &sgcontext->totnode);
607 }
608 
610 {
611  SculptSession *ss = sgcontext->ss;
612  float clip_planes[4][4];
613  copy_m4_m4(clip_planes, sgcontext->clip_planes);
614  negate_m4(clip_planes);
615  PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4};
618  &frustum,
619  &sgcontext->nodes,
620  &sgcontext->totnode);
621 }
622 
624 {
625  switch (sgcontext->shape_type) {
629  break;
632  break;
633  }
634 }
635 
636 static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3])
637 {
638  float scr_co_f[2];
639  int scr_co_s[2];
640  float co_final[3];
641 
642  flip_v3_v3(co_final, co, sgcontext->symmpass);
643 
644  /* First project point to 2d space. */
646  sgcontext->vc.region, co_final, scr_co_f, sgcontext->lasso.projviewobjmat);
647 
648  scr_co_s[0] = scr_co_f[0];
649  scr_co_s[1] = scr_co_f[1];
650 
651  /* Clip against lasso boundbox. */
652  LassoGestureData *lasso = &sgcontext->lasso;
653  if (!BLI_rcti_isect_pt(&lasso->boundbox, scr_co_s[0], scr_co_s[1])) {
654  return false;
655  }
656 
657  scr_co_s[0] -= lasso->boundbox.xmin;
658  scr_co_s[1] -= lasso->boundbox.ymin;
659 
660  return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]);
661 }
662 
664 {
665  float vertex_normal[3];
666  SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal);
667  float dot = dot_v3v3(sgcontext->view_normal, vertex_normal);
668  const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f);
669 
670  if (!is_effected_front_face) {
671  return false;
672  }
673 
674  switch (sgcontext->shape_type) {
676  return isect_point_planes_v3(sgcontext->clip_planes, 4, vd->co);
678  return sculpt_gesture_is_effected_lasso(sgcontext, vd->co);
680  if (sgcontext->line.use_side_planes) {
681  return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f &&
682  plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f &&
683  plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f;
684  }
685  return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f;
686  }
687  return false;
688 }
689 
691 {
692  SculptGestureOperation *operation = sgcontext->operation;
693  SCULPT_undo_push_begin(CTX_data_active_object(C), "Sculpt Gesture Apply");
694 
695  operation->sculpt_gesture_begin(C, sgcontext);
696 
697  for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) {
698  if (SCULPT_is_symmetry_iteration_valid(symmpass, sgcontext->symm)) {
699  sculpt_gesture_flip_for_symmetry_pass(sgcontext, symmpass);
701 
702  operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext);
703 
704  MEM_SAFE_FREE(sgcontext->nodes);
705  }
706  }
707 
708  operation->sculpt_gesture_end(C, sgcontext);
709 
712 
714 }
715 
716 /* Face Set Gesture Operation. */
717 
720 
723 
725 {
727  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false);
728 
729  /* Face Sets modifications do a single undo push. */
731 }
732 
733 static void face_set_gesture_apply_task_cb(void *__restrict userdata,
734  const int i,
735  const TaskParallelTLS *__restrict UNUSED(tls))
736 {
737  SculptGestureContext *sgcontext = userdata;
739  sgcontext->operation;
740  PBVHNode *node = sgcontext->nodes[i];
741  PBVHVertexIter vd;
742  bool any_updated = false;
743 
745  if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
746  SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id);
747  any_updated = true;
748  }
749  }
751 
752  if (any_updated) {
754  }
755 }
756 
758  SculptGestureContext *sgcontext)
759 {
760  TaskParallelSettings settings;
761  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
763  0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings);
764 }
765 
767 {
769 }
770 
772  wmOperator *UNUSED(op))
773 {
774  struct Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact);
775  sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Face Set Operation");
776 
778  sgcontext->operation;
779 
781  face_set_operation->op.sculpt_gesture_apply_for_symmetry_pass =
783  face_set_operation->op.sculpt_gesture_end = sculpt_gesture_face_set_end;
784 
786 }
787 
788 /* Mask Gesture Operation. */
789 
792 
794  float value;
796 
798 {
800  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, false, true, false);
801 }
802 
803 static void mask_gesture_apply_task_cb(void *__restrict userdata,
804  const int i,
805  const TaskParallelTLS *__restrict UNUSED(tls))
806 {
807  SculptGestureContext *sgcontext = userdata;
808  SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation;
809  Object *ob = sgcontext->vc.obact;
810  PBVHNode *node = sgcontext->nodes[i];
811 
812  const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS;
813 
814  PBVHVertexIter vd;
815  bool any_masked = false;
816  bool redraw = false;
817 
819  if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
820  float prevmask = *vd.mask;
821  if (!any_masked) {
822  any_masked = true;
823 
825 
826  if (is_multires) {
828  }
829  }
830  mask_flood_fill_set_elem(vd.mask, mask_operation->mode, mask_operation->value);
831  if (prevmask != *vd.mask) {
832  redraw = true;
833  }
834  }
835  }
837 
838  if (redraw) {
840  }
841 }
842 
844  SculptGestureContext *sgcontext)
845 {
846  TaskParallelSettings settings;
847  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
848  BLI_task_parallel_range(0, sgcontext->totnode, sgcontext, mask_gesture_apply_task_cb, &settings);
849 }
850 
852 {
854  if (BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS) {
856  }
858 }
859 
861 {
862  sgcontext->operation = MEM_callocN(sizeof(SculptGestureMaskOperation), "Mask Operation");
863 
864  SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation;
865 
870 
871  mask_operation->mode = RNA_enum_get(op->ptr, "mode");
872  mask_operation->value = RNA_float_get(op->ptr, "value");
873 }
874 
876 {
879  ot->srna,
880  "value",
881  1.0f,
882  0.0f,
883  1.0f,
884  "Value",
885  "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
886  0.0f,
887  1.0f);
888 }
889 
890 /* Trim Gesture Operation. */
891 
898 
899 /* Intersect is not exposed in the UI because it does not work correctly with symmetry (it deletes
900  * the symmetrical part of the mesh in the first symmetry pass). */
903  "DIFFERENCE",
904  0,
905  "Difference",
906  "Use a difference boolean operation"},
907  {SCULPT_GESTURE_TRIM_UNION, "UNION", 0, "Union", "Use a union boolean operation"},
909  "JOIN",
910  0,
911  "Join",
912  "Join the new mesh as separate geometry, without performing any boolean operation"},
913  {0, NULL, 0, NULL, NULL},
914 };
915 
922  "VIEW",
923  0,
924  "View",
925  "Use the view to orientate the trimming shape"},
927  "SURFACE",
928  0,
929  "Surface",
930  "Use the surface normal to orientate the trimming shape"},
931  {0, NULL, 0, NULL, NULL},
932 };
933 
936 
939 
940  float depth_front;
941  float depth_back;
942 
944 
948 
950 {
951  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
952  Mesh *trim_mesh = trim_operation->mesh;
953 
954  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(trim_mesh);
955  BMesh *bm;
956  bm = BM_mesh_create(&allocsize,
957  &((struct BMeshCreateParams){
958  .use_toolflags = true,
959  }));
960 
962  trim_mesh,
963  (&(struct BMeshFromMeshParams){
964  .calc_face_normal = true,
965  .calc_vert_normal = true,
966  }));
970  "recalc_face_normals faces=%hf",
971  BM_ELEM_TAG);
974  (&(struct BMeshToMeshParams){
975  .calc_object_remap = false,
976  }),
977  trim_mesh);
978  BM_mesh_free(bm);
979  BKE_id_free(NULL, trim_mesh);
980  trim_operation->mesh = result;
981 }
982 
983 /* Get the origin and normal that are going to be used for calculating the depth and position the
984  * trimming geometry. */
986  float *r_origin,
987  float *r_normal)
988 {
989  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
990  /* Use the view origin and normal in world space. The trimming mesh coordinates are
991  * calculated in world space, aligned to the view, and then converted to object space to
992  * store them in the final trimming mesh which is going to be used in the boolean operation.
993  */
994  switch (trim_operation->orientation) {
996  copy_v3_v3(r_origin, sgcontext->world_space_view_origin);
997  copy_v3_v3(r_normal, sgcontext->world_space_view_normal);
998  break;
1000  mul_v3_m4v3(r_origin, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_location);
1001  /* Transforming the normal does not take non uniform scaling into account. Sculpt mode is not
1002  * expected to work on object with non uniform scaling. */
1003  copy_v3_v3(r_normal, sgcontext->ss->gesture_initial_normal);
1004  mul_mat3_m4_v3(sgcontext->vc.obact->obmat, r_normal);
1005  break;
1006  }
1007 }
1008 
1010 {
1011  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1012 
1013  SculptSession *ss = sgcontext->ss;
1014  ViewContext *vc = &sgcontext->vc;
1015 
1016  const int totvert = SCULPT_vertex_count_get(ss);
1017 
1018  float shape_plane[4];
1019  float shape_origin[3];
1020  float shape_normal[3];
1021  sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
1022  plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
1023 
1024  trim_operation->depth_front = FLT_MAX;
1025  trim_operation->depth_back = -FLT_MAX;
1026 
1027  for (int i = 0; i < totvert; i++) {
1028  const float *vco = SCULPT_vertex_co_get(ss, i);
1029  /* Convert the coordinates to world space to calculate the depth. When generating the trimming
1030  * mesh, coordinates are first calculated in world space, then converted to object space to
1031  * store them. */
1032  float world_space_vco[3];
1033  mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco);
1034  const float dist = dist_signed_to_plane_v3(world_space_vco, shape_plane);
1035  trim_operation->depth_front = min_ff(dist, trim_operation->depth_front);
1036  trim_operation->depth_back = max_ff(dist, trim_operation->depth_back);
1037  }
1038 
1039  if (trim_operation->use_cursor_depth) {
1040  float world_space_gesture_initial_location[3];
1041  mul_v3_m4v3(
1042  world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location);
1043 
1044  float mid_point_depth;
1045  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1046  mid_point_depth = ss->gesture_initial_hit ?
1047  dist_signed_to_plane_v3(world_space_gesture_initial_location,
1048  shape_plane) :
1049  (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
1050  }
1051  else {
1052  /* When using normal orientation, if the stroke started over the mesh, position the mid point
1053  * at 0 distance from the shape plane. This positions the trimming shape half inside of the
1054  * surface. */
1055  mid_point_depth = ss->gesture_initial_hit ?
1056  0.0f :
1057  (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
1058  }
1059 
1060  float depth_radius;
1061 
1062  if (ss->gesture_initial_hit) {
1063  depth_radius = ss->cursor_radius;
1064  }
1065  else {
1066  /* ss->cursor_radius is only valid if the stroke started
1067  * over the sculpt mesh. If it's not we must
1068  * compute the radius ourselves. See T81452.
1069  */
1070 
1071  Sculpt *sd = CTX_data_tool_settings(vc->C)->sculpt;
1072  Brush *brush = BKE_paint_brush(&sd->paint);
1073  Scene *scene = CTX_data_scene(vc->C);
1074 
1075  if (!BKE_brush_use_locked_size(scene, brush)) {
1076  depth_radius = paint_calc_object_space_radius(
1077  vc, ss->gesture_initial_location, BKE_brush_size_get(scene, brush));
1078  }
1079  else {
1080  depth_radius = BKE_brush_unprojected_radius_get(scene, brush);
1081  }
1082  }
1083 
1084  trim_operation->depth_front = mid_point_depth - depth_radius;
1085  trim_operation->depth_back = mid_point_depth + depth_radius;
1086  }
1087 }
1088 
1090 {
1091  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1092  ViewContext *vc = &sgcontext->vc;
1093  ARegion *region = vc->region;
1094 
1095  const int tot_screen_points = sgcontext->tot_gesture_points;
1096  float(*screen_points)[2] = sgcontext->gesture_points;
1097 
1098  const int trim_totverts = tot_screen_points * 2;
1099  const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points);
1100  trim_operation->mesh = BKE_mesh_new_nomain(
1101  trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys);
1102  trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco");
1103 
1104  float depth_front = trim_operation->depth_front;
1105  float depth_back = trim_operation->depth_back;
1106 
1107  if (!trim_operation->use_cursor_depth) {
1108  /* When using cursor depth, don't modify the depth set by the cursor radius. If full depth is
1109  * used, adding a little padding to the trimming shape can help avoiding booleans with coplanar
1110  * faces. */
1111  depth_front -= 0.1f;
1112  depth_back += 0.1f;
1113  }
1114 
1115  float shape_origin[3];
1116  float shape_normal[3];
1117  float shape_plane[4];
1118  sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
1119  plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
1120 
1121  const float(*ob_imat)[4] = vc->obact->imat;
1122 
1123  /* Write vertices coordinates for the front face. */
1124  float depth_point[3];
1125  madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front);
1126  for (int i = 0; i < tot_screen_points; i++) {
1127  float new_point[3];
1128  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1129  ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
1130  }
1131  else {
1132  ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
1133  madd_v3_v3fl(new_point, shape_normal, depth_front);
1134  }
1135  mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point);
1136  mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point);
1137  }
1138 
1139  /* Write vertices coordinates for the back face. */
1140  madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back);
1141  for (int i = 0; i < tot_screen_points; i++) {
1142  float new_point[3];
1143  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1144  ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
1145  }
1146  else {
1147  ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
1148  madd_v3_v3fl(new_point, shape_normal, depth_back);
1149  }
1150  mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point);
1151  mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point);
1152  }
1153 
1154  /* Get the triangulation for the front/back poly. */
1155  const int tot_tris_face = tot_screen_points - 2;
1156  uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris");
1157  BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris);
1158 
1159  /* Write the front face triangle indices. */
1160  MPoly *mp = trim_operation->mesh->mpoly;
1161  MLoop *ml = trim_operation->mesh->mloop;
1162  for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
1163  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1164  mp->totloop = 3;
1165  ml[0].v = r_tris[i][0];
1166  ml[1].v = r_tris[i][1];
1167  ml[2].v = r_tris[i][2];
1168  }
1169 
1170  /* Write the back face triangle indices. */
1171  for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
1172  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1173  mp->totloop = 3;
1174  ml[0].v = r_tris[i][0] + tot_screen_points;
1175  ml[1].v = r_tris[i][1] + tot_screen_points;
1176  ml[2].v = r_tris[i][2] + tot_screen_points;
1177  }
1178 
1179  MEM_freeN(r_tris);
1180 
1181  /* Write the indices for the lateral triangles. */
1182  for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
1183  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1184  mp->totloop = 3;
1185  int current_index = i;
1186  int next_index = current_index + 1;
1187  if (next_index >= tot_screen_points) {
1188  next_index = 0;
1189  }
1190  ml[0].v = next_index + tot_screen_points;
1191  ml[1].v = next_index;
1192  ml[2].v = current_index;
1193  }
1194 
1195  for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
1196  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1197  mp->totloop = 3;
1198  int current_index = i;
1199  int next_index = current_index + 1;
1200  if (next_index >= tot_screen_points) {
1201  next_index = 0;
1202  }
1203  ml[0].v = current_index;
1204  ml[1].v = current_index + tot_screen_points;
1205  ml[2].v = next_index + tot_screen_points;
1206  }
1207 
1208  BKE_mesh_calc_edges(trim_operation->mesh, false, false);
1210 }
1211 
1213 {
1214  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1215  BKE_id_free(NULL, trim_operation->mesh);
1216  MEM_freeN(trim_operation->true_mesh_co);
1217 }
1218 
1220 {
1221  return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0;
1222 }
1223 
1225 {
1226  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1227  Mesh *sculpt_mesh = BKE_mesh_from_object(sgcontext->vc.obact);
1228  Mesh *trim_mesh = trim_operation->mesh;
1229 
1230  BMesh *bm;
1231  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh);
1232  bm = BM_mesh_create(&allocsize,
1233  &((struct BMeshCreateParams){
1234  .use_toolflags = false,
1235  }));
1236 
1238  trim_mesh,
1239  &((struct BMeshFromMeshParams){
1240  .calc_face_normal = true,
1241  .calc_vert_normal = true,
1242  }));
1243 
1245  sculpt_mesh,
1246  &((struct BMeshFromMeshParams){
1247  .calc_face_normal = true,
1248  .calc_vert_normal = true,
1249  }));
1250 
1251  const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
1252  BMLoop *(*looptris)[3];
1253  looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
1255 
1256  BMIter iter;
1257  int i;
1258  const int i_faces_end = trim_mesh->totpoly;
1259 
1260  /* We need face normals because of 'BM_face_split_edgenet'
1261  * we could calculate on the fly too (before calling split). */
1262 
1263  const short ob_src_totcol = trim_mesh->totcol;
1264  short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
1265 
1266  BMFace *efa;
1267  i = 0;
1268  BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1269  normalize_v3(efa->no);
1270 
1271  /* Temp tag to test which side split faces are from. */
1273 
1274  /* Remap material. */
1275  if (efa->mat_nr < ob_src_totcol) {
1276  efa->mat_nr = material_remap[efa->mat_nr];
1277  }
1278 
1279  if (++i == i_faces_end) {
1280  break;
1281  }
1282  }
1283 
1284  /* Join does not do a boolean operation, it just adds the geometry. */
1285  if (trim_operation->mode != SCULPT_GESTURE_TRIM_JOIN) {
1286  int boolean_mode = 0;
1287  switch (trim_operation->mode) {
1289  boolean_mode = eBooleanModifierOp_Intersect;
1290  break;
1292  boolean_mode = eBooleanModifierOp_Difference;
1293  break;
1295  boolean_mode = eBooleanModifierOp_Union;
1296  break;
1298  BLI_assert(false);
1299  break;
1300  }
1302  bm, looptris, looptris_tot, bm_face_isect_pair, NULL, 2, true, true, false, boolean_mode);
1303  }
1304 
1305  MEM_freeN(looptris);
1306 
1308  (&(struct BMeshToMeshParams){
1309  .calc_object_remap = false,
1310  }),
1311  sculpt_mesh);
1312  BM_mesh_free(bm);
1314  result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true);
1315 }
1316 
1318 {
1322  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false);
1324 }
1325 
1327  SculptGestureContext *sgcontext)
1328 {
1329  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1330  Mesh *trim_mesh = trim_operation->mesh;
1331  for (int i = 0; i < trim_mesh->totvert; i++) {
1332  flip_v3_v3(trim_mesh->mvert[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass);
1333  }
1335  sculpt_gesture_apply_trim(sgcontext);
1336 }
1337 
1339 {
1340  Object *object = sgcontext->vc.obact;
1341  SculptSession *ss = object->sculpt;
1342  ss->face_sets = CustomData_get_layer(&((Mesh *)object->data)->pdata, CD_SCULPT_FACE_SETS);
1343  if (ss->face_sets) {
1344  /* Assign a new Face Set ID to the new faces created by the trim operation. */
1345  const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data);
1346  ED_sculpt_face_sets_initialize_none_to_id(object->data, next_face_set_id);
1347  }
1348 
1350 
1354 }
1355 
1357 {
1358  sgcontext->operation = MEM_callocN(sizeof(SculptGestureTrimOperation), "Trim Operation");
1359 
1360  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1361 
1363  trim_operation->op.sculpt_gesture_apply_for_symmetry_pass =
1365  trim_operation->op.sculpt_gesture_end = sculpt_gesture_trim_end;
1366 
1367  trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode");
1368  trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth");
1369  trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation");
1370 
1371  /* If the cursor was not over the mesh, force the orientation to view. */
1372  if (!sgcontext->ss->gesture_initial_hit) {
1374  }
1375 }
1376 
1378 {
1379  RNA_def_enum(ot->srna,
1380  "trim_mode",
1383  "Trim Mode",
1384  NULL);
1386  ot->srna,
1387  "use_cursor_depth",
1388  false,
1389  "Use Cursor for Depth",
1390  "Use cursor location and radius for the dimensions and position of the trimming shape");
1391  RNA_def_enum(ot->srna,
1392  "trim_orientation",
1395  "Shape Orientation",
1396  NULL);
1397 }
1398 
1399 /* Project Gesture Operation. */
1400 
1404 
1406 {
1408  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, false, false, false);
1409 }
1410 
1411 static void project_line_gesture_apply_task_cb(void *__restrict userdata,
1412  const int i,
1413  const TaskParallelTLS *__restrict UNUSED(tls))
1414 {
1415  SculptGestureContext *sgcontext = userdata;
1416 
1417  PBVHNode *node = sgcontext->nodes[i];
1418  PBVHVertexIter vd;
1419  bool any_updated = false;
1420 
1422 
1424  if (!sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
1425  continue;
1426  }
1427 
1428  float projected_pos[3];
1429  closest_to_plane_v3(projected_pos, sgcontext->line.plane, vd.co);
1430 
1431  float disp[3];
1432  sub_v3_v3v3(disp, projected_pos, vd.co);
1433  const float mask = vd.mask ? *vd.mask : 0.0f;
1434  mul_v3_fl(disp, 1.0f - mask);
1435  if (is_zero_v3(disp)) {
1436  continue;
1437  }
1438  add_v3_v3(vd.co, disp);
1439  if (vd.mvert) {
1440  BKE_pbvh_vert_tag_update_normal(sgcontext->ss->pbvh, vd.index);
1441  }
1442  any_updated = true;
1443  }
1445 
1446  if (any_updated) {
1448  }
1449 }
1450 
1452  SculptGestureContext *sgcontext)
1453 {
1454  TaskParallelSettings settings;
1455  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
1456 
1457  switch (sgcontext->shape_type) {
1460  0, sgcontext->totnode, sgcontext, project_line_gesture_apply_task_cb, &settings);
1461  break;
1464  /* Gesture shape projection not implemented yet. */
1465  BLI_assert(false);
1466  break;
1467  }
1468 }
1469 
1471 {
1472  SculptSession *ss = sgcontext->ss;
1474  if (ss->deform_modifiers_active || ss->shapekey_active) {
1475  SCULPT_flush_stroke_deform(sd, sgcontext->vc.obact, true);
1476  }
1477 
1480 }
1481 
1483  wmOperator *UNUSED(op))
1484 {
1485  sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Project Operation");
1486 
1488  sgcontext->operation;
1489 
1494 }
1495 
1497 {
1499  if (!sgcontext) {
1500  return OPERATOR_CANCELLED;
1501  }
1502  sculpt_gesture_init_mask_properties(sgcontext, op);
1503  sculpt_gesture_apply(C, sgcontext);
1504  sculpt_gesture_context_free(sgcontext);
1505  return OPERATOR_FINISHED;
1506 }
1507 
1509 {
1511  if (!sgcontext) {
1512  return OPERATOR_CANCELLED;
1513  }
1514  sculpt_gesture_init_mask_properties(sgcontext, op);
1515  sculpt_gesture_apply(C, sgcontext);
1516  sculpt_gesture_context_free(sgcontext);
1517  return OPERATOR_FINISHED;
1518 }
1519 
1521 {
1523  if (!sgcontext) {
1524  return OPERATOR_CANCELLED;
1525  }
1526  sculpt_gesture_init_mask_properties(sgcontext, op);
1527  sculpt_gesture_apply(C, sgcontext);
1528  sculpt_gesture_context_free(sgcontext);
1529  return OPERATOR_FINISHED;
1530 }
1531 
1533 {
1535  if (!sgcontext) {
1536  return OPERATOR_CANCELLED;
1537  }
1539  sculpt_gesture_apply(C, sgcontext);
1540  sculpt_gesture_context_free(sgcontext);
1541  return OPERATOR_FINISHED;
1542 }
1543 
1545 {
1547  if (!sgcontext) {
1548  return OPERATOR_CANCELLED;
1549  }
1551  sculpt_gesture_apply(C, sgcontext);
1552  sculpt_gesture_context_free(sgcontext);
1553  return OPERATOR_FINISHED;
1554 }
1555 
1557 {
1558  Object *object = CTX_data_active_object(C);
1559  SculptSession *ss = object->sculpt;
1560  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1561  /* Not supported in Multires and Dyntopo. */
1562  return OPERATOR_CANCELLED;
1563  }
1564 
1565  if (ss->totvert == 0) {
1566  /* No geometry to trim or to detect a valid position for the trimming shape. */
1567  return OPERATOR_CANCELLED;
1568  }
1569 
1571  if (!sgcontext) {
1572  return OPERATOR_CANCELLED;
1573  }
1574 
1575  sculpt_gesture_init_trim_properties(sgcontext, op);
1576  sculpt_gesture_apply(C, sgcontext);
1577  sculpt_gesture_context_free(sgcontext);
1578  return OPERATOR_FINISHED;
1579 }
1580 
1582 {
1584  SculptSession *ss = ob->sculpt;
1585 
1587  const float mval_fl[2] = {UNPACK2(event->mval)};
1589  ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
1590  if (ss->gesture_initial_hit) {
1593  }
1594 
1595  return WM_gesture_box_invoke(C, op, event);
1596 }
1597 
1599 {
1600  Object *object = CTX_data_active_object(C);
1601  SculptSession *ss = object->sculpt;
1602  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1603  /* Not supported in Multires and Dyntopo. */
1604  return OPERATOR_CANCELLED;
1605  }
1606 
1607  if (ss->totvert == 0) {
1608  /* No geometry to trim or to detect a valid position for the trimming shape. */
1609  return OPERATOR_CANCELLED;
1610  }
1611 
1613  if (!sgcontext) {
1614  return OPERATOR_CANCELLED;
1615  }
1616  sculpt_gesture_init_trim_properties(sgcontext, op);
1617  sculpt_gesture_apply(C, sgcontext);
1618  sculpt_gesture_context_free(sgcontext);
1619  return OPERATOR_FINISHED;
1620 }
1621 
1623 {
1625  SculptSession *ss = ob->sculpt;
1626 
1628  const float mval_fl[2] = {UNPACK2(event->mval)};
1630  ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
1631  if (ss->gesture_initial_hit) {
1634  }
1635 
1636  return WM_gesture_lasso_invoke(C, op, event);
1637 }
1638 
1640 {
1642  if (!sgcontext) {
1643  return OPERATOR_CANCELLED;
1644  }
1646  sculpt_gesture_apply(C, sgcontext);
1647  sculpt_gesture_context_free(sgcontext);
1648  return OPERATOR_FINISHED;
1649 }
1650 
1652 {
1653  ot->name = "Mask Lasso Gesture";
1654  ot->idname = "PAINT_OT_mask_lasso_gesture";
1655  ot->description = "Add mask within the lasso as you move the brush";
1656 
1660 
1662 
1664 
1665  /* Properties. */
1668 
1670 }
1671 
1673 {
1674  ot->name = "Mask Box Gesture";
1675  ot->idname = "PAINT_OT_mask_box_gesture";
1676  ot->description = "Add mask within the box as you move the brush";
1677 
1681 
1683 
1684  ot->flag = OPTYPE_REGISTER;
1685 
1686  /* Properties. */
1689 
1691 }
1692 
1694 {
1695  ot->name = "Mask Line Gesture";
1696  ot->idname = "PAINT_OT_mask_line_gesture";
1697  ot->description = "Add mask to the right of a line as you move the brush";
1698 
1702 
1704 
1705  ot->flag = OPTYPE_REGISTER;
1706 
1707  /* Properties. */
1710 
1712 }
1713 
1715 {
1716  ot->name = "Face Set Lasso Gesture";
1717  ot->idname = "SCULPT_OT_face_set_lasso_gesture";
1718  ot->description = "Add face set within the lasso as you move the brush";
1719 
1723 
1725 
1727 
1728  /* Properties. */
1731 }
1732 
1734 {
1735  ot->name = "Face Set Box Gesture";
1736  ot->idname = "SCULPT_OT_face_set_box_gesture";
1737  ot->description = "Add face set within the box as you move the brush";
1738 
1742 
1744 
1745  ot->flag = OPTYPE_REGISTER;
1746 
1747  /* Properties. */
1750 }
1751 
1753 {
1754  ot->name = "Trim Lasso Gesture";
1755  ot->idname = "SCULPT_OT_trim_lasso_gesture";
1756  ot->description = "Trims the mesh within the lasso as you move the brush";
1757 
1761 
1763 
1765 
1766  /* Properties. */
1769 
1771 }
1772 
1774 {
1775  ot->name = "Trim Box Gesture";
1776  ot->idname = "SCULPT_OT_trim_box_gesture";
1777  ot->description = "Trims the mesh within the box as you move the brush";
1778 
1782 
1784 
1785  ot->flag = OPTYPE_REGISTER;
1786 
1787  /* Properties. */
1790 
1792 }
1793 
1795 {
1796  ot->name = "Project Line Gesture";
1797  ot->idname = "SCULPT_OT_project_line_gesture";
1798  ot->description = "Project the geometry onto a plane defined by a line";
1799 
1803 
1805 
1806  ot->flag = OPTYPE_REGISTER;
1807 
1808  /* Properties. */
1811 }
typedef float(TangentPoint)[2]
int BKE_brush_size_get(const struct Scene *scene, const struct Brush *brush)
float BKE_brush_unprojected_radius_get(const struct Scene *scene, const struct Brush *brush)
bool BKE_brush_use_locked_size(const struct Scene *scene, const struct Brush *brush)
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
Definition: context.c:1282
void * CustomData_get_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.cc:2065
void BKE_id_free(struct Main *bmain, void *idv)
struct Mesh * BKE_mesh_from_object(struct Object *ob)
Definition: mesh.cc:1365
void BKE_mesh_nomain_to_mesh(struct Mesh *mesh_src, struct Mesh *mesh_dst, struct Object *ob, const struct CustomData_MeshMasks *mask, bool take_ownership)
struct Mesh * BKE_mesh_from_bmesh_nomain(struct BMesh *bm, const struct BMeshToMeshParams *params, const struct Mesh *me_settings)
struct Mesh * BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
Definition: mesh.cc:991
void BKE_mesh_batch_cache_dirty_tag(struct Mesh *me, eMeshBatchDirtyMode mode)
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, bool select_new_edges)
@ BKE_MESH_BATCH_DIRTY_ALL
void multires_mark_as_modified(struct Depsgraph *depsgraph, struct Object *object, enum MultiresModifiedFlags flags)
Definition: multires.c:387
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool is_paint_tool)
Definition: paint.c:1914
struct Brush * BKE_paint_brush(struct Paint *paint)
Definition: paint.c:607
A BVH for high poly meshes.
void BKE_pbvh_node_mark_update(PBVHNode *node)
Definition: pbvh.c:1869
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:439
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
Definition: pbvh.c:1895
bool BKE_pbvh_node_frustum_contain_AABB(PBVHNode *node, void *frustum)
Definition: pbvh.c:2793
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1798
void BKE_pbvh_node_mark_normals_update(PBVHNode *node)
Definition: pbvh.c:1911
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:509
void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
Definition: pbvh.c:1967
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:391
@ PBVH_GRIDS
Definition: BKE_pbvh.h:235
@ PBVH_FACES
Definition: BKE_pbvh.h:234
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3211
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
Definition: pbvh.c:1567
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1875
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:838
@ PBVH_UpdateVisibility
Definition: BKE_pbvh.h:72
@ PBVH_UpdateMask
Definition: BKE_pbvh.h:71
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:67
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:22
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_NEW(_num, _alloc_string)
Definition: BLI_bitmap.h:40
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition: BLI_bitmap.h:74
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
void BLI_bitmap_draw_2d_poly_v2i_n(int xmin, int ymin, int xmax, int ymax, const int verts[][2], int verts_len, void(*callback)(int x, int x_end, int y, void *), void *user_data)
void BLI_lasso_boundbox(struct rcti *rect, const int mcoords[][2], unsigned int mcoords_len)
Definition: lasso_2d.c:15
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
float dist_signed_to_plane_v3(const float p[3], const float plane[4])
Definition: math_geom.c:461
MINLINE int poly_to_tri_count(int poly_count, int corner_count)
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:401
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:33
bool isect_point_planes_v3(float(*planes)[4], int totplane, const float p[3])
Definition: math_geom.c:2054
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:926
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:87
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:790
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void negate_m4(float R[4][4])
Definition: math_matrix.c:1011
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:800
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_polyfill_calc(const float(*coords)[2], unsigned int coords_num, int coords_sign, unsigned int(*r_tris)[3])
Definition: polyfill_2d.c:875
bool BLI_rcti_isect_pt(const struct rcti *rect, int x, int y)
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:94
#define UNPACK2(a)
#define UNUSED(x)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ CD_SCULPT_FACE_SETS
@ eBooleanModifierOp_Intersect
@ eBooleanModifierOp_Union
@ eBooleanModifierOp_Difference
Object is a sort of wrapper for general info.
ePaintSymmetryFlags
@ PAINT_SYMM_Y
@ PAINT_SYMM_X
@ PAINT_SYMM_Z
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, int new_id)
bool ED_view3d_win_to_3d_on_plane(const struct ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, const struct Object *ob, float r_pmat[4][4])
void ED_view3d_project_float_v2_m4(const struct ARegion *region, const float co[3], float r_co[2], const float mat[4][4])
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], const struct ARegion *region, const struct Object *ob, const struct rcti *rect)
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
@ OPTYPE_DEPENDS_ON_CURSOR
Definition: WM_types.h:184
@ OPTYPE_REGISTER
Definition: WM_types.h:146
bool BM_mesh_boolean(BMesh *UNUSED(bm), struct BMLoop *(*looptris)[3], const int UNUSED(looptris_tot), int(*test_fn)(BMFace *, void *), void *UNUSED(user_data), const int UNUSED(nshapes), const bool UNUSED(use_self), const bool UNUSED(keep_hidden), const bool UNUSED(hole_tolerant), const int UNUSED(boolean_mode))
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
@ BM_ELEM_DRAW
Definition: bmesh_class.h:486
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:14
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
Definition: bmesh_mesh.cc:258
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
Definition: bmesh_mesh.cc:125
#define BMALLOC_TEMPLATE_FROM_ME(...)
Definition: bmesh_mesh.h:197
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3])
@ BMO_FLAG_RESPECT_HIDE
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_FLAG_DEFAULTS
OperationNode * node
Scene scene
const Depsgraph * depsgraph
void * user_data
SyclQueue void void size_t num_bytes void
IconTextureDrawCall normal
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:34
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static const pxr::TfToken out("out", pxr::TfToken::Immortal)
PaintMaskFloodMode
Definition: paint_intern.h:472
@ PAINT_MASK_FLOOD_VALUE_INVERSE
Definition: paint_intern.h:474
@ PAINT_MASK_FLOOD_VALUE
Definition: paint_intern.h:473
@ PAINT_MASK_INVERT
Definition: paint_intern.h:475
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius)
Definition: paint_utils.c:130
BLI_INLINE void flip_v3_v3(float out[3], const float in[3], const ePaintSymmetryFlags symm)
Definition: paint_intern.h:392
static void sculpt_gesture_project_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1405
static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1317
static int sculpt_trim_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1556
static void flip_plane(float out[4], const float in[4], const char symm)
Definition: paint_mask.c:551
static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:843
eSculptTrimOperationType
Definition: paint_mask.c:892
@ SCULPT_GESTURE_TRIM_UNION
Definition: paint_mask.c:895
@ SCULPT_GESTURE_TRIM_DIFFERENCE
Definition: paint_mask.c:894
@ SCULPT_GESTURE_TRIM_INTERSECT
Definition: paint_mask.c:893
@ SCULPT_GESTURE_TRIM_JOIN
Definition: paint_mask.c:896
static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1089
static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float value)
Definition: paint_mask.c:73
void SCULPT_OT_trim_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1773
struct SculptGestureContext SculptGestureContext
static void mask_gesture_apply_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:803
static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1338
static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1544
static int project_gesture_line_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1639
static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3])
Definition: paint_mask.c:636
void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1733
static const EnumPropertyItem mode_items[]
Definition: paint_mask.c:59
static SculptGestureContext * sculpt_gesture_init_from_line(bContext *C, wmOperator *op)
Definition: paint_mask.c:495
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1794
struct SculptGestureProjectOperation SculptGestureProjectOperation
static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:1377
static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op)
Definition: paint_mask.c:860
static void sculpt_gesture_context_init_common(bContext *C, wmOperator *op, SculptGestureContext *sgcontext)
Definition: paint_mask.c:324
static void sculpt_gesture_context_free(SculptGestureContext *sgcontext)
Definition: paint_mask.c:542
static void sculpt_gesture_line_plane_from_tri(float *r_plane, SculptGestureContext *sgcontext, const bool flip, const float p1[3], const float p2[3], const float p3[3])
Definition: paint_mask.c:451
static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:757
enum eSculptGestureShapeType eMaskGesturesShapeType
static int mask_flood_fill_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:135
struct SculptGestureOperation SculptGestureOperation
static void sculpt_gesture_project_end(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1470
static void mask_flood_fill_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:102
static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1326
void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1752
static void paint_mask_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:875
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot)
Definition: paint_mask.c:187
static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd)
Definition: paint_mask.c:663
static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1508
static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext)
Definition: paint_mask.c:592
static EnumPropertyItem prop_trim_orientation_types[]
Definition: paint_mask.c:920
void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1714
static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1496
static int sculpt_trim_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1598
static void project_line_gesture_apply_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:1411
static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:690
static int face_set_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1532
static void sculpt_gesture_trim_shape_origin_normal_get(SculptGestureContext *sgcontext, float *r_origin, float *r_normal)
Definition: paint_mask.c:985
static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext, wmOperator *UNUSED(op))
Definition: paint_mask.c:771
struct SculptGestureFaceSetOperation SculptGestureFaceSetOperation
static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:724
static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1224
eSculptTrimOrientationType
Definition: paint_mask.c:916
@ SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE
Definition: paint_mask.c:918
@ SCULPT_GESTURE_TRIM_ORIENTATION_VIEW
Definition: paint_mask.c:917
static void sculpt_gesture_trim_geometry_free(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1212
eSculptGestureShapeType
Definition: paint_mask.c:216
@ SCULPT_GESTURE_SHAPE_LINE
Definition: paint_mask.c:219
@ SCULPT_GESTURE_SHAPE_LASSO
Definition: paint_mask.c:218
@ SCULPT_GESTURE_SHAPE_BOX
Definition: paint_mask.c:217
static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1520
static void sculpt_gesture_mask_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:797
static SculptGestureContext * sculpt_gesture_init_from_box(bContext *C, wmOperator *op)
Definition: paint_mask.c:419
static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext)
Definition: paint_mask.c:949
static EnumPropertyItem prop_trim_operation_types[]
Definition: paint_mask.c:901
static void sculpt_gesture_project_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1451
static void sculpt_gesture_face_set_end(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:766
struct SculptGestureMaskOperation SculptGestureMaskOperation
void PAINT_OT_mask_line_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1693
static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1009
static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontext, const ePaintSymmetryFlags symmpass)
Definition: paint_mask.c:575
static SculptGestureContext * sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op)
Definition: paint_mask.c:368
struct MaskTaskData MaskTaskData
static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, wmOperator *op)
Definition: paint_mask.c:1356
void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1672
static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: paint_mask.c:1581
static void sculpt_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:308
struct SculptGestureTrimOperation SculptGestureTrimOperation
static void face_set_gesture_apply_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:733
struct LineGestureData LineGestureData
static void sculpt_gesture_init_project_properties(SculptGestureContext *sgcontext, wmOperator *UNUSED(op))
Definition: paint_mask.c:1482
static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:851
static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgcontext, float line_points[2][2], float r_plane_points[4][3], float r_offset_plane_points[2][3])
Definition: paint_mask.c:471
static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: paint_mask.c:1622
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1651
static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
Definition: paint_mask.c:1219
static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureContext *sgcontext)
Definition: paint_mask.c:609
struct LassoGestureData LassoGestureData
static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext)
Definition: paint_mask.c:623
static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
Definition: paint_mask.c:357
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:125
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:111
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
Definition: sculpt.c:4835
void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
Definition: sculpt.c:483
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
Definition: sculpt.c:1025
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
Definition: sculpt.c:103
void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
Definition: sculpt.c:5212
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
Definition: sculpt.c:5144
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
Definition: sculpt.c:171
bool SCULPT_mode_poll_view3d(bContext *C)
Definition: sculpt.c:3963
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:3957
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:317
void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
Definition: sculpt.c:3719
void SCULPT_tag_update_overlays(bContext *C)
Definition: sculpt.c:1048
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1545
void SCULPT_undo_push_end(struct Object *ob)
Definition: sculpt_undo.c:1575
@ SCULPT_UPDATE_COORDS
Definition: sculpt_intern.h:45
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
Definition: sculpt_undo.c:1419
@ SCULPT_UNDO_GEOMETRY
@ SCULPT_UNDO_FACE_SETS
@ SCULPT_UNDO_COORDS
@ SCULPT_UNDO_MASK
short mat_nr
Definition: bmesh_class.h:281
float no[3]
Definition: bmesh_class.h:271
int totloop
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297
float projviewobjmat[4][4]
Definition: paint_mask.c:223
BLI_bitmap * mask_px
Definition: paint_mask.c:229
float true_plane[4]
Definition: paint_mask.c:234
float side_plane[2][4]
Definition: paint_mask.c:239
bool use_side_planes
Definition: paint_mask.c:241
float true_side_plane[2][4]
Definition: paint_mask.c:240
float plane[4]
Definition: paint_mask.c:235
unsigned int v
float co[3]
PBVH * pbvh
Definition: paint_mask.c:90
PaintMaskFloodMode mode
Definition: paint_mask.c:94
bool multires
Definition: paint_mask.c:92
bool front_faces_only
Definition: paint_mask.c:98
float(* clip_planes_final)[4]
Definition: paint_mask.c:96
Object * ob
Definition: paint_mask.c:89
float value
Definition: paint_mask.c:95
PBVHNode ** nodes
Definition: paint_mask.c:91
float view_normal[3]
Definition: paint_mask.c:99
struct MVert * mvert
struct MLoop * mloop
int totpoly
short totcol
struct MPoly * mpoly
float imat[4][4]
float obmat[4][4]
struct SculptSession * sculpt
void * data
float(* planes)[4]
Definition: BKE_pbvh.h:86
struct MVert * mvert
Definition: BKE_pbvh.h:428
float * co
Definition: BKE_pbvh.h:430
float * mask
Definition: BKE_pbvh.h:433
PBVHNode * nodes
Definition: pbvh_intern.h:136
float viewinv[4][4]
eMaskGesturesShapeType shape_type
Definition: paint_mask.c:257
SculptSession * ss
Definition: paint_mask.c:249
float clip_planes[4][4]
Definition: paint_mask.c:275
PBVHNode ** nodes
Definition: paint_mask.c:292
float true_view_normal[3]
Definition: paint_mask.c:268
LineGestureData line
Definition: paint_mask.c:289
float world_space_view_origin[3]
Definition: paint_mask.c:282
float true_view_origin[3]
Definition: paint_mask.c:271
float world_space_view_normal[3]
Definition: paint_mask.c:283
float true_clip_planes[4][4]
Definition: paint_mask.c:274
float(* gesture_points)[2]
Definition: paint_mask.c:264
ePaintSymmetryFlags symmpass
Definition: paint_mask.c:254
LassoGestureData lasso
Definition: paint_mask.c:286
struct SculptGestureOperation * operation
Definition: paint_mask.c:260
ePaintSymmetryFlags symm
Definition: paint_mask.c:253
SculptGestureOperation op
Definition: paint_mask.c:719
PaintMaskFloodMode mode
Definition: paint_mask.c:793
SculptGestureOperation op
Definition: paint_mask.c:791
void(* sculpt_gesture_begin)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:298
void(* sculpt_gesture_apply_for_symmetry_pass)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:301
void(* sculpt_gesture_end)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:305
SculptGestureOperation operation
Definition: paint_mask.c:1402
eSculptTrimOperationType mode
Definition: paint_mask.c:945
SculptGestureOperation op
Definition: paint_mask.c:935
eSculptTrimOrientationType orientation
Definition: paint_mask.c:946
int * face_sets
Definition: BKE_paint.h:536
struct KeyBlock * shapekey_active
Definition: BKE_paint.h:505
float gesture_initial_location[3]
Definition: BKE_paint.h:584
float gesture_initial_normal[3]
Definition: BKE_paint.h:585
bool gesture_initial_hit
Definition: BKE_paint.h:586
struct PBVH * pbvh
Definition: BKE_paint.h:550
bool deform_modifiers_active
Definition: BKE_paint.h:555
Paint paint
struct ARegion * region
Definition: ED_view3d.h:69
struct Object * obact
Definition: ED_view3d.h:67
struct View3D * v3d
Definition: ED_view3d.h:70
struct RegionView3D * rv3d
Definition: ED_view3d.h:72
int ymin
Definition: DNA_vec_types.h:64
int ymax
Definition: DNA_vec_types.h:64
int xmin
Definition: DNA_vec_types.h:63
int xmax
Definition: DNA_vec_types.h:63
int mval[2]
Definition: WM_types.h:684
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct PointerRNA * ptr
@ WM_CURSOR_EDIT
Definition: wm_cursors.h:22
wmOperatorType * ot
Definition: wm_files.c:3479
int WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const int(* WM_gesture_lasso_path_to_array(bContext *UNUSED(C), wmOperator *op, int *r_mcoords_len))[2]
int WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmEvent *event)
int WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_border_to_rcti(struct wmOperator *op, rcti *rect)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)