Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / paint.c
index dba2bc7287e89a8732350ac9778c670de4afe371..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"
@@ -53,7 +54,6 @@
 #include "BKE_main.h"
 #include "BKE_context.h"
 #include "BKE_crazyspace.h"
-#include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_image.h"
 #include "BKE_key.h"
@@ -65,6 +65,8 @@
 #include "BKE_pbvh.h"
 #include "BKE_subsurf.h"
 
+#include "DEG_depsgraph.h"
+
 #include "bmesh.h"
 
 const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100};
@@ -74,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, 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);
-       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, 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);
-       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)
@@ -156,13 +198,13 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, ePaintMode mode)
        return NULL;
 }
 
-Paint *BKE_paint_get_active(Scene *sce)
+Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer, const eObjectMode object_mode)
 {
-       if (sce) {
+       if (sce && view_layer) {
                ToolSettings *ts = sce->toolsettings;
                
-               if (sce->basact && sce->basact->object) {
-                       switch (sce->basact->object->mode) {
+               if (view_layer->basact && view_layer->basact->object) {
+                       switch (object_mode) {
                                case OB_MODE_SCULPT:
                                        return &ts->sculpt->paint;
                                case OB_MODE_VERTEX_PAINT:
@@ -175,6 +217,8 @@ Paint *BKE_paint_get_active(Scene *sce)
                                        if (ts->use_uv_sculpt)
                                                return &ts->uvsculpt->paint;
                                        return &ts->imapaint.paint;
+                               default:
+                                       break;
                        }
                }
 
@@ -188,17 +232,19 @@ Paint *BKE_paint_get_active(Scene *sce)
 Paint *BKE_paint_get_active_from_context(const bContext *C)
 {
        Scene *sce = CTX_data_scene(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
        SpaceImage *sima;
 
-       if (sce) {
+       if (sce && view_layer) {
+               const WorkSpace *workspace = CTX_wm_workspace(C);
                ToolSettings *ts = sce->toolsettings;
                Object *obact = NULL;
 
-               if (sce->basact && sce->basact->object)
-                       obact = sce->basact->object;
+               if (view_layer->basact && view_layer->basact->object)
+                       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)
@@ -209,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:
@@ -238,17 +284,19 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
 ePaintMode BKE_paintmode_get_active_from_context(const bContext *C)
 {
        Scene *sce = CTX_data_scene(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
        SpaceImage *sima;
 
-       if (sce) {
+       if (sce && view_layer) {
+               const WorkSpace *workspace = CTX_wm_workspace(C);
                ToolSettings *ts = sce->toolsettings;
                Object *obact = NULL;
 
-               if (sce->basact && sce->basact->object)
-                       obact = sce->basact->object;
+               if (view_layer->basact && view_layer->basact->object)
+                       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)
@@ -259,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:
@@ -450,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)
                 );
 }
 
@@ -475,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)
@@ -496,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:
@@ -526,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) {
@@ -733,7 +781,7 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder)
                sculptsession_bm_to_me_update_data_only(ob, reorder);
 
                /* ensure the objects DerivedMesh mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */
-               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
        }
 }
 
@@ -743,7 +791,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
                if (object->sculpt->bm) {
                        /* Ensure no points to old arrays are stored in DM
                         *
-                        * Apparently, we could not use DAG_id_tag_update
+                        * Apparently, we could not use DEG_id_tag_update
                         * here because this will lead to the while object
                         * surface to disappear, so we'll release DM in place.
                         */
@@ -781,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);
@@ -874,8 +922,9 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
 /**
  * \param need_mask So the DerivedMesh thats returned has mask data
  */
-void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
-                                     bool need_pmap, bool need_mask)
+void BKE_sculpt_update_mesh_elements(
+        const EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob,
+        bool need_pmap, bool need_mask)
 {
        DerivedMesh *dm;
        SculptSession *ss = ob->sculpt;
@@ -914,10 +963,10 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
 
        ss->kb = (mmd == NULL) ? BKE_keyblock_from_object(ob) : NULL;
 
-       dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+       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);
@@ -935,7 +984,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
                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);
@@ -949,7 +998,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
 
                        ss->orig_cos = (ss->kb) ? BKE_keyblock_convert_to_vertcos(ob, ss->kb) : BKE_mesh_vertexCos_get(me, NULL);
 
-                       BKE_crazyspace_build_sculpt(scene, ob, &ss->deform_imats, &ss->deform_cos);
+                       BKE_crazyspace_build_sculpt(eval_ctx, scene, ob, &ss->deform_imats, &ss->deform_cos);
                        BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos);
 
                        for (a = 0; a < me->totvert; ++a) {
@@ -985,6 +1034,9 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
                        }
                }
        }
+
+       /* 2.8x - avoid full mesh update! */
+       BKE_mesh_batch_cache_dirty(me, BKE_MESH_BATCH_DIRTY_SCULPT_COORDS);
 }
 
 int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)