Cleanup: sync vertex-paint and sculpt from 2.8
[blender-staging.git] / source / blender / editors / sculpt_paint / paint_mask.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 by Nicholas Bishop
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s):
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  */
28
29 /** \file blender/editors/sculpt_paint/paint_mask.c
30  *  \ingroup edsculpt
31  */
32
33 #include "MEM_guardedalloc.h"
34
35 #include "DNA_meshdata_types.h"
36 #include "DNA_object_types.h"
37
38 #include "BIF_glutil.h"
39
40 #include "BLI_bitmap_draw_2d.h"
41 #include "BLI_math_matrix.h"
42 #include "BLI_math_geom.h"
43 #include "BLI_utildefines.h"
44 #include "BLI_lasso_2d.h"
45 #include "BLI_task.h"
46
47 #include "BKE_pbvh.h"
48 #include "BKE_ccg.h"
49 #include "BKE_context.h"
50 #include "BKE_DerivedMesh.h"
51 #include "BKE_multires.h"
52 #include "BKE_paint.h"
53 #include "BKE_subsurf.h"
54
55 #include "RNA_access.h"
56 #include "RNA_define.h"
57
58 #include "WM_api.h"
59 #include "WM_types.h"
60
61 #include "ED_screen.h"
62 #include "ED_sculpt.h"
63 #include "ED_view3d.h"
64
65 #include "bmesh.h"
66
67 #include "paint_intern.h"
68 #include "sculpt_intern.h" /* for undo push */
69
70 #include <stdlib.h>
71
72 static const EnumPropertyItem mode_items[] = {
73         {PAINT_MASK_FLOOD_VALUE, "VALUE", 0, "Value", "Set mask to the level specified by the 'value' property"},
74         {PAINT_MASK_FLOOD_VALUE_INVERSE, "VALUE_INVERSE", 0, "Value Inverted", "Set mask to the level specified by the inverted 'value' property"},
75         {PAINT_MASK_INVERT, "INVERT", 0, "Invert", "Invert the mask"},
76         {0}};
77
78
79 static void mask_flood_fill_set_elem(float *elem,
80                                      PaintMaskFloodMode mode,
81                                      float value)
82 {
83         switch (mode) {
84                 case PAINT_MASK_FLOOD_VALUE:
85                         (*elem) = value;
86                         break;
87                 case PAINT_MASK_FLOOD_VALUE_INVERSE:
88                         (*elem) = 1.0f - value;
89                         break;
90                 case PAINT_MASK_INVERT:
91                         (*elem) = 1.0f - (*elem);
92                         break;
93         }
94 }
95
96 typedef struct MaskTaskData {
97         Object *ob;
98         PBVH *pbvh;
99         PBVHNode **nodes;
100         bool multires;
101
102         PaintMaskFloodMode mode;
103         float value;
104         float (*clip_planes_final)[4];
105 } MaskTaskData;
106
107 static void mask_flood_fill_task_cb(
108         void *__restrict userdata,
109         const int i,
110         const ParallelRangeTLS *__restrict UNUSED(tls))
111 {
112         MaskTaskData *data = userdata;
113
114         PBVHNode *node = data->nodes[i];
115
116         const PaintMaskFloodMode mode = data->mode;
117         const float value = data->value;
118
119         PBVHVertexIter vi;
120
121         sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
122
123         BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) {
124                 mask_flood_fill_set_elem(vi.mask, mode, value);
125         } BKE_pbvh_vertex_iter_end;
126
127         BKE_pbvh_node_mark_redraw(node);
128         if (data->multires)
129                 BKE_pbvh_node_mark_normals_update(node);
130 }
131
132 static int mask_flood_fill_exec(bContext *C, wmOperator *op)
133 {
134         ARegion *ar = CTX_wm_region(C);
135         struct Scene *scene = CTX_data_scene(C);
136         Object *ob = CTX_data_active_object(C);
137         PaintMaskFloodMode mode;
138         float value;
139         PBVH *pbvh;
140         PBVHNode **nodes;
141         int totnode;
142         bool multires;
143         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
144
145         mode = RNA_enum_get(op->ptr, "mode");
146         value = RNA_float_get(op->ptr, "value");
147
148         BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
149         pbvh = ob->sculpt->pbvh;
150         multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
151
152         BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode);
153
154         sculpt_undo_push_begin("Mask flood fill");
155
156         MaskTaskData data = {
157             .ob = ob, .pbvh = pbvh, .nodes = nodes, .multires = multires,
158             .mode = mode, .value = value,
159         };
160
161         ParallelRangeSettings settings;
162         BLI_parallel_range_settings_defaults(&settings);
163         settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
164         BLI_task_parallel_range(
165                     0, totnode, &data, mask_flood_fill_task_cb,
166                     &settings);
167
168         if (multires)
169                 multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
170
171         sculpt_undo_push_end();
172
173         if (nodes)
174                 MEM_freeN(nodes);
175
176         ED_region_tag_redraw(ar);
177
178         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
179
180         return OPERATOR_FINISHED;
181 }
182
183 void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot)
184 {
185         /* identifiers */
186         ot->name = "Mask Flood Fill";
187         ot->idname = "PAINT_OT_mask_flood_fill";
188         ot->description = "Fill the whole mask with a given value, or invert its values";
189
190         /* api callbacks */
191         ot->exec = mask_flood_fill_exec;
192         ot->poll = sculpt_mode_poll;
193
194         ot->flag = OPTYPE_REGISTER;
195
196         /* rna */
197         RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
198         RNA_def_float(ot->srna, "value", 0, 0, 1, "Value",
199                       "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", 0, 1);
200 }
201
202 /* Box select, operator is VIEW3D_OT_select_border, defined in view3d_select.c */
203
204 static bool is_effected(float planes[4][4], const float co[3])
205 {
206         return isect_point_planes_v3(planes, 4, co);
207 }
208
209 static void flip_plane(float out[4], const float in[4], const char symm)
210 {
211         if (symm & PAINT_SYMM_X)
212                 out[0] = -in[0];
213         else
214                 out[0] = in[0];
215         if (symm & PAINT_SYMM_Y)
216                 out[1] = -in[1];
217         else
218                 out[1] = in[1];
219         if (symm & PAINT_SYMM_Z)
220                 out[2] = -in[2];
221         else
222                 out[2] = in[2];
223
224         out[3] = in[3];
225 }
226
227 static void mask_box_select_task_cb(
228         void *__restrict userdata,
229         const int i,
230         const ParallelRangeTLS *__restrict UNUSED(tls))
231 {
232         MaskTaskData *data = userdata;
233
234         PBVHNode *node = data->nodes[i];
235
236         const PaintMaskFloodMode mode = data->mode;
237         const float value = data->value;
238         float (*clip_planes_final)[4] = data->clip_planes_final;
239
240         PBVHVertexIter vi;
241         bool any_masked = false;
242
243         BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) {
244                 if (is_effected(clip_planes_final, vi.co)) {
245                         if (!any_masked) {
246                                 any_masked = true;
247
248                                 sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
249
250                                 BKE_pbvh_node_mark_redraw(node);
251                                 if (data->multires)
252                                         BKE_pbvh_node_mark_normals_update(node);
253                         }
254                         mask_flood_fill_set_elem(vi.mask, mode, value);
255                 }
256         } BKE_pbvh_vertex_iter_end;
257 }
258
259 int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select, bool UNUSED(extend))
260 {
261         Sculpt *sd = vc->scene->toolsettings->sculpt;
262         BoundBox bb;
263         bglMats mats = {{0}};
264         float clip_planes[4][4];
265         float clip_planes_final[4][4];
266         ARegion *ar = vc->ar;
267         struct Scene *scene = vc->scene;
268         Object *ob = vc->obact;
269         PaintMaskFloodMode mode;
270         float value;
271         bool multires;
272         PBVH *pbvh;
273         PBVHNode **nodes;
274         int totnode, symmpass;
275         int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
276
277         mode = PAINT_MASK_FLOOD_VALUE;
278         value = select ? 1.0 : 0.0;
279
280         /* transform the clip planes in object space */
281         view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, &mats);
282         ED_view3d_clipping_calc(&bb, clip_planes, &mats, rect);
283         negate_m4(clip_planes);
284
285         BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
286         pbvh = ob->sculpt->pbvh;
287         multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
288
289         sculpt_undo_push_begin("Mask box fill");
290
291         for (symmpass = 0; symmpass <= symm; ++symmpass) {
292                 if (symmpass == 0 ||
293                     (symm & symmpass &&
294                      (symm != 5 || symmpass != 3) &&
295                      (symm != 6 || (symmpass != 3 && symmpass != 5))))
296                 {
297                         int j = 0;
298
299                         /* flip the planes symmetrically as needed */
300                         for (; j < 4; j++) {
301                                 flip_plane(clip_planes_final[j], clip_planes[j], symmpass);
302                         }
303
304                         BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
305
306                         MaskTaskData data = {
307                             .ob = ob, .pbvh = pbvh, .nodes = nodes, .multires = multires,
308                             .mode = mode, .value = value, .clip_planes_final = clip_planes_final,
309                         };
310
311                         ParallelRangeSettings settings;
312                         BLI_parallel_range_settings_defaults(&settings);
313                         settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
314                         BLI_task_parallel_range(
315                                     0, totnode, &data, mask_box_select_task_cb,
316                                     &settings);
317
318                         if (nodes)
319                                 MEM_freeN(nodes);
320                 }
321         }
322
323         if (multires)
324                 multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
325
326         sculpt_undo_push_end();
327
328         ED_region_tag_redraw(ar);
329
330         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
331
332         return OPERATOR_FINISHED;
333 }
334
335 typedef struct LassoMaskData {
336         struct ViewContext *vc;
337         float projviewobjmat[4][4];
338         BLI_bitmap *px;
339         int width;
340         rcti rect; /* bounding box for scanfilling */
341         int symmpass;
342
343         MaskTaskData task_data;
344 } LassoMaskData;
345
346
347 /* Lasso select. This could be defined as part of VIEW3D_OT_select_lasso, still the shortcuts conflict,
348  * so we will use a separate operator */
349
350 static bool is_effected_lasso(LassoMaskData *data, float co[3])
351 {
352         float scr_co_f[2];
353         int   scr_co_s[2];
354         float co_final[3];
355
356         flip_v3_v3(co_final, co, data->symmpass);
357         /* first project point to 2d space */
358         ED_view3d_project_float_v2_m4(data->vc->ar, co_final, scr_co_f, data->projviewobjmat);
359
360         scr_co_s[0] = scr_co_f[0];
361         scr_co_s[1] = scr_co_f[1];
362
363         /* clip against screen, because lasso is limited to screen only */
364         if ((scr_co_s[0] < data->rect.xmin) ||
365             (scr_co_s[1] < data->rect.ymin) ||
366             (scr_co_s[0] >= data->rect.xmax) ||
367             (scr_co_s[1] >= data->rect.ymax))
368         {
369                 return false;
370         }
371
372         scr_co_s[0] -= data->rect.xmin;
373         scr_co_s[1] -= data->rect.ymin;
374
375         return BLI_BITMAP_TEST_BOOL(data->px, scr_co_s[1] * data->width + scr_co_s[0]);
376 }
377
378 static void mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
379 {
380         LassoMaskData *data = user_data;
381         int index     = (y * data->width) + x;
382         int index_end = (y * data->width) + x_end;
383         do {
384                 BLI_BITMAP_ENABLE(data->px, index);
385         } while (++index != index_end);
386 }
387
388 static void mask_gesture_lasso_task_cb(
389         void *__restrict userdata,
390         const int i,
391         const ParallelRangeTLS *__restrict UNUSED(tls))
392 {
393         LassoMaskData *lasso_data = userdata;
394         MaskTaskData *data = &lasso_data->task_data;
395
396         PBVHNode *node = data->nodes[i];
397
398         const PaintMaskFloodMode mode = data->mode;
399         const float value = data->value;
400
401         PBVHVertexIter vi;
402         bool any_masked = false;
403
404         BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) {
405                 if (is_effected_lasso(lasso_data, vi.co)) {
406                         if (!any_masked) {
407                                 any_masked = true;
408
409                                 sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
410
411                                 BKE_pbvh_node_mark_redraw(node);
412                                 if (data->multires)
413                                         BKE_pbvh_node_mark_normals_update(node);
414                         }
415
416                         mask_flood_fill_set_elem(vi.mask, mode, value);
417                 }
418         } BKE_pbvh_vertex_iter_end;
419 }
420
421 static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
422 {
423         int mcords_tot;
424         const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
425
426         if (mcords) {
427                 float clip_planes[4][4], clip_planes_final[4][4];
428                 BoundBox bb;
429                 bglMats mats = {{0}};
430                 Object *ob;
431                 ViewContext vc;
432                 LassoMaskData data;
433                 struct Scene *scene = CTX_data_scene(C);
434                 Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
435                 int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
436                 PBVH *pbvh;
437                 PBVHNode **nodes;
438                 int totnode, symmpass;
439                 bool multires;
440                 PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode");
441                 float value = RNA_float_get(op->ptr, "value");
442
443                 /* Calculations of individual vertices are done in 2D screen space to diminish the amount of
444                  * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle
445                  * of lasso */
446                 view3d_set_viewcontext(C, &vc);
447                 view3d_get_transformation(vc.ar, vc.rv3d, vc.obact, &mats);
448
449                 /* lasso data calculations */
450                 data.vc = &vc;
451                 ob = vc.obact;
452                 ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat);
453
454                 BLI_lasso_boundbox(&data.rect, mcords, mcords_tot);
455                 data.width = data.rect.xmax - data.rect.xmin;
456                 data.px = BLI_BITMAP_NEW(data.width * (data.rect.ymax - data.rect.ymin), __func__);
457
458                 BLI_bitmap_draw_2d_poly_v2i_n(
459                        data.rect.xmin, data.rect.ymin, data.rect.xmax, data.rect.ymax,
460                        mcords, mcords_tot,
461                        mask_lasso_px_cb, &data);
462
463                 ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect);
464                 negate_m4(clip_planes);
465
466                 BKE_sculpt_update_mesh_elements(scene, sd, ob, false, true);
467                 pbvh = ob->sculpt->pbvh;
468                 multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
469
470                 sculpt_undo_push_begin("Mask lasso fill");
471
472                 for (symmpass = 0; symmpass <= symm; ++symmpass) {
473                         if ((symmpass == 0) ||
474                             (symm & symmpass &&
475                              (symm != 5 || symmpass != 3) &&
476                              (symm != 6 || (symmpass != 3 && symmpass != 5))))
477                         {
478                                 int j = 0;
479
480                                 /* flip the planes symmetrically as needed */
481                                 for (; j < 4; j++) {
482                                         flip_plane(clip_planes_final[j], clip_planes[j], symmpass);
483                                 }
484
485                                 data.symmpass = symmpass;
486
487                                 /* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */
488                                 BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode);
489
490                                 data.task_data.ob = ob;
491                                 data.task_data.pbvh = pbvh;
492                                 data.task_data.nodes = nodes;
493                                 data.task_data.multires = multires;
494                                 data.task_data.mode = mode;
495                                 data.task_data.value = value;
496
497                                 ParallelRangeSettings settings;
498                                 BLI_parallel_range_settings_defaults(&settings);
499                                 settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && (totnode > SCULPT_THREADED_LIMIT));
500                                 BLI_task_parallel_range(
501                                             0, totnode, &data, mask_gesture_lasso_task_cb,
502                                             &settings);
503
504                                 if (nodes)
505                                         MEM_freeN(nodes);
506                         }
507                 }
508
509                 if (multires)
510                         multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED);
511
512                 sculpt_undo_push_end();
513
514                 ED_region_tag_redraw(vc.ar);
515                 MEM_freeN((void *)mcords);
516                 MEM_freeN(data.px);
517
518                 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
519
520                 return OPERATOR_FINISHED;
521         }
522         return OPERATOR_PASS_THROUGH;
523 }
524
525 void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
526 {
527         ot->name = "Mask Lasso Gesture";
528         ot->idname = "PAINT_OT_mask_lasso_gesture";
529         ot->description = "Add mask within the lasso as you move the brush";
530
531         ot->invoke = WM_gesture_lasso_invoke;
532         ot->modal = WM_gesture_lasso_modal;
533         ot->exec = paint_mask_gesture_lasso_exec;
534
535         ot->poll = sculpt_mode_poll;
536
537         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
538
539         /* properties */
540         WM_operator_properties_gesture_lasso(ot);
541
542         RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
543         RNA_def_float(ot->srna, "value", 1.0, 0, 1.0, "Value",
544                       "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", 0, 1);
545 }