Sculpt: Fix T101864: Mask initialization not updating multires data
BKE_sculpt_mask_layers_ensure now takes a depsgraph argument and will evaluate the depsgraph if a multires mask layer is added. This is necassary to update the multires runtime data so that pbvh knows it has a grids mask layer. Also added code to update pbvh->gridkey.
This commit is contained in:
parent
4c320e2639
commit
25e84334f7
Notes:
blender-bot
2023-02-14 04:20:36 +01:00
Referenced by issue #101864, Regression: Crash when lasso masking in sculpt mode
|
@ -860,7 +860,18 @@ int *BKE_sculpt_face_sets_ensure(struct Mesh *mesh);
|
|||
* (see #SCULPT_visibility_sync_all_from_faces).
|
||||
*/
|
||||
bool *BKE_sculpt_hide_poly_ensure(struct Mesh *mesh);
|
||||
int BKE_sculpt_mask_layers_ensure(struct Object *ob, struct MultiresModifierData *mmd);
|
||||
|
||||
/* Ensures a mask layer exists. If depsgraph and bmain are non-null,
|
||||
* a mask doesn't exist and the object has a multiresolution modifier
|
||||
* then the scene depsgraph will be evaluated to update the runtime
|
||||
* subdivision data.
|
||||
*
|
||||
* Note: always call *before* BKE_sculpt_update_object_for_edit.
|
||||
*/
|
||||
int BKE_sculpt_mask_layers_ensure(struct Depsgraph *depsgraph,
|
||||
struct Main *bmain,
|
||||
struct Object *ob,
|
||||
struct MultiresModifierData *mmd);
|
||||
void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene);
|
||||
|
||||
struct PBVH *BKE_sculpt_object_pbvh_ensure(struct Depsgraph *depsgraph, struct Object *ob);
|
||||
|
|
|
@ -505,7 +505,8 @@ void BKE_pbvh_grids_update(PBVH *pbvh,
|
|||
struct CCGElem **grids,
|
||||
void **gridfaces,
|
||||
struct DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden);
|
||||
unsigned int **grid_hidden,
|
||||
struct CCGKey *key);
|
||||
void BKE_pbvh_subdiv_cgg_set(PBVH *pbvh, struct SubdivCCG *subdiv_ccg);
|
||||
void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets);
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_subsurf.h"
|
||||
|
||||
|
@ -1986,7 +1987,10 @@ bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh)
|
|||
&mesh->pdata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh->totpoly, ".hide_poly"));
|
||||
}
|
||||
|
||||
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
|
||||
int BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
|
||||
Main *bmain,
|
||||
Object *ob,
|
||||
MultiresModifierData *mmd)
|
||||
{
|
||||
Mesh *me = static_cast<Mesh *>(ob->data);
|
||||
const Span<MPoly> polys = me->polys();
|
||||
|
@ -2045,6 +2049,9 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
|
|||
}
|
||||
/* The evaluated multires CCG must be updated to contain the new data. */
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
|
||||
if (depsgraph) {
|
||||
BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
|
||||
}
|
||||
|
||||
ret |= SCULPT_MASK_LAYER_CALC_LOOP;
|
||||
}
|
||||
|
@ -2296,11 +2303,15 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
|
|||
|
||||
void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
|
||||
{
|
||||
CCGKey key;
|
||||
BKE_subdiv_ccg_key_top_level(&key, subdiv_ccg);
|
||||
|
||||
BKE_pbvh_grids_update(pbvh,
|
||||
subdiv_ccg->grids,
|
||||
(void **)subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
subdiv_ccg->grid_hidden);
|
||||
subdiv_ccg->grid_hidden,
|
||||
&key);
|
||||
}
|
||||
|
||||
bool BKE_sculptsession_use_pbvh_draw(const Object *ob, const View3D * /*v3d*/)
|
||||
|
|
|
@ -3064,9 +3064,14 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_pbvh_grids_update(
|
||||
PBVH *pbvh, CCGElem **grids, void **gridfaces, DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
void **gridfaces,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
CCGKey *key)
|
||||
{
|
||||
pbvh->gridkey = *key;
|
||||
pbvh->grids = grids;
|
||||
pbvh->gridfaces = gridfaces;
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ static int geometry_extract_apply(bContext *C,
|
|||
|
||||
ED_object_sculptmode_exit(C, depsgraph);
|
||||
|
||||
BKE_sculpt_mask_layers_ensure(ob, NULL);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, bmain, ob, NULL);
|
||||
|
||||
/* Ensures that deformation from sculpt mode is taken into account before duplicating the mesh to
|
||||
* extract the geometry. */
|
||||
|
@ -481,7 +481,7 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op)
|
|||
Object *ob = CTX_data_active_object(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
|
||||
BKE_sculpt_mask_layers_ensure(ob, NULL);
|
||||
BKE_sculpt_mask_layers_ensure(NULL, NULL, ob, NULL);
|
||||
|
||||
Mesh *mesh = ob->data;
|
||||
Mesh *new_mesh = (Mesh *)BKE_id_copy(bmain, &mesh->id);
|
||||
|
|
|
@ -218,7 +218,7 @@ ModifierData *ED_object_modifier_add(
|
|||
|
||||
if (ob->mode & OB_MODE_SCULPT) {
|
||||
/* ensure that grid paint mask layer is created */
|
||||
BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
|
||||
BKE_sculpt_mask_layers_ensure(nullptr, nullptr, ob, (MultiresModifierData *)new_md);
|
||||
}
|
||||
}
|
||||
else if (type == eModifierType_Skin) {
|
||||
|
@ -2041,7 +2041,8 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (object->mode & OB_MODE_SCULPT) {
|
||||
/* ensure that grid paint mask layer is created */
|
||||
BKE_sculpt_mask_layers_ensure(object, mmd);
|
||||
BKE_sculpt_mask_layers_ensure(
|
||||
CTX_data_ensure_evaluated_depsgraph(C), CTX_data_main(C), object, mmd);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "BKE_multires.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subsurf.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -146,7 +147,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op)
|
|||
value = RNA_float_get(op->ptr, "value");
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
BKE_sculpt_mask_layers_ensure(ob, mmd);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
|
||||
pbvh = ob->sculpt->pbvh;
|
||||
|
@ -861,7 +862,9 @@ static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext
|
|||
BKE_pbvh_update_vertex_data(sgcontext->ss->pbvh, PBVH_UpdateMask);
|
||||
}
|
||||
|
||||
static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op)
|
||||
static void sculpt_gesture_init_mask_properties(bContext *C,
|
||||
SculptGestureContext *sgcontext,
|
||||
wmOperator *op)
|
||||
{
|
||||
sgcontext->operation = MEM_callocN(sizeof(SculptGestureMaskOperation), "Mask Operation");
|
||||
|
||||
|
@ -869,7 +872,8 @@ static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext,
|
|||
|
||||
Object *object = sgcontext->vc.obact;
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(sgcontext->vc.scene, object);
|
||||
BKE_sculpt_mask_layers_ensure(sgcontext->vc.obact, mmd);
|
||||
BKE_sculpt_mask_layers_ensure(
|
||||
CTX_data_depsgraph_pointer(C), CTX_data_main(C), sgcontext->vc.obact, mmd);
|
||||
|
||||
mask_operation->op.sculpt_gesture_begin = sculpt_gesture_mask_begin;
|
||||
mask_operation->op.sculpt_gesture_apply_for_symmetry_pass =
|
||||
|
@ -1514,7 +1518,7 @@ static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
|
|||
if (!sgcontext) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
sculpt_gesture_init_mask_properties(sgcontext, op);
|
||||
sculpt_gesture_init_mask_properties(C, sgcontext, op);
|
||||
sculpt_gesture_apply(C, sgcontext, op);
|
||||
sculpt_gesture_context_free(sgcontext);
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1526,7 +1530,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
|
|||
if (!sgcontext) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
sculpt_gesture_init_mask_properties(sgcontext, op);
|
||||
sculpt_gesture_init_mask_properties(C, sgcontext, op);
|
||||
sculpt_gesture_apply(C, sgcontext, op);
|
||||
sculpt_gesture_context_free(sgcontext);
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -1538,7 +1542,7 @@ static int paint_mask_gesture_line_exec(bContext *C, wmOperator *op)
|
|||
if (!sgcontext) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
sculpt_gesture_init_mask_properties(sgcontext, op);
|
||||
sculpt_gesture_init_mask_properties(C, sgcontext, op);
|
||||
sculpt_gesture_apply(C, sgcontext, op);
|
||||
sculpt_gesture_context_free(sgcontext);
|
||||
return OPERATOR_FINISHED;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
#include "BKE_subsurf.h"
|
||||
|
||||
|
@ -5666,7 +5667,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
}
|
||||
if (SCULPT_tool_is_mask(brush->sculpt_tool)) {
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
|
||||
BKE_sculpt_mask_layers_ensure(ob, mmd);
|
||||
BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd);
|
||||
}
|
||||
if (SCULPT_tool_is_face_sets(brush->sculpt_tool)) {
|
||||
Mesh *mesh = BKE_object_get_original_mesh(ob);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_subdiv_ccg.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -2107,6 +2108,11 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
}
|
||||
|
||||
if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_MASK) {
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||
}
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, needs_colors);
|
||||
|
||||
/* Do nothing when the mesh has 0 vertices. */
|
||||
|
@ -2121,11 +2127,6 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
ss->face_sets = BKE_sculpt_face_sets_ensure(mesh);
|
||||
}
|
||||
|
||||
if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_MASK) {
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob);
|
||||
BKE_sculpt_mask_layers_ensure(ob, mmd);
|
||||
}
|
||||
|
||||
/* Face Set operations are not supported in dyntopo. */
|
||||
if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS &&
|
||||
BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "BKE_context.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pbvh.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
||||
|
@ -166,7 +167,7 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
|
|||
int filter_type = RNA_enum_get(op->ptr, "filter_type");
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
|
||||
BKE_sculpt_mask_layers_ensure(ob, mmd);
|
||||
BKE_sculpt_mask_layers_ensure(CTX_data_depsgraph_pointer(C), CTX_data_main(C), ob, mmd);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_ccg.h"
|
||||
|
@ -331,6 +332,11 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
SculptCursorGeometryInfo sgi;
|
||||
const float mval_fl[2] = {UNPACK2(event->mval)};
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
||||
op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position");
|
||||
|
@ -338,8 +344,6 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
|
||||
SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
|
||||
int vertex_count = SCULPT_vertex_count_get(ss);
|
||||
|
||||
ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_ccg.h"
|
||||
|
@ -110,6 +111,9 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
|||
|
||||
const int mode = RNA_enum_get(op->ptr, "mode");
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "DNA_listBase.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
@ -1041,12 +1042,12 @@ static int sculpt_bake_cavity_exec(bContext *C, wmOperator *op)
|
|||
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||
BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd);
|
||||
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);
|
||||
SCULPT_vertex_random_access_ensure(ss);
|
||||
|
||||
MultiresModifierData *mmd = BKE_sculpt_multires_active(CTX_data_scene(C), ob);
|
||||
BKE_sculpt_mask_layers_ensure(ob, mmd);
|
||||
|
||||
SCULPT_undo_push_begin(ob, op);
|
||||
|
||||
CavityBakeMixMode mode = RNA_enum_get(op->ptr, "mix_mode");
|
||||
|
|
Loading…
Reference in New Issue