Blender  V2.93
paint_mask.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) 2012 by Nicholas Bishop
17  * All rights reserved.
18  */
19 
24 #include "MEM_guardedalloc.h"
25 
26 #include "DNA_mesh_types.h"
27 #include "DNA_meshdata_types.h"
28 #include "DNA_modifier_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_vec_types.h"
31 
32 #include "BLI_alloca.h"
33 #include "BLI_bitmap_draw_2d.h"
34 #include "BLI_lasso_2d.h"
35 #include "BLI_math_geom.h"
36 #include "BLI_math_matrix.h"
37 #include "BLI_polyfill_2d.h"
38 #include "BLI_rect.h"
39 #include "BLI_task.h"
40 #include "BLI_utildefines.h"
41 
42 #include "BKE_brush.h"
43 #include "BKE_ccg.h"
44 #include "BKE_context.h"
45 #include "BKE_lib_id.h"
46 #include "BKE_mesh.h"
47 #include "BKE_multires.h"
48 #include "BKE_paint.h"
49 #include "BKE_pbvh.h"
50 #include "BKE_subsurf.h"
51 
52 #include "DEG_depsgraph.h"
53 
54 #include "RNA_access.h"
55 #include "RNA_define.h"
56 
57 #include "WM_api.h"
58 #include "WM_types.h"
59 
60 #include "ED_screen.h"
61 #include "ED_sculpt.h"
62 #include "ED_view3d.h"
63 
64 #include "bmesh.h"
65 #include "bmesh_tools.h"
66 #include "tools/bmesh_boolean.h"
67 
68 #include "paint_intern.h"
69 
70 /* For undo push. */
71 #include "sculpt_intern.h"
72 
73 #include <stdlib.h>
74 
75 static const EnumPropertyItem mode_items[] = {
77  "VALUE",
78  0,
79  "Value",
80  "Set mask to the level specified by the 'value' property"},
82  "VALUE_INVERSE",
83  0,
84  "Value Inverted",
85  "Set mask to the level specified by the inverted 'value' property"},
86  {PAINT_MASK_INVERT, "INVERT", 0, "Invert", "Invert the mask"},
87  {0}};
88 
89 static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float value)
90 {
91  switch (mode) {
93  (*elem) = value;
94  break;
96  (*elem) = 1.0f - value;
97  break;
98  case PAINT_MASK_INVERT:
99  (*elem) = 1.0f - (*elem);
100  break;
101  }
102 }
103 
104 typedef struct MaskTaskData {
108  bool multires;
109 
111  float value;
113 
115  float view_normal[3];
117 
118 static void mask_flood_fill_task_cb(void *__restrict userdata,
119  const int i,
120  const TaskParallelTLS *__restrict UNUSED(tls))
121 {
122  MaskTaskData *data = userdata;
123 
124  PBVHNode *node = data->nodes[i];
125 
126  const PaintMaskFloodMode mode = data->mode;
127  const float value = data->value;
128  bool redraw = false;
129 
130  PBVHVertexIter vi;
131 
133 
135  float prevmask = *vi.mask;
136  mask_flood_fill_set_elem(vi.mask, mode, value);
137  if (prevmask != *vi.mask) {
138  redraw = true;
139  }
140  }
142 
143  if (redraw) {
145  if (data->multires) {
147  }
148  }
149 }
150 
152 {
155  PaintMaskFloodMode mode;
156  float value;
157  PBVH *pbvh;
158  PBVHNode **nodes;
159  int totnode;
160  bool multires;
161 
162  mode = RNA_enum_get(op->ptr, "mode");
163  value = RNA_float_get(op->ptr, "value");
164 
165  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
166  pbvh = ob->sculpt->pbvh;
167  multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
168 
169  BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
170 
171  SCULPT_undo_push_begin(ob, "Mask flood fill");
172 
173  MaskTaskData data = {
174  .ob = ob,
175  .pbvh = pbvh,
176  .nodes = nodes,
177  .multires = multires,
178  .mode = mode,
179  .value = value,
180  };
181 
182  TaskParallelSettings settings;
183  BKE_pbvh_parallel_range_settings(&settings, true, totnode);
184  BLI_task_parallel_range(0, totnode, &data, mask_flood_fill_task_cb, &settings);
185 
186  if (multires) {
188  }
189 
191 
193 
194  if (nodes) {
195  MEM_freeN(nodes);
196  }
197 
199 
200  return OPERATOR_FINISHED;
201 }
202 
204 {
205  /* Identifiers. */
206  ot->name = "Mask Flood Fill";
207  ot->idname = "PAINT_OT_mask_flood_fill";
208  ot->description = "Fill the whole mask with a given value, or invert its values";
209 
210  /* API callbacks. */
213 
215 
216  /* RNA. */
219  ot->srna,
220  "value",
221  0.0f,
222  0.0f,
223  1.0f,
224  "Value",
225  "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
226  0.0f,
227  1.0f);
228 }
229 
230 /* Sculpt Gesture Operators. */
231 
237 
238 typedef struct LassoGestureData {
239  float projviewobjmat[4][4];
240 
242  int width;
243 
244  /* 2D bitmap to test if a vertex is affected by the lasso shape. */
247 
248 typedef struct LineGestureData {
249  /* Plane aligned to the gesture line. */
250  float true_plane[4];
251  float plane[4];
252 
253  /* Planes to limit the action to the length of the gesture segment at both sides of the affected
254  * area. */
255  float side_plane[2][4];
256  float true_side_plane[2][4];
258 
259  bool flip;
261 
263 
264 typedef struct SculptGestureContext {
267 
268  /* Enabled and currently active symmetry. */
271 
272  /* Operation parameters. */
275 
277 
278  /* Gesture data. */
279  /* Screen space points that represent the gesture shape. */
282 
283  /* View parameters. */
285  float view_normal[3];
286 
288  float view_origin[3];
289 
290  float true_clip_planes[4][4];
291  float clip_planes[4][4];
292 
293  /* These store the view origin and normal in world space, which is used in some gestures to
294  * generate geometry aligned from the view directly in world space. */
295  /* World space view origin and normal are not affected by object symmetry when doing symmetry
296  * passes, so there is no separate variables with the true_ prefix to store their original values
297  * without symmetry modifications. */
300 
301  /* Lasso Gesture. */
303 
304  /* Line Gesture. */
306 
307  /* Task Callback Data. */
309  int totnode;
311 
312 typedef struct SculptGestureOperation {
313  /* Initial setup (data updates, special undo push...). */
315 
316  /* Apply the gesture action for each symmetry pass. */
318 
319  /* Remaining actions after finishing the symmetry passes iterations
320  * (updating data-layers, tagging PBVH updates...). */
323 
325 {
327  "use_front_faces_only",
328  false,
329  "Front Faces Only",
330  "Affect only faces facing towards the view");
331 
333  "use_limit_to_segment",
334  false,
335  "Limit to Segment",
336  "Apply the gesture action only to the area that is contained within the "
337  "segment without extending its effect to the entire line");
338 }
339 
341  wmOperator *op,
342  SculptGestureContext *sgcontext)
343 {
345  ED_view3d_viewcontext_init(C, &sgcontext->vc, depsgraph);
346  Object *ob = sgcontext->vc.obact;
347 
348  /* Operator properties. */
349  sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
350  sgcontext->line.use_side_planes = RNA_boolean_get(op->ptr, "use_limit_to_segment");
351 
352  /* SculptSession */
353  sgcontext->ss = ob->sculpt;
354 
355  /* Symmetry. */
356  sgcontext->symm = SCULPT_mesh_symmetry_xyz_get(ob);
357 
358  /* View Normal. */
359  float mat[3][3];
360  float view_dir[3] = {0.0f, 0.0f, 1.0f};
361  copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv);
362  mul_m3_v3(mat, view_dir);
363  normalize_v3_v3(sgcontext->world_space_view_normal, view_dir);
364  copy_m3_m4(mat, ob->imat);
365  mul_m3_v3(mat, view_dir);
366  normalize_v3_v3(sgcontext->true_view_normal, view_dir);
367 
368  /* View Origin. */
369  copy_v3_v3(sgcontext->world_space_view_origin, sgcontext->vc.rv3d->viewinv[3]);
370  copy_v3_v3(sgcontext->true_view_origin, sgcontext->vc.rv3d->viewinv[3]);
371 }
372 
373 static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
374 {
375  SculptGestureContext *mcontext = user_data;
376  LassoGestureData *lasso = &mcontext->lasso;
377  int index = (y * lasso->width) + x;
378  int index_end = (y * lasso->width) + x_end;
379  do {
380  BLI_BITMAP_ENABLE(lasso->mask_px, index);
381  } while (++index != index_end);
382 }
383 
385 {
387  "sculpt gesture context lasso");
389 
390  sculpt_gesture_context_init_common(C, op, sgcontext);
391 
392  int mcoords_len;
393  const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
394 
395  if (!mcoords) {
396  return NULL;
397  }
398 
400  sgcontext->vc.rv3d, sgcontext->vc.obact, sgcontext->lasso.projviewobjmat);
401  BLI_lasso_boundbox(&sgcontext->lasso.boundbox, mcoords, mcoords_len);
402  const int lasso_width = 1 + sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin;
403  const int lasso_height = 1 + sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin;
404  sgcontext->lasso.width = lasso_width;
405  sgcontext->lasso.mask_px = BLI_BITMAP_NEW(lasso_width * lasso_height, __func__);
406 
408  sgcontext->lasso.boundbox.ymin,
409  sgcontext->lasso.boundbox.xmax,
410  sgcontext->lasso.boundbox.ymax,
411  mcoords,
412  mcoords_len,
414  sgcontext);
415 
416  BoundBox bb;
418  sgcontext->true_clip_planes,
419  sgcontext->vc.region,
420  sgcontext->vc.obact,
421  &sgcontext->lasso.boundbox);
422 
423  sgcontext->gesture_points = MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points");
424  sgcontext->tot_gesture_points = mcoords_len;
425  for (int i = 0; i < mcoords_len; i++) {
426  sgcontext->gesture_points[i][0] = mcoords[i][0];
427  sgcontext->gesture_points[i][1] = mcoords[i][1];
428  }
429 
430  MEM_freeN((void *)mcoords);
431 
432  return sgcontext;
433 }
434 
436 {
438  "sculpt gesture context box");
440 
441  sculpt_gesture_context_init_common(C, op, sgcontext);
442 
443  rcti rect;
445 
446  BoundBox bb;
448  &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect);
449 
450  sgcontext->gesture_points = MEM_calloc_arrayN(4, sizeof(float[2]), "trim points");
451  sgcontext->tot_gesture_points = 4;
452 
453  sgcontext->gesture_points[0][0] = rect.xmax;
454  sgcontext->gesture_points[0][1] = rect.ymax;
455 
456  sgcontext->gesture_points[1][0] = rect.xmax;
457  sgcontext->gesture_points[1][1] = rect.ymin;
458 
459  sgcontext->gesture_points[2][0] = rect.xmin;
460  sgcontext->gesture_points[2][1] = rect.ymin;
461 
462  sgcontext->gesture_points[3][0] = rect.xmin;
463  sgcontext->gesture_points[3][1] = rect.ymax;
464  return sgcontext;
465 }
466 
467 static void sculpt_gesture_line_plane_from_tri(float *r_plane,
468  SculptGestureContext *sgcontext,
469  const bool flip,
470  const float p1[3],
471  const float p2[3],
472  const float p3[3])
473 {
474  float normal[3];
475  normal_tri_v3(normal, p1, p2, p3);
476  mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal);
477  if (flip) {
478  mul_v3_fl(normal, -1.0f);
479  }
480  float plane_point_object_space[3];
481  mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1);
482  plane_from_point_normal_v3(r_plane, plane_point_object_space, normal);
483 }
484 
485 /* Creates 4 points in the plane defined by the line and 2 extra points with an offset relative to
486  * this plane. */
488  float line_points[2][2],
489  float r_plane_points[4][3],
490  float r_offset_plane_points[2][3])
491 {
492  float depth_point[3];
493  add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal);
495  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[0]);
497  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[3]);
498 
499  madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f);
501  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[1]);
503  sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[2]);
504 
505  float normal[3];
506  normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]);
507  add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal);
508  add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal);
509 }
510 
512 {
514  "sculpt gesture context line");
516 
517  sculpt_gesture_context_init_common(C, op, sgcontext);
518 
519  float line_points[2][2];
520  line_points[0][0] = RNA_int_get(op->ptr, "xstart");
521  line_points[0][1] = RNA_int_get(op->ptr, "ystart");
522  line_points[1][0] = RNA_int_get(op->ptr, "xend");
523  line_points[1][1] = RNA_int_get(op->ptr, "yend");
524 
525  sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip");
526 
527  float plane_points[4][3];
528  float offset_plane_points[2][3];
530  sgcontext, line_points, plane_points, offset_plane_points);
531 
532  /* Calculate line plane and normal. */
533  const bool flip = sgcontext->line.flip ^ (!sgcontext->vc.rv3d->is_persp);
535  sgcontext,
536  flip,
537  plane_points[0],
538  plane_points[1],
539  plane_points[2]);
540 
541  /* Calculate the side planes. */
543  sgcontext,
544  false,
545  plane_points[1],
546  plane_points[0],
547  offset_plane_points[0]);
549  sgcontext,
550  false,
551  plane_points[3],
552  plane_points[2],
553  offset_plane_points[1]);
554 
555  return sgcontext;
556 }
557 
559 {
560  MEM_SAFE_FREE(sgcontext->lasso.mask_px);
561  MEM_SAFE_FREE(sgcontext->gesture_points);
562  MEM_SAFE_FREE(sgcontext->operation);
563  MEM_SAFE_FREE(sgcontext->nodes);
564  MEM_SAFE_FREE(sgcontext);
565 }
566 
567 static void flip_plane(float out[4], const float in[4], const char symm)
568 {
569  if (symm & PAINT_SYMM_X) {
570  out[0] = -in[0];
571  }
572  else {
573  out[0] = in[0];
574  }
575  if (symm & PAINT_SYMM_Y) {
576  out[1] = -in[1];
577  }
578  else {
579  out[1] = in[1];
580  }
581  if (symm & PAINT_SYMM_Z) {
582  out[2] = -in[2];
583  }
584  else {
585  out[2] = in[2];
586  }
587 
588  out[3] = in[3];
589 }
590 
592  const ePaintSymmetryFlags symmpass)
593 {
594  sgcontext->symmpass = symmpass;
595  for (int j = 0; j < 4; j++) {
596  flip_plane(sgcontext->clip_planes[j], sgcontext->true_clip_planes[j], symmpass);
597  }
598 
599  negate_m4(sgcontext->clip_planes);
600 
601  flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass);
602  flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass);
603  flip_plane(sgcontext->line.plane, sgcontext->line.true_plane, symmpass);
604  flip_plane(sgcontext->line.side_plane[0], sgcontext->line.true_side_plane[0], symmpass);
605  flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass);
606 }
607 
609 {
610  SculptSession *ss = sgcontext->ss;
611  float clip_planes[3][4];
612  copy_v4_v4(clip_planes[0], sgcontext->line.plane);
613  copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]);
614  copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]);
615 
616  const int num_planes = sgcontext->line.use_side_planes ? 3 : 1;
617  PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes};
620  &frustum,
621  &sgcontext->nodes,
622  &sgcontext->totnode);
623 }
624 
626 {
627  SculptSession *ss = sgcontext->ss;
628  float clip_planes[4][4];
629  copy_m4_m4(clip_planes, sgcontext->clip_planes);
630  negate_m4(clip_planes);
631  PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4};
634  &frustum,
635  &sgcontext->nodes,
636  &sgcontext->totnode);
637 }
638 
640 {
641  switch (sgcontext->shape_type) {
645  break;
648  break;
649  }
650 }
651 
652 static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3])
653 {
654  float scr_co_f[2];
655  int scr_co_s[2];
656  float co_final[3];
657 
658  flip_v3_v3(co_final, co, sgcontext->symmpass);
659 
660  /* First project point to 2d space. */
662  sgcontext->vc.region, co_final, scr_co_f, sgcontext->lasso.projviewobjmat);
663 
664  scr_co_s[0] = scr_co_f[0];
665  scr_co_s[1] = scr_co_f[1];
666 
667  /* Clip against lasso boundbox. */
668  LassoGestureData *lasso = &sgcontext->lasso;
669  if (!BLI_rcti_isect_pt(&lasso->boundbox, scr_co_s[0], scr_co_s[1])) {
670  return false;
671  }
672 
673  scr_co_s[0] -= lasso->boundbox.xmin;
674  scr_co_s[1] -= lasso->boundbox.ymin;
675 
676  return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]);
677 }
678 
680 {
681  float vertex_normal[3];
682  SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal);
683  float dot = dot_v3v3(sgcontext->view_normal, vertex_normal);
684  const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f);
685 
686  if (!is_effected_front_face) {
687  return false;
688  }
689 
690  switch (sgcontext->shape_type) {
692  return isect_point_planes_v3(sgcontext->clip_planes, 4, vd->co);
694  return sculpt_gesture_is_effected_lasso(sgcontext, vd->co);
696  if (sgcontext->line.use_side_planes) {
697  return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f &&
698  plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f &&
699  plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f;
700  }
701  return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f;
702  }
703  return false;
704 }
705 
707 {
708  SculptGestureOperation *operation = sgcontext->operation;
709  SCULPT_undo_push_begin(CTX_data_active_object(C), "Sculpt Gesture Apply");
710 
711  operation->sculpt_gesture_begin(C, sgcontext);
712 
713  for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) {
714  if (SCULPT_is_symmetry_iteration_valid(symmpass, sgcontext->symm)) {
715  sculpt_gesture_flip_for_symmetry_pass(sgcontext, symmpass);
717 
718  operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext);
719 
720  MEM_SAFE_FREE(sgcontext->nodes);
721  }
722  }
723 
724  operation->sculpt_gesture_end(C, sgcontext);
725 
727 
729 }
730 
731 /* Face Set Gesture Operation. */
732 
735 
738 
740 {
742  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false);
743 
744  /* Face Sets modifications do a single undo push. */
746 }
747 
748 static void face_set_gesture_apply_task_cb(void *__restrict userdata,
749  const int i,
750  const TaskParallelTLS *__restrict UNUSED(tls))
751 {
752  SculptGestureContext *sgcontext = userdata;
754  sgcontext->operation;
755  PBVHNode *node = sgcontext->nodes[i];
756  PBVHVertexIter vd;
757  bool any_updated = false;
758 
760  if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
761  SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id);
762  any_updated = true;
763  }
764  }
766 
767  if (any_updated) {
769  }
770 }
771 
773  SculptGestureContext *sgcontext)
774 {
775  TaskParallelSettings settings;
776  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
778  0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings);
779 }
780 
782 {
784 }
785 
787  wmOperator *UNUSED(op))
788 {
789  struct Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact);
790  sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Face Set Operation");
791 
793  sgcontext->operation;
794 
796  face_set_operation->op.sculpt_gesture_apply_for_symmetry_pass =
798  face_set_operation->op.sculpt_gesture_end = sculpt_gesture_face_set_end;
799 
801 }
802 
803 /* Mask Gesture Operation. */
804 
807 
809  float value;
811 
813 {
815  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, false, true, false);
816 }
817 
818 static void mask_gesture_apply_task_cb(void *__restrict userdata,
819  const int i,
820  const TaskParallelTLS *__restrict UNUSED(tls))
821 {
822  SculptGestureContext *sgcontext = userdata;
823  SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation;
824  Object *ob = sgcontext->vc.obact;
825  PBVHNode *node = sgcontext->nodes[i];
826 
827  const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS;
828 
829  PBVHVertexIter vd;
830  bool any_masked = false;
831  bool redraw = false;
832 
834  if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
835  float prevmask = *vd.mask;
836  if (!any_masked) {
837  any_masked = true;
838 
840 
841  if (is_multires) {
843  }
844  }
845  mask_flood_fill_set_elem(vd.mask, mask_operation->mode, mask_operation->value);
846  if (prevmask != *vd.mask) {
847  redraw = true;
848  }
849  }
850  }
852 
853  if (redraw) {
855  }
856 }
857 
859  SculptGestureContext *sgcontext)
860 {
861  TaskParallelSettings settings;
862  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
863  BLI_task_parallel_range(0, sgcontext->totnode, sgcontext, mask_gesture_apply_task_cb, &settings);
864 }
865 
867 {
869  if (BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS) {
871  }
873 }
874 
876 {
877  sgcontext->operation = MEM_callocN(sizeof(SculptGestureMaskOperation), "Mask Operation");
878 
879  SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation;
880 
885 
886  mask_operation->mode = RNA_enum_get(op->ptr, "mode");
887  mask_operation->value = RNA_float_get(op->ptr, "value");
888 }
889 
891 {
894  ot->srna,
895  "value",
896  1.0f,
897  0.0f,
898  1.0f,
899  "Value",
900  "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
901  0.0f,
902  1.0f);
903 }
904 
905 /* Trim Gesture Operation. */
906 
913 
914 /* Intersect is not exposed in the UI because it does not work correctly with symmetry (it deletes
915  * the symmetrical part of the mesh in the first symmetry pass). */
918  "DIFFERENCE",
919  0,
920  "Difference",
921  "Use a difference boolean operation"},
922  {SCULPT_GESTURE_TRIM_UNION, "UNION", 0, "Union", "Use a union boolean operation"},
924  "JOIN",
925  0,
926  "Join",
927  "Join the new mesh as separate geometry, without performing any boolean operation"},
928  {0, NULL, 0, NULL, NULL},
929 };
930 
937  "VIEW",
938  0,
939  "View",
940  "Use the view to orientate the trimming shape"},
942  "SURFACE",
943  0,
944  "Surface",
945  "Use the surface normal to orientate the trimming shape"},
946  {0, NULL, 0, NULL, NULL},
947 };
948 
951 
954 
955  float depth_front;
956  float depth_back;
957 
959 
963 
965 {
966  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
967  Mesh *trim_mesh = trim_operation->mesh;
968  BKE_mesh_calc_normals(trim_mesh);
969 
970  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(trim_mesh);
971  BMesh *bm;
972  bm = BM_mesh_create(&allocsize,
973  &((struct BMeshCreateParams){
974  .use_toolflags = true,
975  }));
976 
978  trim_mesh,
979  (&(struct BMeshFromMeshParams){
980  .calc_face_normal = true,
981  }));
985  "recalc_face_normals faces=%hf",
986  BM_ELEM_TAG);
989  (&(struct BMeshToMeshParams){
990  .calc_object_remap = false,
991  }),
992  trim_mesh);
993  BM_mesh_free(bm);
994  BKE_id_free(NULL, trim_mesh);
995  trim_operation->mesh = result;
996 }
997 
998 /* Get the origin and normal that are going to be used for calculating the depth and position the
999  * trimming geometry. */
1001  float *r_origin,
1002  float *r_normal)
1003 {
1004  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1005  /* Use the view origin and normal in world space. The trimming mesh coordinates are
1006  * calculated in world space, aligned to the view, and then converted to object space to
1007  * store them in the final trimming mesh which is going to be used in the boolean operation.
1008  */
1009  switch (trim_operation->orientation) {
1011  copy_v3_v3(r_origin, sgcontext->world_space_view_origin);
1012  copy_v3_v3(r_normal, sgcontext->world_space_view_normal);
1013  break;
1015  mul_v3_m4v3(r_origin, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_location);
1016  /* Transforming the normal does not take non uniform scaling into account. Sculpt mode is not
1017  * expected to work on object with non uniform scaling. */
1018  copy_v3_v3(r_normal, sgcontext->ss->gesture_initial_normal);
1019  mul_mat3_m4_v3(sgcontext->vc.obact->obmat, r_normal);
1020  break;
1021  }
1022 }
1023 
1025 {
1026  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1027 
1028  SculptSession *ss = sgcontext->ss;
1029  ViewContext *vc = &sgcontext->vc;
1030 
1031  const int totvert = SCULPT_vertex_count_get(ss);
1032 
1033  float shape_plane[4];
1034  float shape_origin[3];
1035  float shape_normal[3];
1036  sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
1037  plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
1038 
1039  trim_operation->depth_front = FLT_MAX;
1040  trim_operation->depth_back = -FLT_MAX;
1041 
1042  for (int i = 0; i < totvert; i++) {
1043  const float *vco = SCULPT_vertex_co_get(ss, i);
1044  /* Convert the coordinates to world space to calculate the depth. When generating the trimming
1045  * mesh, coordinates are first calculated in world space, then converted to object space to
1046  * store them. */
1047  float world_space_vco[3];
1048  mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco);
1049  const float dist = dist_signed_to_plane_v3(world_space_vco, shape_plane);
1050  trim_operation->depth_front = min_ff(dist, trim_operation->depth_front);
1051  trim_operation->depth_back = max_ff(dist, trim_operation->depth_back);
1052  }
1053 
1054  if (trim_operation->use_cursor_depth) {
1055  float world_space_gesture_initial_location[3];
1056  mul_v3_m4v3(
1057  world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location);
1058 
1059  float mid_point_depth;
1060  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1061  mid_point_depth = ss->gesture_initial_hit ?
1062  dist_signed_to_plane_v3(world_space_gesture_initial_location,
1063  shape_plane) :
1064  (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
1065  }
1066  else {
1067  /* When using normal orientation, if the stroke started over the mesh, position the mid point
1068  * at 0 distance from the shape plane. This positions the trimming shape half inside of the
1069  * surface. */
1070  mid_point_depth = ss->gesture_initial_hit ?
1071  0.0f :
1072  (trim_operation->depth_back + trim_operation->depth_front) * 0.5f;
1073  }
1074 
1075  const float depth_radius = ss->cursor_radius;
1076  trim_operation->depth_front = mid_point_depth - depth_radius;
1077  trim_operation->depth_back = mid_point_depth + depth_radius;
1078  }
1079 }
1080 
1082 {
1083  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1084  ViewContext *vc = &sgcontext->vc;
1085  ARegion *region = vc->region;
1086 
1087  const int tot_screen_points = sgcontext->tot_gesture_points;
1088  float(*screen_points)[2] = sgcontext->gesture_points;
1089 
1090  const int trim_totverts = tot_screen_points * 2;
1091  const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points);
1092  trim_operation->mesh = BKE_mesh_new_nomain(
1093  trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys);
1094  trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, 3 * sizeof(float), "mesh orco");
1095 
1096  float depth_front = trim_operation->depth_front;
1097  float depth_back = trim_operation->depth_back;
1098 
1099  if (!trim_operation->use_cursor_depth) {
1100  /* When using cursor depth, don't modify the depth set by the cursor radius. If full depth is
1101  * used, adding a little padding to the trimming shape can help avoiding booleans with coplanar
1102  * faces. */
1103  depth_front -= 0.1f;
1104  depth_back += 0.1f;
1105  }
1106 
1107  float shape_origin[3];
1108  float shape_normal[3];
1109  float shape_plane[4];
1110  sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal);
1111  plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal);
1112 
1113  const float(*ob_imat)[4] = vc->obact->imat;
1114 
1115  /* Write vertices coordinates for the front face. */
1116  float depth_point[3];
1117  madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front);
1118  for (int i = 0; i < tot_screen_points; i++) {
1119  float new_point[3];
1120  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1121  ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
1122  }
1123  else {
1124  ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
1125  madd_v3_v3fl(new_point, shape_normal, depth_front);
1126  }
1127  mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point);
1128  mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point);
1129  }
1130 
1131  /* Write vertices coordinates for the back face. */
1132  madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back);
1133  for (int i = 0; i < tot_screen_points; i++) {
1134  float new_point[3];
1135  if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) {
1136  ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point);
1137  }
1138  else {
1139  ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
1140  madd_v3_v3fl(new_point, shape_normal, depth_back);
1141  }
1142  mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point);
1143  mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point);
1144  }
1145 
1146  /* Get the triangulation for the front/back poly. */
1147  const int tot_tris_face = tot_screen_points - 2;
1148  uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, 3 * sizeof(uint), "tris");
1149  BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris);
1150 
1151  /* Write the front face triangle indices. */
1152  MPoly *mp = trim_operation->mesh->mpoly;
1153  MLoop *ml = trim_operation->mesh->mloop;
1154  for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
1155  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1156  mp->totloop = 3;
1157  ml[0].v = r_tris[i][0];
1158  ml[1].v = r_tris[i][1];
1159  ml[2].v = r_tris[i][2];
1160  }
1161 
1162  /* Write the back face triangle indices. */
1163  for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
1164  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1165  mp->totloop = 3;
1166  ml[0].v = r_tris[i][0] + tot_screen_points;
1167  ml[1].v = r_tris[i][1] + tot_screen_points;
1168  ml[2].v = r_tris[i][2] + tot_screen_points;
1169  }
1170 
1171  MEM_freeN(r_tris);
1172 
1173  /* Write the indices for the lateral triangles. */
1174  for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
1175  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1176  mp->totloop = 3;
1177  int current_index = i;
1178  int next_index = current_index + 1;
1179  if (next_index >= tot_screen_points) {
1180  next_index = 0;
1181  }
1182  ml[0].v = next_index + tot_screen_points;
1183  ml[1].v = next_index;
1184  ml[2].v = current_index;
1185  }
1186 
1187  for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
1188  mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
1189  mp->totloop = 3;
1190  int current_index = i;
1191  int next_index = current_index + 1;
1192  if (next_index >= tot_screen_points) {
1193  next_index = 0;
1194  }
1195  ml[0].v = current_index;
1196  ml[1].v = current_index + tot_screen_points;
1197  ml[2].v = next_index + tot_screen_points;
1198  }
1199 
1200  BKE_mesh_calc_edges(trim_operation->mesh, false, false);
1202 }
1203 
1205 {
1206  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1207  BKE_id_free(NULL, trim_operation->mesh);
1208  MEM_freeN(trim_operation->true_mesh_co);
1209 }
1210 
1212 {
1213  return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0;
1214 }
1215 
1217 {
1218  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1219  Mesh *sculpt_mesh = BKE_mesh_from_object(sgcontext->vc.obact);
1220  Mesh *trim_mesh = trim_operation->mesh;
1221 
1222  BMesh *bm;
1223  const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh);
1224  bm = BM_mesh_create(&allocsize,
1225  &((struct BMeshCreateParams){
1226  .use_toolflags = false,
1227  }));
1228 
1230  trim_mesh,
1231  &((struct BMeshFromMeshParams){
1232  .calc_face_normal = true,
1233  }));
1234 
1236  sculpt_mesh,
1237  &((struct BMeshFromMeshParams){
1238  .calc_face_normal = true,
1239  }));
1240 
1241  const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
1242  int tottri;
1243  BMLoop *(*looptris)[3];
1244  looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__);
1245  BM_mesh_calc_tessellation_beauty(bm, looptris, &tottri);
1246 
1247  BMIter iter;
1248  int i;
1249  const int i_faces_end = trim_mesh->totpoly;
1250 
1251  /* We need face normals because of 'BM_face_split_edgenet'
1252  * we could calculate on the fly too (before calling split). */
1253 
1254  const short ob_src_totcol = trim_mesh->totcol;
1255  short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1);
1256 
1257  BMFace *efa;
1258  i = 0;
1259  BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1260  normalize_v3(efa->no);
1261 
1262  /* Temp tag to test which side split faces are from. */
1264 
1265  /* Remap material. */
1266  if (efa->mat_nr < ob_src_totcol) {
1267  efa->mat_nr = material_remap[efa->mat_nr];
1268  }
1269 
1270  if (++i == i_faces_end) {
1271  break;
1272  }
1273  }
1274 
1275  /* Join does not do a boolean operation, it just adds the geometry. */
1276  if (trim_operation->mode != SCULPT_GESTURE_TRIM_JOIN) {
1277  int boolean_mode = 0;
1278  switch (trim_operation->mode) {
1280  boolean_mode = eBooleanModifierOp_Intersect;
1281  break;
1283  boolean_mode = eBooleanModifierOp_Difference;
1284  break;
1286  boolean_mode = eBooleanModifierOp_Union;
1287  break;
1289  BLI_assert(false);
1290  break;
1291  }
1293  bm, looptris, tottri, bm_face_isect_pair, NULL, 2, true, true, false, boolean_mode);
1294  }
1295 
1296  MEM_freeN(looptris);
1297 
1299  (&(struct BMeshToMeshParams){
1300  .calc_object_remap = false,
1301  }),
1302  sculpt_mesh);
1303  BM_mesh_free(bm);
1304  result->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
1306  result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true);
1307 }
1308 
1310 {
1314  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false);
1316 }
1317 
1319  SculptGestureContext *sgcontext)
1320 {
1321  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1322  Mesh *trim_mesh = trim_operation->mesh;
1323  for (int i = 0; i < trim_mesh->totvert; i++) {
1324  flip_v3_v3(trim_mesh->mvert[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass);
1325  }
1327  sculpt_gesture_apply_trim(sgcontext);
1328 }
1329 
1331 {
1332  Object *object = sgcontext->vc.obact;
1333  SculptSession *ss = object->sculpt;
1334  ss->face_sets = CustomData_get_layer(&((Mesh *)object->data)->pdata, CD_SCULPT_FACE_SETS);
1335  if (ss->face_sets) {
1336  /* Assign a new Face Set ID to the new faces created by the trim operation. */
1337  const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data);
1338  ED_sculpt_face_sets_initialize_none_to_id(object->data, next_face_set_id);
1339  }
1340 
1342 
1346 }
1347 
1349 {
1350  sgcontext->operation = MEM_callocN(sizeof(SculptGestureTrimOperation), "Trim Operation");
1351 
1352  SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
1353 
1355  trim_operation->op.sculpt_gesture_apply_for_symmetry_pass =
1357  trim_operation->op.sculpt_gesture_end = sculpt_gesture_trim_end;
1358 
1359  trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode");
1360  trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth");
1361  trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation");
1362 
1363  /* If the cursor was not over the mesh, force the orientation to view. */
1364  if (!sgcontext->ss->gesture_initial_hit) {
1366  }
1367 }
1368 
1370 {
1371  RNA_def_enum(ot->srna,
1372  "trim_mode",
1375  "Trim Mode",
1376  NULL);
1378  ot->srna,
1379  "use_cursor_depth",
1380  false,
1381  "Use Cursor for Depth",
1382  "Use cursor location and radius for the dimensions and position of the trimming shape");
1383  RNA_def_enum(ot->srna,
1384  "trim_orientation",
1387  "Shape Orientation",
1388  NULL);
1389 }
1390 
1391 /* Project Gesture Operation. */
1392 
1396 
1398 {
1400  BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, false, false, false);
1401 }
1402 
1403 static void project_line_gesture_apply_task_cb(void *__restrict userdata,
1404  const int i,
1405  const TaskParallelTLS *__restrict UNUSED(tls))
1406 {
1407  SculptGestureContext *sgcontext = userdata;
1408 
1409  PBVHNode *node = sgcontext->nodes[i];
1410  PBVHVertexIter vd;
1411  bool any_updated = false;
1412 
1414 
1416  if (!sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
1417  continue;
1418  }
1419 
1420  float projected_pos[3];
1421  closest_to_plane_v3(projected_pos, sgcontext->line.plane, vd.co);
1422 
1423  float disp[3];
1424  sub_v3_v3v3(disp, projected_pos, vd.co);
1425  const float mask = vd.mask ? *vd.mask : 0.0f;
1426  mul_v3_fl(disp, 1.0f - mask);
1427  if (is_zero_v3(disp)) {
1428  continue;
1429  }
1430  add_v3_v3(vd.co, disp);
1431  if (vd.mvert) {
1433  }
1434  any_updated = true;
1435  }
1437 
1438  if (any_updated) {
1440  }
1441 }
1442 
1444  SculptGestureContext *sgcontext)
1445 {
1446  TaskParallelSettings settings;
1447  BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode);
1448 
1449  switch (sgcontext->shape_type) {
1452  0, sgcontext->totnode, sgcontext, project_line_gesture_apply_task_cb, &settings);
1453  break;
1456  /* Gesture shape projection not implemented yet. */
1457  BLI_assert(false);
1458  break;
1459  }
1460 }
1461 
1463 {
1464  SculptSession *ss = sgcontext->ss;
1466  if (ss->deform_modifiers_active || ss->shapekey_active) {
1467  SCULPT_flush_stroke_deform(sd, sgcontext->vc.obact, true);
1468  }
1469 
1472 }
1473 
1475  wmOperator *UNUSED(op))
1476 {
1477  sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Project Operation");
1478 
1480  sgcontext->operation;
1481 
1486 }
1487 
1489 {
1491  if (!sgcontext) {
1492  return OPERATOR_CANCELLED;
1493  }
1494  sculpt_gesture_init_mask_properties(sgcontext, op);
1495  sculpt_gesture_apply(C, sgcontext);
1496  sculpt_gesture_context_free(sgcontext);
1497  return OPERATOR_FINISHED;
1498 }
1499 
1501 {
1503  if (!sgcontext) {
1504  return OPERATOR_CANCELLED;
1505  }
1506  sculpt_gesture_init_mask_properties(sgcontext, op);
1507  sculpt_gesture_apply(C, sgcontext);
1508  sculpt_gesture_context_free(sgcontext);
1509  return OPERATOR_FINISHED;
1510 }
1511 
1513 {
1515  if (!sgcontext) {
1516  return OPERATOR_CANCELLED;
1517  }
1518  sculpt_gesture_init_mask_properties(sgcontext, op);
1519  sculpt_gesture_apply(C, sgcontext);
1520  sculpt_gesture_context_free(sgcontext);
1521  return OPERATOR_FINISHED;
1522 }
1523 
1525 {
1527  if (!sgcontext) {
1528  return OPERATOR_CANCELLED;
1529  }
1531  sculpt_gesture_apply(C, sgcontext);
1532  sculpt_gesture_context_free(sgcontext);
1533  return OPERATOR_FINISHED;
1534 }
1535 
1537 {
1539  if (!sgcontext) {
1540  return OPERATOR_CANCELLED;
1541  }
1543  sculpt_gesture_apply(C, sgcontext);
1544  sculpt_gesture_context_free(sgcontext);
1545  return OPERATOR_FINISHED;
1546 }
1547 
1549 {
1550  Object *object = CTX_data_active_object(C);
1551  SculptSession *ss = object->sculpt;
1552  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1553  /* Not supported in Multires and Dyntopo. */
1554  return OPERATOR_CANCELLED;
1555  }
1556 
1557  if (ss->totvert == 0) {
1558  /* No geometry to trim or to detect a valid position for the trimming shape. */
1559  return OPERATOR_CANCELLED;
1560  }
1561 
1563  if (!sgcontext) {
1564  return OPERATOR_CANCELLED;
1565  }
1566 
1567  sculpt_gesture_init_trim_properties(sgcontext, op);
1568  sculpt_gesture_apply(C, sgcontext);
1569  sculpt_gesture_context_free(sgcontext);
1570  return OPERATOR_FINISHED;
1571 }
1572 
1574 {
1576  SculptSession *ss = ob->sculpt;
1577 
1579  float mouse[2] = {event->mval[0], event->mval[1]};
1581  ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
1582  if (ss->gesture_initial_hit) {
1585  }
1586 
1587  return WM_gesture_box_invoke(C, op, event);
1588 }
1589 
1591 {
1592  Object *object = CTX_data_active_object(C);
1593  SculptSession *ss = object->sculpt;
1594  if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) {
1595  /* Not supported in Multires and Dyntopo. */
1596  return OPERATOR_CANCELLED;
1597  }
1598 
1599  if (ss->totvert == 0) {
1600  /* No geometry to trim or to detect a valid position for the trimming shape. */
1601  return OPERATOR_CANCELLED;
1602  }
1603 
1605  if (!sgcontext) {
1606  return OPERATOR_CANCELLED;
1607  }
1608  sculpt_gesture_init_trim_properties(sgcontext, op);
1609  sculpt_gesture_apply(C, sgcontext);
1610  sculpt_gesture_context_free(sgcontext);
1611  return OPERATOR_FINISHED;
1612 }
1613 
1615 {
1617  SculptSession *ss = ob->sculpt;
1618 
1620  float mouse[2] = {event->mval[0], event->mval[1]};
1622  ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false);
1623  if (ss->gesture_initial_hit) {
1626  }
1627 
1628  return WM_gesture_lasso_invoke(C, op, event);
1629 }
1630 
1632 {
1634  if (!sgcontext) {
1635  return OPERATOR_CANCELLED;
1636  }
1638  sculpt_gesture_apply(C, sgcontext);
1639  sculpt_gesture_context_free(sgcontext);
1640  return OPERATOR_FINISHED;
1641 }
1642 
1644 {
1645  ot->name = "Mask Lasso Gesture";
1646  ot->idname = "PAINT_OT_mask_lasso_gesture";
1647  ot->description = "Add mask within the lasso as you move the brush";
1648 
1652 
1654 
1655  ot->flag = OPTYPE_REGISTER;
1656 
1657  /* Properties. */
1660 
1662 }
1663 
1665 {
1666  ot->name = "Mask Box Gesture";
1667  ot->idname = "PAINT_OT_mask_box_gesture";
1668  ot->description = "Add mask within the box as you move the brush";
1669 
1673 
1675 
1676  ot->flag = OPTYPE_REGISTER;
1677 
1678  /* Properties. */
1681 
1683 }
1684 
1686 {
1687  ot->name = "Mask Line Gesture";
1688  ot->idname = "PAINT_OT_mask_line_gesture";
1689  ot->description = "Add mask to the right of a line as you move the brush";
1690 
1694 
1696 
1697  ot->flag = OPTYPE_REGISTER;
1698 
1699  /* Properties. */
1702 
1704 }
1705 
1707 {
1708  ot->name = "Face Set Lasso Gesture";
1709  ot->idname = "SCULPT_OT_face_set_lasso_gesture";
1710  ot->description = "Add face set within the lasso as you move the brush";
1711 
1715 
1717 
1718  /* Properties. */
1721 }
1722 
1724 {
1725  ot->name = "Face Set Box Gesture";
1726  ot->idname = "SCULPT_OT_face_set_box_gesture";
1727  ot->description = "Add face set within the box as you move the brush";
1728 
1732 
1734 
1735  ot->flag = OPTYPE_REGISTER;
1736 
1737  /* Properties. */
1740 }
1741 
1743 {
1744  ot->name = "Trim Lasso Gesture";
1745  ot->idname = "SCULPT_OT_trim_lasso_gesture";
1746  ot->description = "Trims the mesh within the lasso as you move the brush";
1747 
1751 
1753 
1754  ot->flag = OPTYPE_REGISTER;
1755 
1756  /* Properties. */
1759 
1761 }
1762 
1764 {
1765  ot->name = "Trim Box Gesture";
1766  ot->idname = "SCULPT_OT_trim_box_gesture";
1767  ot->description = "Trims the mesh within the box as you move the brush";
1768 
1772 
1774 
1775  ot->flag = OPTYPE_REGISTER;
1776 
1777  /* Properties. */
1780 
1782 }
1783 
1785 {
1786  ot->name = "Project Line Gesture";
1787  ot->idname = "SCULPT_OT_project_line_gesture";
1788  ot->description = "Project the geometry onto a plane defined by a line";
1789 
1793 
1795 
1796  ot->flag = OPTYPE_REGISTER;
1797 
1798  /* Properties. */
1801 }
typedef float(TangentPoint)[2]
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
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
void * CustomData_get_layer(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_MESH
Definition: customdata.c:1933
void BKE_id_free(struct Main *bmain, void *idv)
struct Mesh * BKE_mesh_from_object(struct Object *ob)
Definition: mesh.c:1271
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.c:877
void BKE_mesh_calc_normals(struct Mesh *me)
void BKE_mesh_batch_cache_dirty_tag(struct Mesh *me, eMeshBatchDirtyMode mode)
Definition: mesh_runtime.c:251
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, const 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:406
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.
void BKE_pbvh_node_mark_update(PBVHNode *node)
Definition: pbvh.c:1732
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
Definition: BKE_pbvh.h:384
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
Definition: pbvh.c:1748
bool BKE_pbvh_node_frustum_contain_AABB(PBVHNode *node, void *frustum)
Definition: pbvh.c:2630
PBVHType BKE_pbvh_type(const PBVH *pbvh)
Definition: pbvh.c:1661
void BKE_pbvh_node_mark_normals_update(PBVHNode *node)
Definition: pbvh.c:1764
#define BKE_pbvh_vertex_iter_end
Definition: BKE_pbvh.h:457
#define PBVH_ITER_UNIQUE
Definition: BKE_pbvh.h:335
@ PBVH_GRIDS
Definition: BKE_pbvh.h:211
@ PBVH_FACES
Definition: BKE_pbvh.h:210
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
Definition: pbvh.c:3042
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
Definition: pbvh.c:1432
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
Definition: pbvh.c:1738
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
Definition: pbvh.c:843
@ PBVH_UpdateVisibility
Definition: BKE_pbvh.h:72
@ PBVH_UpdateMask
Definition: BKE_pbvh.h:71
@ MULTIRES_COORDS_MODIFIED
Definition: BKE_subsurf.h:92
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:78
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index)
Definition: BLI_bitmap.h:73
#define BLI_BITMAP_NEW(_tot, _alloc_string)
Definition: BLI_bitmap.h:50
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:32
void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin, const int ymin, const int xmax, const int ymax, const int verts[][2], const 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], const unsigned int mcoords_len)
Definition: lasso_2d.c:31
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:243
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
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:468
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:405
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:51
bool isect_point_planes_v3(float(*planes)[4], int totplane, const float p[3])
Definition: math_geom.c:2152
void mul_m3_v3(const float M[3][3], float r[3])
Definition: math_matrix.c:930
void copy_m3_m4(float m1[3][3], const float m2[4][4])
Definition: math_matrix.c:105
void mul_mat3_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:794
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:95
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:742
void negate_m4(float R[4][4])
Definition: math_matrix.c:1015
void mul_v3_mat3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:804
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], const unsigned int coords_tot, const int coords_sign, unsigned int(*r_tris)[3])
Definition: polyfill_2d.c:905
bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y)
unsigned int uint
Definition: BLI_sys_types.h:83
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)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
#define CD_MASK_NORMAL
@ CD_SCULPT_FACE_SETS
@ ME_VERT_PBVH_UPDATE
@ 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, const int new_id)
bool ED_view3d_win_to_3d_on_plane(const struct ARegion *region, const float plane[4], const float mval[2], const bool do_clip, float r_out[3])
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float r_pmat[4][4])
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
void ED_view3d_project_float_v2_m4(const struct ARegion *region, const float co[3], float r_co[2], 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:39
@ OPTYPE_REGISTER
Definition: WM_types.h:153
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:26
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:28
#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.c:307
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
BMesh Make Mesh.
Definition: bmesh_mesh.c:157
#define BMALLOC_TEMPLATE_FROM_ME(...)
Definition: bmesh_mesh.h:163
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
Mesh -> BMesh.
#define BMO_FLAG_DEFAULTS
@ BMO_FLAG_RESPECT_HIDE
bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt,...)
void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot)
OperationNode * node
const Depsgraph * depsgraph
void * user_data
IconTextureDrawCall normal
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
PaintMaskFloodMode
Definition: paint_intern.h:334
@ PAINT_MASK_FLOOD_VALUE_INVERSE
Definition: paint_intern.h:336
@ PAINT_MASK_FLOOD_VALUE
Definition: paint_intern.h:335
@ PAINT_MASK_INVERT
Definition: paint_intern.h:337
void flip_v3_v3(float out[3], const float in[3], const enum ePaintSymmetryFlags symm)
Definition: paint_utils.c:407
static void sculpt_gesture_project_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1397
static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1309
static int sculpt_trim_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1548
static void flip_plane(float out[4], const float in[4], const char symm)
Definition: paint_mask.c:567
static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:858
eSculptTrimOperationType
Definition: paint_mask.c:907
@ SCULPT_GESTURE_TRIM_UNION
Definition: paint_mask.c:910
@ SCULPT_GESTURE_TRIM_DIFFERENCE
Definition: paint_mask.c:909
@ SCULPT_GESTURE_TRIM_INTERSECT
Definition: paint_mask.c:908
@ SCULPT_GESTURE_TRIM_JOIN
Definition: paint_mask.c:911
static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1081
static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float value)
Definition: paint_mask.c:89
void SCULPT_OT_trim_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1763
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:818
static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1330
static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1536
static int project_gesture_line_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1631
static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3])
Definition: paint_mask.c:652
void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1723
static const EnumPropertyItem mode_items[]
Definition: paint_mask.c:75
static SculptGestureContext * sculpt_gesture_init_from_line(bContext *C, wmOperator *op)
Definition: paint_mask.c:511
void SCULPT_OT_project_line_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1784
struct SculptGestureProjectOperation SculptGestureProjectOperation
static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:1369
static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op)
Definition: paint_mask.c:875
static void sculpt_gesture_context_init_common(bContext *C, wmOperator *op, SculptGestureContext *sgcontext)
Definition: paint_mask.c:340
static void sculpt_gesture_context_free(SculptGestureContext *sgcontext)
Definition: paint_mask.c:558
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:467
static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:772
enum eSculptGestureShapeType eMaskGesturesShapeType
static int mask_flood_fill_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:151
struct SculptGestureOperation SculptGestureOperation
static void sculpt_gesture_project_end(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:1462
static void mask_flood_fill_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:118
static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1318
void SCULPT_OT_trim_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1742
static void paint_mask_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:890
void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot)
Definition: paint_mask.c:203
static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd)
Definition: paint_mask.c:679
static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1500
static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext)
Definition: paint_mask.c:608
static EnumPropertyItem prop_trim_orientation_types[]
Definition: paint_mask.c:935
void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1706
static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1488
static int sculpt_trim_gesture_lasso_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1590
static void project_line_gesture_apply_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: paint_mask.c:1403
static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:706
static int face_set_gesture_box_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1524
static void sculpt_gesture_trim_shape_origin_normal_get(SculptGestureContext *sgcontext, float *r_origin, float *r_normal)
Definition: paint_mask.c:1000
static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext, wmOperator *UNUSED(op))
Definition: paint_mask.c:786
struct SculptGestureFaceSetOperation SculptGestureFaceSetOperation
static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:739
static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1216
eSculptTrimOrientationType
Definition: paint_mask.c:931
@ SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE
Definition: paint_mask.c:933
@ SCULPT_GESTURE_TRIM_ORIENTATION_VIEW
Definition: paint_mask.c:932
static void sculpt_gesture_trim_geometry_free(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1204
eSculptGestureShapeType
Definition: paint_mask.c:232
@ SCULPT_GESTURE_SHAPE_LINE
Definition: paint_mask.c:235
@ SCULPT_GESTURE_SHAPE_LASSO
Definition: paint_mask.c:234
@ SCULPT_GESTURE_SHAPE_BOX
Definition: paint_mask.c:233
static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op)
Definition: paint_mask.c:1512
static void sculpt_gesture_mask_begin(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:812
static SculptGestureContext * sculpt_gesture_init_from_box(bContext *C, wmOperator *op)
Definition: paint_mask.c:435
static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext)
Definition: paint_mask.c:964
static EnumPropertyItem prop_trim_operation_types[]
Definition: paint_mask.c:916
static void sculpt_gesture_project_apply_for_symmetry_pass(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:1443
static void sculpt_gesture_face_set_end(bContext *UNUSED(C), SculptGestureContext *sgcontext)
Definition: paint_mask.c:781
struct SculptGestureMaskOperation SculptGestureMaskOperation
void PAINT_OT_mask_line_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1685
static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext)
Definition: paint_mask.c:1024
static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontext, const ePaintSymmetryFlags symmpass)
Definition: paint_mask.c:591
static SculptGestureContext * sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op)
Definition: paint_mask.c:384
struct MaskTaskData MaskTaskData
static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, wmOperator *op)
Definition: paint_mask.c:1348
void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1664
static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: paint_mask.c:1573
static void sculpt_gesture_operator_properties(wmOperatorType *ot)
Definition: paint_mask.c:324
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:748
struct LineGestureData LineGestureData
static void sculpt_gesture_init_project_properties(SculptGestureContext *sgcontext, wmOperator *UNUSED(op))
Definition: paint_mask.c:1474
static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext)
Definition: paint_mask.c:866
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:487
static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
Definition: paint_mask.c:1614
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
Definition: paint_mask.c:1643
static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data))
Definition: paint_mask.c:1211
static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureContext *sgcontext)
Definition: paint_mask.c:625
struct LassoGestureData LassoGestureData
static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext)
Definition: paint_mask.c:639
static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
Definition: paint_mask.c:373
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6308
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
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:3825
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_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
const float * SCULPT_vertex_co_get(SculptSession *ss, int index)
Definition: sculpt.c:134
int SCULPT_vertex_count_get(SculptSession *ss)
Definition: sculpt.c:120
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], bool use_sampled_normal)
Definition: sculpt.c:7452
void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
Definition: sculpt.c:489
bool SCULPT_is_symmetry_iteration_valid(char i, char symm)
Definition: sculpt.c:1042
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
bool SCULPT_mode_poll_view3d(bContext *C)
Definition: sculpt.c:6615
bool SCULPT_mode_poll(bContext *C)
Definition: sculpt.c:6601
char SCULPT_mesh_symmetry_xyz_get(Object *object)
Definition: sculpt.c:323
void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
Definition: sculpt.c:6340
void SCULPT_tag_update_overlays(bContext *C)
Definition: sculpt.c:1066
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
Definition: sculpt_undo.c:1383
@ SCULPT_UPDATE_COORDS
Definition: sculpt_intern.h:58
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_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:280
int totloop
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297
float projviewobjmat[4][4]
Definition: paint_mask.c:239
BLI_bitmap * mask_px
Definition: paint_mask.c:245
float true_plane[4]
Definition: paint_mask.c:250
float side_plane[2][4]
Definition: paint_mask.c:255
bool use_side_planes
Definition: paint_mask.c:257
float true_side_plane[2][4]
Definition: paint_mask.c:256
float plane[4]
Definition: paint_mask.c:251
unsigned int v
float co[3]
PBVH * pbvh
Definition: paint_mask.c:106
PaintMaskFloodMode mode
Definition: paint_mask.c:110
bool front_faces_only
Definition: paint_mask.c:114
float(* clip_planes_final)[4]
Definition: paint_mask.c:112
Object * ob
Definition: paint_mask.c:105
PBVHNode ** nodes
Definition: paint_mask.c:107
float view_normal[3]
Definition: paint_mask.c:115
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:84
struct MVert * mvert
Definition: BKE_pbvh.h:372
float * co
Definition: BKE_pbvh.h:374
float * mask
Definition: BKE_pbvh.h:377
PBVHNode * nodes
Definition: pbvh_intern.h:122
float viewinv[4][4]
eMaskGesturesShapeType shape_type
Definition: paint_mask.c:273
SculptSession * ss
Definition: paint_mask.c:265
float clip_planes[4][4]
Definition: paint_mask.c:291
PBVHNode ** nodes
Definition: paint_mask.c:308
float true_view_normal[3]
Definition: paint_mask.c:284
LineGestureData line
Definition: paint_mask.c:305
float world_space_view_origin[3]
Definition: paint_mask.c:298
float true_view_origin[3]
Definition: paint_mask.c:287
float world_space_view_normal[3]
Definition: paint_mask.c:299
float true_clip_planes[4][4]
Definition: paint_mask.c:290
float(* gesture_points)[2]
Definition: paint_mask.c:280
ePaintSymmetryFlags symmpass
Definition: paint_mask.c:270
LassoGestureData lasso
Definition: paint_mask.c:302
struct SculptGestureOperation * operation
Definition: paint_mask.c:276
ePaintSymmetryFlags symm
Definition: paint_mask.c:269
SculptGestureOperation op
Definition: paint_mask.c:734
PaintMaskFloodMode mode
Definition: paint_mask.c:808
SculptGestureOperation op
Definition: paint_mask.c:806
void(* sculpt_gesture_begin)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:314
void(* sculpt_gesture_apply_for_symmetry_pass)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:317
void(* sculpt_gesture_end)(struct bContext *, SculptGestureContext *)
Definition: paint_mask.c:321
SculptGestureOperation operation
Definition: paint_mask.c:1394
eSculptTrimOperationType mode
Definition: paint_mask.c:960
SculptGestureOperation op
Definition: paint_mask.c:950
eSculptTrimOrientationType orientation
Definition: paint_mask.c:961
int * face_sets
Definition: BKE_paint.h:490
struct KeyBlock * shapekey_active
Definition: BKE_paint.h:468
float gesture_initial_location[3]
Definition: BKE_paint.h:539
float gesture_initial_normal[3]
Definition: BKE_paint.h:540
bool gesture_initial_hit
Definition: BKE_paint.h:541
struct PBVH * pbvh
Definition: BKE_paint.h:504
bool deform_modifiers_active
Definition: BKE_paint.h:509
struct ARegion * region
Definition: ED_view3d.h:80
struct Object * obact
Definition: ED_view3d.h:78
struct View3D * v3d
Definition: ED_view3d.h:81
struct RegionView3D * rv3d
Definition: ED_view3d.h:83
int ymin
Definition: DNA_vec_types.h:80
int ymax
Definition: DNA_vec_types.h:80
int xmin
Definition: DNA_vec_types.h:79
int xmax
Definition: DNA_vec_types.h:79
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
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct PointerRNA * ptr
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
@ WM_CURSOR_EDIT
Definition: wm_cursors.h:38
wmOperatorType * ot
Definition: wm_files.c:3156
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)