Ensure mask layers are always present in sculpt mode.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user