diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2012-05-11 00:34:35 +0400 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2012-05-11 00:34:35 +0400 |
commit | c9c0bfeeb8569c4c8e3d39186a2922de1f7fdc5b (patch) | |
tree | 7df6775b6d01a28530c72ec5c1b767537825f106 | |
parent | 0f57b0f1e514c8f13f2fcfeb71c6291640f88794 (diff) |
Ensure mask layers are always present in sculpt mode.
-rw-r--r-- | source/blender/editors/include/ED_sculpt.h | 3 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 10 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 68 |
3 files changed, 80 insertions, 1 deletions
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index 2df699255be..d35fc8f4636 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -32,6 +32,7 @@ struct ARegion; struct bContext; +struct MultiresModifierData; struct Object; struct RegionView3D; struct wmKeyConfig; @@ -44,6 +45,8 @@ 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, float *max); +void ED_sculpt_mask_layers_ensure(struct Object *ob, + struct MultiresModifierData *mmd); /* paint_ops.c */ void ED_operatortypes_paint(void); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 4dd3688e877..7e9201a708d 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -76,6 +76,7 @@ #include "ED_armature.h" #include "ED_object.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "ED_mesh.h" #include "WM_api.h" @@ -147,9 +148,13 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc } else if (type == eModifierType_Surface) DAG_scene_sort(bmain, scene); - else if (type == eModifierType_Multires) + else if (type == eModifierType_Multires) { /* 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); + } } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -610,6 +615,9 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi BLI_remlink(&ob->modifiers, md); modifier_free(md); + /* ensure mesh paint mask layer remains after applying */ + ED_sculpt_mask_layers_ensure(ob, NULL); + return 1; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 77f9a444153..656ac0c1117 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3703,6 +3703,71 @@ static void sculpt_init_session(Scene *scene, Object *ob) sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0); } +void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) +{ + float *paint_mask; + Mesh *me = ob->data; + + paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); + + /* if multires is active, create a grid paint mask layer if there + isn't one already */ + if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) { + GridPaintMask *gmask; + int level = MAX2(1, mmd->sculptlvl); + int gridsize = ccg_gridsize(level); + int gridarea = gridsize * gridsize; + int i, j; + + gmask = CustomData_add_layer(&me->ldata, CD_GRID_PAINT_MASK, + CD_CALLOC, NULL, me->totloop); + + for (i = 0; i < me->totloop; i++) { + GridPaintMask *gpm = &gmask[i]; + + gpm->level = level; + gpm->data = MEM_callocN(sizeof(float) * gridarea, + "GridPaintMask.data"); + } + + /* if vertices already have mask, copy into multires data */ + if (paint_mask) { + for (i = 0; i < me->totpoly; i++) { + const MPoly *p = &me->mpoly[i]; + float avg = 0; + + /* mask center */ + for (j = 0; j < p->totloop; j++) { + const MLoop *l = &me->mloop[p->loopstart + j]; + avg += paint_mask[l->v]; + } + avg /= (float)p->totloop; + + /* fill in multires mask corner */ + for (j = 0; j < p->totloop; j++) { + GridPaintMask *gpm = &gmask[p->loopstart + j]; + const MLoop *l = &me->mloop[p->loopstart + j]; + const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j); + const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j); + + gpm->data[0] = avg; + gpm->data[1] = (paint_mask[l->v] + + paint_mask[next->v]) * 0.5f; + gpm->data[2] = (paint_mask[l->v] + + paint_mask[prev->v]) * 0.5f; + gpm->data[3] = paint_mask[l->v]; + } + } + } + } + + /* 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); + } +} + static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -3749,6 +3814,9 @@ 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); + paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); paint_cursor_start(C, sculpt_poll); |