diff options
-rw-r--r-- | source/blender/blenkernel/intern/multires.c | 15 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_pbvh.h | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_sculpt.h | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 11 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_hide.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 86 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_undo.c | 17 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 120 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 5 |
11 files changed, 191 insertions, 80 deletions
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 245fa4aa375..591524e5156 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -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); diff --git a/source/blender/blenlib/BLI_pbvh.h b/source/blender/blenlib/BLI_pbvh.h index 20d04f7881e..810b3b56386 100644 --- a/source/blender/blenlib/BLI_pbvh.h +++ b/source/blender/blenlib/BLI_pbvh.h @@ -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)) \ diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index e908868df75..0381ecc1fb3 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -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); diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 0ea2f78a415..6d124377821 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -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; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 6fe7ad05a70..d75ef78fc4c 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -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; } diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 2970bdfb5a4..bdd73cd6db3 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -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)) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 05b5b90344c..5f17d44a881 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -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); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 5e79616b0b0..0852378974e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -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); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 25555f2526f..b204fc75255 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -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); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index c44a181841e..2aa7bb9cc6b 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -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) { diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index afc85a8144e..4292246d8cc 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -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; |