diff options
Diffstat (limited to 'source/blender/blenkernel/intern/paint.c')
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 203 |
1 files changed, 161 insertions, 42 deletions
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 2c17fa44229..404a1a656d9 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -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,18 +54,21 @@ #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" #include "BKE_library.h" #include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_paint.h" #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,9 +78,9 @@ 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) +void BKE_paint_invalidate_overlay_tex(Scene *scene, ViewLayer *view_layer, const Tex *tex) { - Paint *p = BKE_paint_get_active(scene); + Paint *p = BKE_paint_get_active(scene, view_layer); Brush *br = p->brush; if (!br) @@ -88,9 +92,9 @@ void BKE_paint_invalidate_overlay_tex(Scene *scene, const Tex *tex) overlay_flags |= PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY; } -void BKE_paint_invalidate_cursor_overlay(Scene *scene, CurveMapping *curve) +void BKE_paint_invalidate_cursor_overlay(Scene *scene, ViewLayer *view_layer, CurveMapping *curve) { - Paint *p = BKE_paint_get_active(scene); + Paint *p = BKE_paint_get_active(scene, view_layer); Brush *br = p->brush; if (br && br->curve == curve) @@ -156,13 +160,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) { - 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 (view_layer->basact->object->mode) { case OB_MODE_SCULPT: return &ts->sculpt->paint; case OB_MODE_VERTEX_PAINT: @@ -175,6 +179,8 @@ Paint *BKE_paint_get_active(Scene *sce) if (ts->use_uv_sculpt) return &ts->uvsculpt->paint; return &ts->imapaint.paint; + default: + break; } } @@ -188,14 +194,15 @@ 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) { 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) { @@ -209,7 +216,7 @@ Paint *BKE_paint_get_active_from_context(const bContext *C) } } else { - return BKE_paint_get_active(sce); + return BKE_paint_get_active(sce, view_layer); } } @@ -219,14 +226,15 @@ 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) { 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) { @@ -332,8 +340,8 @@ void BKE_paint_palette_set(Paint *p, Palette *palette) { if (p) { id_us_min((ID *)p->palette); - id_us_plus((ID *)palette); p->palette = palette; + id_us_plus((ID *)p->palette); } } @@ -341,8 +349,8 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc) { if (br) { id_us_min((ID *)br->paint_curve); - id_us_plus((ID *)pc); br->paint_curve = pc; + id_us_plus((ID *)br->paint_curve); } } @@ -375,9 +383,7 @@ void BKE_palette_clear(Palette *palette) Palette *BKE_palette_add(Main *bmain, const char *name) { - Palette *palette; - - palette = BKE_libblock_alloc(bmain, ID_PAL, name, 0); + Palette *palette = BKE_id_new(bmain, ID_PAL, name); /* enable fake user by default */ id_fake_user_set(&palette->id); @@ -418,7 +424,7 @@ void BKE_palette_free(Palette *palette) PaletteColor *BKE_palette_color_add(Palette *palette) { - PaletteColor *color = MEM_callocN(sizeof(*color), "Pallete Color"); + PaletteColor *color = MEM_callocN(sizeof(*color), "Palette Color"); BLI_addtail(&palette->colors, color); return color; } @@ -713,8 +719,8 @@ void BKE_sculptsession_bm_to_me(Object *ob, bool reorder) if (ob && ob->sculpt) { 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); + /* ensure the objects evaluated mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */ + DEG_id_tag_update(&ob->id, OB_RECALC_DATA); } } @@ -724,7 +730,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. */ @@ -749,7 +755,6 @@ void BKE_sculptsession_free(Object *ob) { if (ob && ob->sculpt) { SculptSession *ss = ob->sculpt; - DerivedMesh *dm = ob->derivedFinal; if (ss->bm) { BKE_sculptsession_bm_to_me(ob, true); @@ -758,12 +763,11 @@ void BKE_sculptsession_free(Object *ob) if (ss->pbvh) BKE_pbvh_free(ss->pbvh); + MEM_SAFE_FREE(ss->pmap); + MEM_SAFE_FREE(ss->pmap_mem); if (ss->bm_log) BM_log_free(ss->bm_log); - if (dm && dm->getPBVH) - dm->getPBVH(NULL, dm); /* signal to clear */ - if (ss->texcache) MEM_freeN(ss->texcache); @@ -853,14 +857,23 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) } /** - * \param need_mask So the DerivedMesh thats returned has mask data + * \param need_mask So taht the evaluated mesh that is 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( + Depsgraph *depsgraph, Scene *scene, Sculpt *sd, Object *ob, + bool need_pmap, bool need_mask) { - DerivedMesh *dm; + if (depsgraph == NULL) { + /* Happens on file load. + * + * We do nothing in this case, it will be taken care about on depsgraph + * evaluation. + */ + return; + } + SculptSession *ss = ob->sculpt; - Mesh *me = ob->data; + Mesh *me = BKE_object_get_original_mesh(ob); MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); ss->modifiers_active = sculpt_modifiers_active(scene, sd, ob); @@ -895,13 +908,14 @@ 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); + Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH); + Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene, ob, CD_MASK_BAREMESH); /* VWPaint require mesh info for loop lookup, so require sculpt mode here */ if (mmd && ob->mode & OB_MODE_SCULPT) { ss->multires = mmd; - ss->totvert = dm->getNumVerts(dm); - ss->totpoly = dm->getNumPolys(dm); + ss->totvert = me_eval->totvert; + ss->totpoly = me_eval->totpoly; ss->mvert = NULL; ss->mpoly = NULL; ss->mloop = NULL; @@ -916,8 +930,17 @@ 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->pmap = (need_pmap && dm->getPolyMap) ? dm->getPolyMap(ob, dm) : NULL; + PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(ob, me_eval_deform); + BLI_assert(pbvh == ss->pbvh); + UNUSED_VARS_NDEBUG(pbvh); + MEM_SAFE_FREE(ss->pmap); + MEM_SAFE_FREE(ss->pmap_mem); + if (need_pmap && ob->type == OB_MESH) { + BKE_mesh_vert_poly_map_create( + &ss->pmap, &ss->pmap_mem, + me->mpoly, me->mloop, + me->totvert, me->totpoly, me->totloop); + } pbvh_show_diffuse_color_set(ss->pbvh, ss->show_diffuse_color); pbvh_show_mask_set(ss->pbvh, ss->show_mask); @@ -930,8 +953,8 @@ 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_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos); + BKE_crazyspace_build_sculpt(depsgraph, scene, ob, &ss->deform_imats, &ss->deform_cos); + BKE_pbvh_apply_vertCos(ss->pbvh, ss->deform_cos, me->totvert); for (a = 0; a < me->totvert; ++a) { invert_m3(ss->deform_imats[a]); @@ -955,7 +978,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, if (vertCos) { if (!pbvh_deformed) { /* apply shape keys coordinates to PBVH */ - BKE_pbvh_apply_vertCos(ss->pbvh, vertCos); + BKE_pbvh_apply_vertCos(ss->pbvh, vertCos, me->totvert); } if (ss->deform_cos == NULL) { ss->deform_cos = vertCos; @@ -966,6 +989,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) @@ -1074,3 +1100,96 @@ void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene) sd->paint.tile_offset[2] = 1.0f; } } + +static bool check_sculpt_object_deformed(Object *object, const bool for_construction) +{ + bool deformed = false; + + /* Active modifiers means extra deformation, which can't be handled correct + * on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush + * stuff and show final evaluated mesh so user would see actual object shape. + */ + deformed |= object->sculpt->modifiers_active; + + if (for_construction) { + deformed |= object->sculpt->kb != NULL; + } + else { + /* As in case with modifiers, we can't synchronize deformation made against + * PBVH and non-locked keyblock, so also use PBVH only for brushes and + * final DM to give final result to user. + */ + deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0; + } + + return deformed; +} + +PBVH *BKE_sculpt_object_pbvh_ensure(Object *ob, Mesh *me_eval_deform) +{ + if (!ob) { + return NULL; + } + + if (!ob->sculpt) { + return NULL; + } + + PBVH *pbvh = ob->sculpt->pbvh; + + /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */ + if (!pbvh && ob->sculpt->bm) { + pbvh = BKE_pbvh_new(); + + BKE_pbvh_build_bmesh(pbvh, ob->sculpt->bm, + ob->sculpt->bm_smooth_shading, + ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset, + ob->sculpt->cd_face_node_offset); + + pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color); + pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); + } + + /* always build pbvh from original mesh, and only use it for drawing if + * this evaluated mesh is just original mesh. it's the multires subsurf dm + * that this is actually for, to support a pbvh on a modified mesh */ + if (!pbvh && ob->type == OB_MESH) { + Mesh *me = BKE_object_get_original_mesh(ob); + const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop); + MLoopTri *looptri; + bool deformed; + + pbvh = BKE_pbvh_new(); + + looptri = MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__); + + BKE_mesh_recalc_looptri( + me->mloop, me->mpoly, + me->mvert, + me->totloop, me->totpoly, + looptri); + + BKE_pbvh_build_mesh( + pbvh, + me->mpoly, me->mloop, + me->mvert, me->totvert, &me->vdata, + looptri, looptris_num); + + pbvh_show_diffuse_color_set(pbvh, ob->sculpt->show_diffuse_color); + pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); + + deformed = check_sculpt_object_deformed(ob, true); + + if (deformed && me_eval_deform) { + int totvert; + float (*v_cos)[3]; + + v_cos = BKE_mesh_vertexCos_get(me_eval_deform, &totvert); + BKE_pbvh_apply_vertCos(pbvh, v_cos, totvert); + MEM_freeN(v_cos); + } + } + + ob->sculpt->pbvh = pbvh; + return pbvh; +} |