Sculpt: Fix broken pivots when entering paint modes

When entering paint modes the paint pivot was cleared,
which broken rotate around pivot.  Fixed for all paint modes.
PBVH modes set the pivot to the PBVH bounding box
while texture paint uses the evaluated mesh bounding box.
This commit is contained in:
Joseph Eagar 2022-11-30 12:36:29 -08:00
parent 8fa5206ab0
commit fde628ddb3
6 changed files with 82 additions and 4 deletions

View File

@ -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);

View File

@ -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"

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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);
}