diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index acb0e53aa55..9e8d9636a29 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -293,7 +293,10 @@ void ED_object_vpaintmode_exit(struct bContext *C); void ED_object_wpaintmode_exit_ex(struct Object *ob); void ED_object_wpaintmode_exit(struct bContext *C); -void ED_object_texture_paint_mode_enter_ex(struct Main *bmain, struct Scene *scene, Object *ob); +void ED_object_texture_paint_mode_enter_ex(struct Main *bmain, + struct Scene *scene, + struct Depsgraph *depsgraph, + Object *ob); void ED_object_texture_paint_mode_enter(struct bContext *C); void ED_object_texture_paint_mode_exit_ex(struct Main *bmain, struct Scene *scene, Object *ob); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index b6e83187c86..c2fde7c2117 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -15,6 +15,7 @@ #include "DNA_brush_types.h" #include "DNA_color_types.h" #include "DNA_customdata_types.h" +#include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" @@ -27,6 +28,7 @@ #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_image.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_paint.h" diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index 8c6358520ca..eebc1bdb4b9 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -34,11 +34,14 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_object.h" #include "BKE_paint.h" +#include "BKE_scene.h" #include "NOD_texture.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "UI_interface.h" #include "UI_view2d.h" @@ -755,7 +758,34 @@ void PAINT_OT_sample_color(wmOperatorType *ot) /******************** texture paint toggle operator ********************/ -void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob) +static void paint_init_pivot(Object *ob, Scene *scene) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + + const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob); + if (!me_eval) { + me_eval = (const Mesh *)ob->data; + } + + float location[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + + if (!BKE_mesh_minmax(me_eval, location, max)) { + zero_v3(location); + zero_v3(max); + } + + interp_v3_v3v3(location, location, max, 0.5f); + mul_m4_v3(ob->object_to_world, location); + + ups->last_stroke_valid = true; + ups->average_stroke_counter = 1; + copy_v3_v3(ups->average_stroke_accum, location); +} + +void ED_object_texture_paint_mode_enter_ex(Main *bmain, + Scene *scene, + Depsgraph *depsgraph, + Object *ob) { Image *ima = nullptr; ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; @@ -812,6 +842,14 @@ void ED_object_texture_paint_mode_enter_ex(Main *bmain, Scene *scene, Object *ob Mesh *me = BKE_mesh_from_object(ob); BLI_assert(me != nullptr); DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE); + + /* Ensure we have evaluated data for bounding box. */ + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); + + /* Set pivot to bounding box center. */ + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + paint_init_pivot(ob_eval ? ob_eval : ob, scene); + WM_main_add_notifier(NC_SCENE | ND_MODE, scene); } @@ -820,7 +858,9 @@ void ED_object_texture_paint_mode_enter(bContext *C) Main *bmain = CTX_data_main(C); Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); - ED_object_texture_paint_mode_enter_ex(bmain, scene, ob); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + + ED_object_texture_paint_mode_enter_ex(bmain, scene, depsgraph, ob); } void ED_object_texture_paint_mode_exit_ex(Main *bmain, Scene *scene, Object *ob) @@ -879,7 +919,8 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op) ED_object_texture_paint_mode_exit_ex(bmain, scene, ob); } else { - ED_object_texture_paint_mode_enter_ex(bmain, scene, ob); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + ED_object_texture_paint_mode_enter_ex(bmain, scene, depsgraph, ob); } WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 8e790ac435e..c01894cf2ce 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -1175,6 +1175,8 @@ static void vertex_paint_init_session(Depsgraph *depsgraph, ob->sculpt = (SculptSession *)MEM_callocN(sizeof(SculptSession), "sculpt session"); ob->sculpt->mode_type = object_mode; BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, true); + + SCULPT_ensure_valid_pivot(ob, scene); } static void vwpaint_init_stroke(Depsgraph *depsgraph, Object *ob) diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 46414cf6a0d..75c896018af 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1927,6 +1927,8 @@ void SCULPT_stroke_id_ensure(struct Object *ob); void SCULPT_stroke_id_next(struct Object *ob); bool SCULPT_tool_can_reuse_automask(int sculpt_tool); +void SCULPT_ensure_valid_pivot(const struct Object *ob, struct Scene *scene); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index 6893bf1c9e2..2506f6915a1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -303,6 +303,32 @@ static void sculpt_init_session(Main *bmain, Depsgraph *depsgraph, Scene *scene, } } +void SCULPT_ensure_valid_pivot(const Object *ob, Scene *scene) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + const SculptSession *ss = ob->sculpt; + + printf("%s: stroke counter: %d %d\n", + __func__, + ups->average_stroke_counter, + (int)ups->last_stroke_valid); + + /* No valid pivot? Use bounding box center. */ + if (ups->average_stroke_counter == 0 || !ups->last_stroke_valid) { + float location[3], max[3]; + BKE_pbvh_bounding_box(ss->pbvh, location, max); + + interp_v3_v3v3(location, location, max, 0.5f); + mul_m4_v3(ob->object_to_world, location); + + copy_v3_v3(ups->average_stroke_accum, location); + ups->average_stroke_counter = 1; + + /* Update last stroke position. */ + ups->last_stroke_valid = true; + } +} + void ED_object_sculptmode_enter_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, @@ -387,6 +413,8 @@ void ED_object_sculptmode_enter_ex(Main *bmain, } } + SCULPT_ensure_valid_pivot(ob, scene); + /* Flush object mode. */ DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); }