Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / paint.c
index 47df20906c7b83cbc51a39fd8a157dbeb113975a..81943d470dc3d1a956da7255608174dd95df342a 100644 (file)
@@ -41,6 +41,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_brush_types.h"
 #include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
 
 #include "BLI_bitmap.h"
 #include "BLI_utildefines.h"
@@ -75,27 +76,67 @@ const char PAINT_CURSOR_TEXTURE_PAINT[3] = {255, 255, 255};
 
 static eOverlayControlFlags overlay_flags = 0;
 
-void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex)
+/* Keep in sync with 'BKE_paint_get_active' */
+#define OB_MODE_HAS_PAINT_STRUCT(SEP) \
+       OB_MODE_SCULPT SEP \
+       OB_MODE_VERTEX_PAINT SEP \
+       OB_MODE_WEIGHT_PAINT SEP \
+       OB_MODE_TEXTURE_PAINT SEP \
+       OB_MODE_EDIT
+
+#define COMMA ,
+static const eObjectMode ob_mode_has_paint_struct = OB_MODE_HAS_PAINT_STRUCT(|);
+static const eObjectMode ob_mode_has_paint_struct_array[] = {OB_MODE_HAS_PAINT_STRUCT(COMMA)};
+#undef COMMA
+
+#define FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p) \
+{ \
+       eObjectMode object_mode_test = object_mode & ob_mode_has_paint_struct; \
+       for (uint _i = 0; _i < ARRAY_SIZE(ob_mode_has_paint_struct_array) && object_mode_test; _i++) { \
+               eObjectMode object_mode_single = ob_mode_has_paint_struct_array[_i]; \
+               if (object_mode_test & object_mode_single) { \
+                       object_mode_test &= ~object_mode_single; \
+                       Paint *p = BKE_paint_get_active(scene, view_layer, object_mode_single); \
+                       {
+
+#define FOREACH_OB_MODE_PAINT_ITER_END \
+                       } \
+               } \
+       } \
+} ((void)0)
+
+void BKE_paint_invalidate_overlay_tex(
+        Scene *scene, ViewLayer *view_layer, const Tex *tex, eObjectMode object_mode)
 {
-       Paint *p = BKE_paint_get_active(scene, view_layer);
-       Brush *br = p->brush;
-
-       if (!br)
-               return;
-
-       if (br->mtex.tex == tex)
-               overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY;
-       if (br->mask_mtex.tex == tex)
-               overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY;
+       FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p)
+       {
+               Brush *br = p->brush;
+               if (br) {
+                       if (br->mtex.tex == tex) {
+                               overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY;
+                       }
+                       if (br->mask_mtex.tex == tex) {
+                               overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY;
+                       }
+               }
+       }
+       FOREACH_OB_MODE_PAINT_ITER_END;
 }
 
-void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve)
+void BKE_paint_invalidate_cursor_overlay(
+        Scene *scene, ViewLayer *view_layer, CurveMapping *curve, eObjectMode object_mode)
 {
-       Paint *p = BKE_paint_get_active(scene, view_layer);
-       Brush *br = p->brush;
-
-       if (br && br->curve == curve)
-               overlay_flags |= PAINT_INVALID_OVERLAY_CURVE;
+       FOREACH_OB_MODE_PAINT_ITER_BEGIN(scene, view_layer, object_mode, p)
+       {
+               Brush *br = p->brush;
+               if (br) {
+                       if (br->curve == curve) {
+                               overlay_flags |= PAINT_INVALID_OVERLAY_CURVE;
+                               break;
+                       }
+               }
+       }
+       FOREACH_OB_MODE_PAINT_ITER_END;
 }
 
 void BKE_paint_invalidate_overlay_all(void)
@@ -157,13 +198,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
        return NULL;
 }
 
-Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
+Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer, const eObjectMode object_mode)
 {
        if (sce && view_layer) {
                ToolSettings *ts = sce->toolsettings;
                
                if (view_layer->basact && view_layer->basact->object) {
-                       switch (view_layer->basact->object->mode) {
+                       switch (object_mode) {
                                case OB_MODE_SCULPT:
                                        return &ts->sculpt->paint;
                                case OB_MODE_VERTEX_PAINT:
@@ -176,6 +217,8 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
                                        if (ts->use_uv_sculpt)
                                                return &ts->uvsculpt->paint;
                                        return &ts->imapaint.paint;
+                               default:
+                                       break;
                        }
                }
 
@@ -193,6 +236,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
        SpaceImage *sima;
 
        if (sce && view_layer) {
+               const WorkSpace *workspace = CTX_wm_workspace(C);
                ToolSettings *ts = sce->toolsettings;
                Object *obact = NULL;
 
@@ -200,7 +244,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
                        obact = view_layer->basact->object;
 
                if ((sima = CTX_wm_space_image(C)) != NULL) {
-                       if (obact && obact->mode == OB_MODE_EDIT) {
+                       if (obact && workspace->object_mode == OB_MODE_EDIT) {
                                if (sima->mode == SI_MODE_PAINT)
                                        return &ts->imapaint.paint;
                                else if (ts->use_uv_sculpt)
@@ -211,7 +255,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
                        }
                }
                else if (obact) {
-                       switch (obact->mode) {
+                       switch (workspace->object_mode) {
                                case OB_MODE_SCULPT:
                                        return &ts->sculpt->paint;
                                case OB_MODE_VERTEX_PAINT:
@@ -244,6 +288,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
        SpaceImage *sima;
 
        if (sce && view_layer) {
+               const WorkSpace *workspace = CTX_wm_workspace(C);
                ToolSettings *ts = sce->toolsettings;
                Object *obact = NULL;
 
@@ -251,7 +296,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
                        obact = view_layer->basact->object;
 
                if ((sima = CTX_wm_space_image(C)) != NULL) {
-                       if (obact && obact->mode == OB_MODE_EDIT) {
+                       if (obact && workspace->object_mode == OB_MODE_EDIT) {
                                if (sima->mode == SI_MODE_PAINT)
                                        return ePaintTexture2D;
                                else if (ts->use_uv_sculpt)
@@ -262,7 +307,7 @@ ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
                        }
                }
                else if (obact) {
-                       switch (obact->mode) {
+                       switch (workspace->object_mode) {
                                case OB_MODE_SCULPT:
                                        return ePaintSculpt;
                                case OB_MODE_VERTEX_PAINT:
@@ -453,24 +498,24 @@ bool BKE_palette_is_empty(const struct Palette *palette)
 
 
 /* are we in vertex paint or weight pain face select mode? */
-bool BKE_paint_select_face_test(Object *ob)
+bool BKE_paint_select_face_test(Object *ob, eObjectMode object_mode)
 {
        return ( (ob != NULL) &&
                 (ob->type == OB_MESH) &&
                 (ob->data != NULL) &&
                 (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) &&
-                (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
+                (object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))
                 );
 }
 
 /* are we in weight paint vertex select mode? */
-bool BKE_paint_select_vert_test(Object *ob)
+bool BKE_paint_select_vert_test(Object *ob, eObjectMode object_mode)
 {
        return ( (ob != NULL) &&
                 (ob->type == OB_MESH) &&
                 (ob->data != NULL) &&
                 (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) &&
-                (ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT)
+                (object_mode & OB_MODE_WEIGHT_PAINT || object_mode & OB_MODE_VERTEX_PAINT)
                 );
 }
 
@@ -478,10 +523,10 @@ bool BKE_paint_select_vert_test(Object *ob)
  * used to check if selection is possible
  * (when we don't care if its face or vert)
  */
-bool BKE_paint_select_elem_test(Object *ob)
+bool BKE_paint_select_elem_test(Object *ob, eObjectMode object_mode)
 {
-       return (BKE_paint_select_vert_test(ob) ||
-               BKE_paint_select_face_test(ob));
+       return (BKE_paint_select_vert_test(ob, object_mode) ||
+               BKE_paint_select_face_test(ob, object_mode));
 }
 
 void BKE_paint_cavity_curve_preset(Paint *p, int preset)
@@ -499,7 +544,7 @@ void BKE_paint_cavity_curve_preset(Paint *p, int preset)
        curvemapping_changed(p->cavity_curve, false);
 }
 
-short BKE_paint_object_mode_from_paint_mode(ePaintMode mode)
+eObjectMode BKE_paint_object_mode_from_paint_mode(ePaintMode mode)
 {
        switch (mode) {
                case ePaintSculpt:
@@ -529,7 +574,7 @@ void BKE_paint_init(Scene *sce, ePaintMode mode, const char col[3])
        /* If there's no brush, create one */
        brush = BKE_paint_brush(paint);
        if (brush == NULL) {
-               short ob_mode = BKE_paint_object_mode_from_paint_mode(mode);
+               eObjectMode ob_mode = BKE_paint_object_mode_from_paint_mode(mode);
                brush = BKE_brush_first_search(G.main, ob_mode);
 
                if (!brush) {
@@ -784,7 +829,7 @@ void BKE_sculptsession_free(Object *ob)
                        BM_log_free(ss->bm_log);
 
                if (dm && dm->getPBVH)
-                       dm->getPBVH(NULL, dm);  /* signal to clear */
+                       dm->getPBVH(NULL, dm, OB_MODE_OBJECT);  /* signal to clear */
 
                if (ss->texcache)
                        MEM_freeN(ss->texcache);
@@ -888,6 +933,7 @@ void BKE_sculpt_update_mesh_elements(
 
        ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
        ss->show_diffuse_color = (sd->flags & SCULPT_SHOW_DIFFUSE) != 0;
+       ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0;
 
        ss->building_vp_handle = false;
 
@@ -920,7 +966,7 @@ void BKE_sculpt_update_mesh_elements(
        dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
 
        /* VWPaint require mesh info for loop lookup, so require sculpt mode here */
-       if (mmd && ob->mode & OB_MODE_SCULPT) {
+       if (mmd && eval_ctx->object_mode & OB_MODE_SCULPT) {
                ss->multires = mmd;
                ss->totvert = dm->getNumVerts(dm);
                ss->totpoly = dm->getNumPolys(dm);
@@ -938,10 +984,11 @@ void BKE_sculpt_update_mesh_elements(
                ss->vmask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
        }
 
-       ss->pbvh = dm->getPBVH(ob, dm);
+       ss->pbvh = dm->getPBVH(ob, dm, eval_ctx->object_mode);
        ss->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL;
 
        pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color);
+       pbvh_show_mask_set(ss->pbvh, ss->show_mask);
 
        if (ss->modifiers_active) {
                if (!ss->orig_cos) {
@@ -1062,3 +1109,39 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
 
        return ret;
 }
+
+void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
+{
+       Sculpt *sd = scene->toolsettings->sculpt;
+       if (sd == NULL) {
+               sd = scene->toolsettings->sculpt = MEM_callocN(sizeof(Sculpt), __func__);
+
+               /* Turn on X plane mirror symmetry by default */
+               sd->paint.symmetry_flags |= PAINT_SYMM_X;
+               sd->paint.flags |= PAINT_SHOW_BRUSH;
+
+               /* Make sure at least dyntopo subdivision is enabled */
+               sd->flags |= SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE;
+       }
+
+       if (!sd->detail_size) {
+               sd->detail_size = 12;
+       }
+       if (!sd->detail_percent) {
+               sd->detail_percent = 25;
+       }
+       if (sd->constant_detail == 0.0f) {
+               sd->constant_detail = 3.0f;
+       }
+
+       /* Set sane default tiling offsets */
+       if (!sd->paint.tile_offset[0]) {
+               sd->paint.tile_offset[0] = 1.0f;
+       }
+       if (!sd->paint.tile_offset[1]) {
+               sd->paint.tile_offset[1] = 1.0f;
+       }
+       if (!sd->paint.tile_offset[2]) {
+               sd->paint.tile_offset[2] = 1.0f;
+       }
+}