mask data is no longer automatically added when sculpting (except when there is a...
authorCampbell Barton <ideasman42@gmail.com>
Mon, 1 Oct 2012 05:19:57 +0000 (05:19 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 1 Oct 2012 05:19:57 +0000 (05:19 +0000)
source/blender/blenkernel/intern/multires.c
source/blender/blenlib/BLI_pbvh.h
source/blender/editors/include/ED_sculpt.h
source/blender/editors/object/object_bake.c
source/blender/editors/object/object_modifier.c
source/blender/editors/sculpt_paint/paint_hide.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/gpu/intern/gpu_buffers.c
source/blender/modifiers/intern/MOD_multires.c

index 245fa4aa37514e0ae0247fa3a17b17444365857c..591524e5156f9a1b2ed52aa9dc2d43bf66cf33ee 100644 (file)
@@ -895,15 +895,16 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
                CCGKey highGridKey, lowGridKey;
                CCGSubSurf *ss;
                int i, numGrids, highGridSize;
+               int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
 
                /* create subsurf DM from original mesh at high level */
                cddm = CDDM_from_mesh(me, NULL);
                DM_set_only_copy(cddm, CD_MASK_BAREMESH);
-               highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+               highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
                ss = ((CCGDerivedMesh *)highdm)->ss;
 
                /* create multires DM from original mesh at low level */
-               lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE);
+               lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask);
                cddm->release(cddm);
 
                /* copy subsurf grids and replace them with low displaced grids */
@@ -1166,17 +1167,18 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                        CCGKey highGridKey, lowGridKey;
                        CCGSubSurf *ss;
                        int i, j, numGrids, highGridSize, lowGridSize;
+                       int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
 
                        /* create subsurf DM from original mesh at high level */
                        if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+                       highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
                        ss = ((CCGDerivedMesh *)highdm)->ss;
 
                        /* create multires DM from original mesh and displacements */
-                       lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE);
+                       lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask);
                        cddm->release(cddm);
 
                        /* gather grid data */
@@ -1228,12 +1230,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
                }
                else {
                        DerivedMesh *cddm, *subdm;
+                       int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
 
                        if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
                        else cddm = CDDM_from_mesh(me, NULL);
                        DM_set_only_copy(cddm, CD_MASK_BAREMESH);
 
-                       subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+                       subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
                        cddm->release(cddm);
 
                        multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
@@ -2109,7 +2112,7 @@ void multires_load_old(Object *ob, Mesh *me)
         *     reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
         *     which implicitly expects both subsurfs from its first dm and oldGridData parameters to
         *     be of the same "format"! */
-       dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK);
+       dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
 
        multires_load_old_dm(dm, me, mmd->totlvl + 1);
 
index 20d04f7881eac9be153f8a1721d1d5062f63b87e..810b3b563868127618dbac0e84a2bad46a80c440 100644 (file)
@@ -233,7 +233,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
                                if (vi.grid) { \
                                        vi.co = CCG_elem_co(vi.key, vi.grid); \
                                        vi.fno = CCG_elem_no(vi.key, vi.grid); \
-                                       vi.mask = CCG_elem_mask(vi.key, vi.grid); \
+                                       vi.mask = vi.key->has_mask ? CCG_elem_mask(vi.key, vi.grid) : NULL; \
                                        vi.grid = CCG_elem_next(vi.key, vi.grid); \
                                        if (vi.gh) { \
                                                if (BLI_BITMAP_GET(vi.gh, vi.gy * vi.gridsize + vi.gx)) \
index e908868df75f5464a897d2b14bd10439a960f732..0381ecc1fb3a297c97cc5cd45d4d251917afbe23 100644 (file)
@@ -45,8 +45,12 @@ void sculpt_get_redraw_planes(float planes[4][4], struct ARegion *ar,
 void ED_sculpt_force_update(struct bContext *C);
 float *ED_sculpt_get_last_stroke(struct Object *ob);
 int ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]);
-void ED_sculpt_mask_layers_ensure(struct Object *ob,
+int ED_sculpt_mask_layers_ensure(struct Object *ob,
                                   struct MultiresModifierData *mmd);
+enum {
+       ED_SCULPT_MASK_LAYER_CALC_VERT = (1 << 0),
+       ED_SCULPT_MASK_LAYER_CALC_LOOP = (1 << 1)
+};
 
 /* paint_ops.c */
 void ED_operatortypes_paint(void);
index 0ea2f78a415b5df005839ade6696ec2e00c2fe2b..6d124377821cf97fa90e2c709e0fb43b8ebb2184 100644 (file)
@@ -1031,7 +1031,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l
                tmp_mmd.lvl = *lvl;
                tmp_mmd.sculptlvl = *lvl;
                dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob,
-                                                       MULTIRES_USE_LOCAL_MMD);
+                                                       0);
                cddm->release(cddm);
        }
 
@@ -1052,7 +1052,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l
        tmp_mmd.lvl = mmd->totlvl;
        tmp_mmd.sculptlvl = mmd->totlvl;
        dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob,
-                                               MULTIRES_USE_LOCAL_MMD);
+                                               0);
        cddm->release(cddm);
 
        return dm;
index 6fe7ad05a704ada50dcf75fe41fc1b788dc96cc9..d75ef78fc4cdd9645d07abef1ed0e4785b4a2a7e 100644 (file)
@@ -159,8 +159,10 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
                        /* set totlvl from existing MDISPS layer if object already had it */
                        multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
 
-                       /* ensure that grid paint mask layer is created */
-                       ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+                       if (ob->mode & OB_MODE_SCULPT) {
+                               /* ensure that grid paint mask layer is created */
+                               ED_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+                       }
                }
                else if (type == eModifierType_Skin) {
                        /* ensure skin-node customdata exists */
@@ -710,11 +712,6 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
        BLI_remlink(&ob->modifiers, md);
        modifier_free(md);
 
-       if (ob->type == OB_MESH) {
-               /* ensure mesh paint mask layer remains after applying */
-               ED_sculpt_mask_layers_ensure(ob, NULL);
-       }
-
        return 1;
 }
 
index 2970bdfb5a47d1e484df2a0e1e10b4eefe178ca3..bdd73cd6db34bfcdbba3c57f3dc4d697d81fa23a 100644 (file)
@@ -197,7 +197,7 @@ static void partialvis_update_grids(Object *ob,
                        for (x = 0; x < key.grid_size; x++) {
                                CCGElem *elem = CCG_grid_elem(&key, grids[g], x, y);
                                const float *co = CCG_elem_co(&key, elem);
-                               float mask = *CCG_elem_mask(&key, elem);
+                               float mask = key.has_mask ? *CCG_elem_mask(&key, elem) : 0.0f;
 
                                /* skip grid element if not in the effected area */
                                if (is_effected(area, planes, co, mask)) {
index 05b5b90344cbfcf82a08182bd380cf4a7dd4640a..5f17d44a8815b052833c1674abc639cebb7d1da3 100644 (file)
@@ -1225,7 +1225,7 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node,
                if (sculpt_brush_test(&test, vd.co)) {
                        const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
                                                                    ss->cache->view_normal, vd.no, vd.fno,
-                                                                   smooth_mask ? 0 : *vd.mask);
+                                                                   smooth_mask ? 0 : (vd.mask ? *vd.mask : 0.0f));
                        if (smooth_mask) {
                                float val = neighbor_average_mask(ss, vd.vert_indices[vd.i]) - *vd.mask;
                                val *= fade * bstrength;
@@ -1524,7 +1524,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
                                /* offset vertex */
                                float fade = tex_strength(ss, brush, vd.co, test.dist,
                                                          ss->cache->sculpt_normal_symm, vd.no,
-                                                         vd.fno, *vd.mask);
+                                                         vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_v3fl(proxy[vd.i], offset, fade);
 
@@ -1580,7 +1580,7 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
                                /* offset vertex */
                                const float fade = tex_strength(ss, brush, vd.co, test.dist,
                                                                ss->cache->sculpt_normal_symm,
-                                                               vd.no, vd.fno, *vd.mask);
+                                                               vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
                                float val1[3];
                                float val2[3];
 
@@ -1623,7 +1623,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
                        if (sculpt_brush_test(&test, vd.co)) {
                                float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
                                                                      ss->cache->view_normal, vd.no,
-                                                                     vd.fno, *vd.mask);
+                                                                     vd.fno, vd.mask ? *vd.mask : 0.0f);
                                float val[3];
 
                                sub_v3_v3v3(val, test.location, vd.co);
@@ -1677,7 +1677,8 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
                {
                        if (sculpt_brush_test(&test, origco[vd.i])) {
                                const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
-                                                                           ss->cache->sculpt_normal_symm, origno[vd.i], NULL, *vd.mask);
+                                                                           ss->cache->sculpt_normal_symm, origno[vd.i],
+                                                                           NULL, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
 
@@ -1718,7 +1719,7 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
                        if (sculpt_brush_test(&test, vd.co)) {
                                const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
                                                                            ss->cache->sculpt_normal_symm,
-                                                                           vd.no, vd.fno, *vd.mask);
+                                                                           vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_v3fl(proxy[vd.i], cono, fade);
 
@@ -1767,7 +1768,7 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
                        if (sculpt_brush_test(&test, vd.co)) {
                                const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
                                                                            ss->cache->sculpt_normal_symm,
-                                                                           vd.no, vd.fno, *vd.mask);
+                                                                           vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
 
@@ -1815,7 +1816,7 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
                        if (sculpt_brush_test(&test, origco[vd.i])) {
                                const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
                                                                            ss->cache->sculpt_normal_symm,
-                                                                           origno[vd.i], NULL, *vd.mask);
+                                                                           origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_v3fl(proxy[vd.i], cono, fade);
 
@@ -1868,7 +1869,7 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
                        if (sculpt_brush_test(&test, origco[vd.i])) {
                                const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist,
                                                                            ss->cache->sculpt_normal_symm,
-                                                                           origno[vd.i], NULL, *vd.mask);
+                                                                           origno[vd.i], NULL, vd.mask ? *vd.mask : 0.0f);
 
                                mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]);
                                sub_v3_v3(proxy[vd.i], origco[vd.i]);
@@ -1921,7 +1922,7 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
                        if (sculpt_brush_test(&test, origco[vd.i])) {
                                const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
                                                                            ss->cache->sculpt_normal_symm,
-                                                                           vd.no, vd.fno, *vd.mask);
+                                                                           vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
                                float *disp = &layer_disp[vd.i];
                                float val[3];
 
@@ -1974,7 +1975,8 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
                {
                        if (sculpt_brush_test(&test, vd.co)) {
                                const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist,
-                                                                           ss->cache->view_normal, vd.no, vd.fno, *vd.mask);
+                                                                           ss->cache->view_normal,
+                                                                           vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
                                float val[3];
 
                                if (vd.fno) copy_v3_v3(val, vd.fno);
@@ -2315,7 +2317,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
 
                                if (plane_trim(ss->cache, brush, val)) {
                                        const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist),
-                                                                                   an, vd.no, vd.fno, *vd.mask);
+                                                                                   an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                        mul_v3_v3fl(proxy[vd.i], val, fade);
 
@@ -2389,7 +2391,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
                                        if (plane_trim(ss->cache, brush, val)) {
                                                const float fade = bstrength * tex_strength(ss, brush, vd.co,
                                                                                            sqrt(test.dist),
-                                                                                           an, vd.no, vd.fno, *vd.mask);
+                                                                                           an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                                mul_v3_v3fl(proxy[vd.i], val, fade);
 
@@ -2491,7 +2493,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
                                        if (plane_trim(ss->cache, brush, val)) {
                                                const float fade = bstrength * tex_strength(ss, brush, vd.co,
                                                                                            ss->cache->radius * test.dist,
-                                                                                           an, vd.no, vd.fno, *vd.mask);
+                                                                                           an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                                mul_v3_v3fl(proxy[vd.i], val, fade);
 
@@ -2555,7 +2557,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
                                        if (plane_trim(ss->cache, brush, val)) {
                                                const float fade = bstrength * tex_strength(ss, brush, vd.co,
                                                                                            sqrt(test.dist),
-                                                                                           an, vd.no, vd.fno, *vd.mask);
+                                                                                           an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                                mul_v3_v3fl(proxy[vd.i], val, fade);
 
@@ -2619,7 +2621,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
                                        if (plane_trim(ss->cache, brush, val)) {
                                                const float fade = bstrength * tex_strength(ss, brush, vd.co,
                                                                                            sqrt(test.dist),
-                                                                                           an, vd.no, vd.fno, *vd.mask);
+                                                                                           an, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
 
                                                mul_v3_v3fl(proxy[vd.i], val, fade);
 
@@ -3062,7 +3064,11 @@ static void sculpt_update_tex(const Scene *scene, Sculpt *sd, SculptSession *ss)
        }
 }
 
-void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_pmap)
+/**
+ * \param need_mask So the DerivedMesh thats returned has mask data
+ */
+void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
+                                 int need_pmap, int need_mask)
 {
        DerivedMesh *dm;
        SculptSession *ss = ob->sculpt;
@@ -3071,6 +3077,27 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_
 
        ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob);
 
+       if (need_mask) {
+               if (mmd == NULL) {
+                       if (!CustomData_has_layer(&me->vdata, CD_PAINT_MASK)) {
+                               ED_sculpt_mask_layers_ensure(ob, NULL);
+                       }
+               }
+               else {
+                       if (!CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
+#if 1
+                               ED_sculpt_mask_layers_ensure(ob, mmd);
+#else                          /* if we wanted to support adding mask data while multi-res painting, we would need to do this */
+                               if ((ED_sculpt_mask_layers_ensure(ob, mmd) & ED_SCULPT_MASK_LAYER_CALC_LOOP)) {
+                                       /* remake the derived mesh */
+                                       ob->recalc |= OB_RECALC_DATA;
+                                       BKE_object_handle_update(scene, ob);
+                               }
+#endif
+                       }
+               }
+       }
+
        /* BMESH ONLY --- at some point we should move sculpt code to use polygons only - but for now it needs tessfaces */
        BKE_mesh_tessface_ensure(me);
 
@@ -3676,7 +3703,7 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob)
                Brush *brush = paint_brush(&sd->paint);
 
                sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob,
-                                           sculpt_any_smooth_mode(brush, ss->cache, 0));
+                                           sculpt_any_smooth_mode(brush, ss->cache, 0), FALSE);
        }
 }
 
@@ -3782,12 +3809,17 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
        Brush *brush = paint_brush(&sd->paint);
        int mode = RNA_enum_get(op->ptr, "mode");
        int is_smooth = 0;
+       int need_mask = FALSE;
+
+       if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
+               need_mask = TRUE;
+       }
 
        view3d_operator_needs_opengl(C);
        sculpt_brush_init_tex(scene, sd, ss);
 
        is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
-       sculpt_update_mesh_elements(scene, sd, ob, is_smooth);
+       sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
 
        return 1;
 }
@@ -4103,13 +4135,14 @@ static void sculpt_init_session(Scene *scene, Object *ob)
 {
        ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
 
-       sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0);
+       sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0, FALSE);
 }
 
-void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
+int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
 {
        float *paint_mask;
        Mesh *me = ob->data;
+       int ret = 0;
 
        paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK);
 
@@ -4162,13 +4195,18 @@ void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
                                }
                        }
                }
+
+               ret |= ED_SCULPT_MASK_LAYER_CALC_LOOP;
        }
 
        /* create vertex paint mask layer if there isn't one already */
        if (!paint_mask) {
                CustomData_add_layer(&me->vdata, CD_PAINT_MASK,
                                     CD_CALLOC, NULL, me->totvert);
+               ret |= ED_SCULPT_MASK_LAYER_CALC_VERT;
        }
+
+       return ret;
 }
 
 static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
@@ -4218,7 +4256,11 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
                sculpt_init_session(scene, ob);
 
                /* Mask layer is required */
-               ED_sculpt_mask_layers_ensure(ob, mmd);
+               if (mmd) {
+                       /* XXX, we could attempt to support adding mask data mid-sculpt mode (with multi-res)
+                        * but this ends up being quite tricky (and slow) */
+                       ED_sculpt_mask_layers_ensure(ob, mmd);
+               }
 
                BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT);
                
index 5e79616b0b0c62b829b0c0493fe9d163a4cee06c..0852378974e2cef9c1d6418a44d1dfe7106a28c5 100644 (file)
@@ -58,7 +58,8 @@ void sculpt(struct Sculpt *sd);
 int sculpt_mode_poll(struct bContext *C);
 int sculpt_mode_poll_view3d(struct bContext *C);
 int sculpt_poll(struct bContext *C);
-void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, int need_pmap);
+void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
+                                 int need_pmap, int need_mask);
 
 /* Deformed mesh sculpt */
 void free_sculptsession_deformMats(struct SculptSession *ss);
index 25555f2526f7050c5c26f3ea68269380fa59da9a..b204fc75255e63f7a82401ec1e1ab958d68e3867 100644 (file)
@@ -113,7 +113,7 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
                        if (kb) {
                                ob->shapenr = BLI_findindex(&key->block, kb) + 1;
 
-                               sculpt_update_mesh_elements(scene, sd, ob, 0);
+                               sculpt_update_mesh_elements(scene, sd, ob, 0, FALSE);
                                WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
                        }
                        else {
@@ -271,8 +271,21 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
        SculptUndoNode *unode;
        MultiresModifierData *mmd;
        int update = FALSE, rebuild = FALSE;
+       int need_mask = FALSE;
+
+       for (unode = lb->first; unode; unode = unode->next) {
+               if (strcmp(unode->idname, ob->id.name) == 0) {
+                       if (unode->type == SCULPT_UNDO_MASK) {
+                               /* is possible that we can't do the mask undo (below)
+                                * because of the vertex count */
+                               need_mask = TRUE;
+                               break;
+                       }
+               }
+       }
+
+       sculpt_update_mesh_elements(scene, sd, ob, 0, need_mask);
 
-       sculpt_update_mesh_elements(scene, sd, ob, 0);
        /* call _after_ sculpt_update_mesh_elements() which may update 'ob->derivedFinal' */
        dm = mesh_get_derived_final(scene, ob, 0);
 
index c44a181841ef1c6291849e6d7ae791635f77edb0..2aa7bb9cc6bac767e0cee63afa14db0a230a7e72 100644 (file)
@@ -1404,8 +1404,10 @@ void GPU_update_mesh_buffers(GPU_Buffers *buffers, MVert *mvert,
 
                                copy_v3_v3(out->co, v->co);
                                memcpy(out->no, v->no, sizeof(short) * 3);
-                               gpu_color_from_mask_copy(vmask[vert_indices[i]],
-                                                        out->color);
+                               if (vmask) {
+                                       gpu_color_from_mask_copy(vmask[vert_indices[i]],
+                                                                out->color);
+                               }
                        }
 
                        glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
@@ -1507,6 +1509,7 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
        if (buffers->vert_buf) {
                int totvert = key->grid_area * totgrid;
                int smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH;
+               const int has_mask = key->has_mask;
 
                glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
                glBufferDataARB(GL_ARRAY_BUFFER_ARB,
@@ -1527,8 +1530,10 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
                                                        normal_float_to_short_v3(vd->no,
                                                                                 CCG_elem_no(key, elem));
 
-                                                       gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
-                                                                                vd->color);
+                                                       if (has_mask) {
+                                                               gpu_color_from_mask_copy(*CCG_elem_mask(key, elem),
+                                                                                        vd->color);
+                                                       }
                                                }
                                                vd++;
                                        }
@@ -1556,12 +1561,15 @@ void GPU_update_grid_buffers(GPU_Buffers *buffers, CCGElem **grids,
 
                                                        vd = vert_data + (j + 1) * key->grid_size + (k + 1);
                                                        normal_float_to_short_v3(vd->no, fno);
-                                                       gpu_color_from_mask_quad_copy(key,
-                                                                                     elems[0],
-                                                                                     elems[1],
-                                                                                     elems[2],
-                                                                                     elems[3],
-                                                                                     vd->color);
+
+                                                       if (has_mask) {
+                                                               gpu_color_from_mask_quad_copy(key,
+                                                                                             elems[0],
+                                                                                             elems[1],
+                                                                                             elems[2],
+                                                                                             elems[3],
+                                                                                             vd->color);
+                                                       }
                                                }
                                        }
                                }
@@ -1769,8 +1777,11 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
 {
        const MVert *mvert = buffers->mvert;
        int i, j;
+       const int has_mask = (buffers->vmask != NULL);
 
-       gpu_colors_enable(VBO_DISABLED);
+       if (has_mask) {
+               gpu_colors_enable(VBO_DISABLED);
+       }
 
        for (i = 0; i < buffers->totface; ++i) {
                MFace *f = buffers->mface + buffers->face_indices[i];
@@ -1784,13 +1795,15 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
 
                if (smooth) {
                        for (j = 0; j < S; j++) {
-                               gpu_color_from_mask_set(buffers->vmask[fv[j]]);
+                               if (has_mask) {
+                                       gpu_color_from_mask_set(buffers->vmask[fv[j]]);
+                               }
                                glNormal3sv(mvert[fv[j]].no);
                                glVertex3fv(mvert[fv[j]].co);
                        }
                }
                else {
-                       float fmask, fno[3];
+                       float fno[3];
 
                        /* calculate face normal */
                        if (f->v4) {
@@ -1801,15 +1814,19 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
                                normal_tri_v3(fno, mvert[fv[0]].co, mvert[fv[1]].co, mvert[fv[2]].co);
                        glNormal3fv(fno);
 
-                       /* calculate face mask color */
-                       fmask = (buffers->vmask[fv[0]] +
-                                buffers->vmask[fv[1]] +
-                                buffers->vmask[fv[2]]);
-                       if (f->v4)
-                               fmask = (fmask + buffers->vmask[fv[3]]) * 0.25;
-                       else
-                               fmask /= 3.0f;
-                       gpu_color_from_mask_set(fmask);
+                       if (has_mask) {
+                               float fmask;
+
+                               /* calculate face mask color */
+                               fmask = (buffers->vmask[fv[0]] +
+                                        buffers->vmask[fv[1]] +
+                                        buffers->vmask[fv[2]]);
+                               if (f->v4)
+                                       fmask = (fmask + buffers->vmask[fv[3]]) * 0.25;
+                               else
+                                       fmask /= 3.0f;
+                               gpu_color_from_mask_set(fmask);
+                       }
                        
                        for (j = 0; j < S; j++)
                                glVertex3fv(mvert[fv[j]].co);
@@ -1818,15 +1835,20 @@ static void gpu_draw_buffers_legacy_mesh(GPU_Buffers *buffers, int smooth)
                glEnd();
        }
 
-       gpu_colors_disable(VBO_DISABLED);
+       if (has_mask) {
+               gpu_colors_disable(VBO_DISABLED);
+       }
 }
 
 static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
 {
        const CCGKey *key = &buffers->gridkey;
        int i, j, x, y, gridsize = buffers->gridkey.grid_size;
+       const int has_mask = key->has_mask;
 
-       gpu_colors_enable(VBO_DISABLED);
+       if (has_mask) {
+               gpu_colors_enable(VBO_DISABLED);
+       }
 
        for (i = 0; i < buffers->totgrid; ++i) {
                int g = buffers->grid_indices[i];
@@ -1853,7 +1875,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
 
                                        if (smooth) {
                                                for (j = 0; j < 4; j++) {
-                                                       gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]));
+                                                       if (has_mask) {
+                                                               gpu_color_from_mask_set(*CCG_elem_mask(key, e[j]));
+                                                       }
                                                        glNormal3fv(CCG_elem_no(key, e[j]));
                                                        glVertex3fv(CCG_elem_co(key, e[j]));
                                                }
@@ -1866,7 +1890,10 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                                               CCG_elem_co(key, e[2]),
                                                               CCG_elem_co(key, e[3]));
                                                glNormal3fv(fno);
-                                               gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]);
+
+                                               if (has_mask) {
+                                                       gpu_color_from_mask_quad_set(key, e[0], e[1], e[2], e[3]);
+                                               }
 
                                                for (j = 0; j < 4; j++)
                                                        glVertex3fv(CCG_elem_co(key, e[j]));
@@ -1883,10 +1910,14 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                        CCGElem *a = CCG_grid_elem(key, grid, x, y);
                                        CCGElem *b = CCG_grid_elem(key, grid, x, y + 1);
 
-                                       gpu_color_from_mask_set(*CCG_elem_mask(key, a));
+                                       if (has_mask) {
+                                               gpu_color_from_mask_set(*CCG_elem_mask(key, a));
+                                       }
                                        glNormal3fv(CCG_elem_no(key, a));
                                        glVertex3fv(CCG_elem_co(key, a));
-                                       gpu_color_from_mask_set(*CCG_elem_mask(key, b));
+                                       if (has_mask) {
+                                               gpu_color_from_mask_set(*CCG_elem_mask(key, b));
+                                       }
                                        glNormal3fv(CCG_elem_no(key, b));
                                        glVertex3fv(CCG_elem_co(key, b));
                                }
@@ -1912,7 +1943,9 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                                                               CCG_elem_co(key, c));
                                                glNormal3fv(fno);
 
-                                               gpu_color_from_mask_quad_set(key, a, b, c, d);
+                                               if (has_mask) {
+                                                       gpu_color_from_mask_quad_set(key, a, b, c, d);
+                                               }
                                        }
 
                                        glVertex3fv(CCG_elem_co(key, a));
@@ -1923,11 +1956,14 @@ static void gpu_draw_buffers_legacy_grids(GPU_Buffers *buffers, int smooth)
                }
        }
 
-       gpu_colors_disable(VBO_DISABLED);
+       if (has_mask) {
+               gpu_colors_disable(VBO_DISABLED);
+       }
 }
 
 void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
 {
+       const int has_mask = (buffers->vmask || buffers->gridkey.has_mask);
        int smooth = 0;
 
        if (buffers->totface) {
@@ -1950,7 +1986,13 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
        if (buffers->vert_buf && buffers->index_buf) {
                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_NORMAL_ARRAY);
-               gpu_colors_enable(VBO_ENABLED);
+               if (buffers->vmask || buffers->gridkey.has_mask) {
+                       gpu_colors_enable(VBO_ENABLED);
+               }
+               else {
+                       gpu_colors_enable(VBO_DISABLED);
+                       glColor4ub(0xff, 0xff, 0xff, 0xff);
+               }
 
                glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffers->vert_buf);
                glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffers->index_buf);
@@ -1963,8 +2005,10 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
                                                offset + offsetof(VertexBufferFormat, co));
                                glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
                                                offset + offsetof(VertexBufferFormat, no));
-                               glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
-                                              offset + offsetof(VertexBufferFormat, color));
+                               if (has_mask) {
+                                       glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
+                                                      offset + offsetof(VertexBufferFormat, color));
+                               }
                                
                                glDrawElements(GL_QUADS, buffers->tot_quad * 4, buffers->index_type, 0);
 
@@ -1976,8 +2020,10 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
                                        (void *)offsetof(VertexBufferFormat, co));
                        glNormalPointer(GL_SHORT, sizeof(VertexBufferFormat),
                                        (void *)offsetof(VertexBufferFormat, no));
-                       glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
-                                      (void *)offsetof(VertexBufferFormat, color));
+                       if (has_mask) {
+                               glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VertexBufferFormat),
+                                              (void *)offsetof(VertexBufferFormat, color));
+                       }
 
                        glDrawElements(GL_TRIANGLES, buffers->tot_tri * 3, buffers->index_type, 0);
                }
@@ -1987,7 +2033,9 @@ void GPU_draw_buffers(GPU_Buffers *buffers, DMSetMaterial setMaterial)
 
                glDisableClientState(GL_VERTEX_ARRAY);
                glDisableClientState(GL_NORMAL_ARRAY);
-               gpu_colors_disable(VBO_ENABLED);
+               if (has_mask) {
+                       gpu_colors_disable(VBO_ENABLED);
+               }
        }
        /* fallbacks if we are out of memory or VBO is disabled */
        else if (buffers->totface) {
index afc85a8144e556673615bbac088df29b12ca9b0f..4292246d8ccbf825a93570e5e8689387791a950a 100644 (file)
@@ -80,6 +80,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
        Mesh *me = (Mesh *)ob->data;
        const int useRenderParams = flag & MOD_APPLY_RENDER;
        MultiresFlags flags = 0;
+       int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
 
        if (mmd->totlvl) {
                if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
@@ -88,7 +89,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm,
                }
        }
 
-       flags = MULTIRES_ALLOC_PAINT_MASK;
+       if (has_mask)
+               flags |= MULTIRES_ALLOC_PAINT_MASK;
+
        if (useRenderParams)
                flags |= MULTIRES_USE_RENDER_PARAMS;