forked from bartvdbraak/blender
Fix #34818: Sculpting Mode only rotates around geometry origin (bring bug back)
Made it so average coordinate of previous stroke is used as a viewport rotation center when Rotate Around Selection is enabled in user preferences.
This commit is contained in:
parent
e430ee20d5
commit
1d008de24f
@ -158,6 +158,9 @@ typedef struct SculptSession {
|
||||
/* last paint/sculpt stroke location */
|
||||
int last_stroke_valid;
|
||||
float last_stroke[3];
|
||||
|
||||
float average_stroke_accum[3];
|
||||
int average_stroke_counter;
|
||||
} SculptSession;
|
||||
|
||||
void free_sculptsession(struct Object *ob);
|
||||
|
@ -44,6 +44,7 @@ void sculpt_get_redraw_planes(float planes[4][4], struct ARegion *ar,
|
||||
struct RegionView3D *rv3d, struct Object *ob);
|
||||
void ED_sculpt_force_update(struct bContext *C);
|
||||
float *ED_sculpt_get_last_stroke(struct Object *ob);
|
||||
void ED_sculpt_get_average_stroke(struct Object *ob, float stroke[3]);
|
||||
int ED_sculpt_minmax(struct bContext *C, float min[3], float max[3]);
|
||||
int ED_sculpt_mask_layers_ensure(struct Object *ob,
|
||||
struct MultiresModifierData *mmd);
|
||||
|
@ -118,6 +118,17 @@ float *ED_sculpt_get_last_stroke(struct Object *ob)
|
||||
return (ob && ob->sculpt && ob->sculpt->last_stroke_valid) ? ob->sculpt->last_stroke : NULL;
|
||||
}
|
||||
|
||||
void ED_sculpt_get_average_stroke(Object *ob, float stroke[3])
|
||||
{
|
||||
if (ob->sculpt->last_stroke_valid) {
|
||||
float fac = 1.0f / ob->sculpt->average_stroke_counter;
|
||||
mul_v3_v3fl(stroke, ob->sculpt->average_stroke_accum, fac);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(stroke, ob->obmat[3]);
|
||||
}
|
||||
}
|
||||
|
||||
int ED_sculpt_minmax(bContext *C, float min[3], float max[3])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
@ -3015,6 +3026,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
|
||||
|
||||
/* Only act if some verts are inside the brush area */
|
||||
if (totnode) {
|
||||
float location[3];
|
||||
|
||||
#pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP)
|
||||
for (n = 0; n < totnode; n++) {
|
||||
sculpt_undo_push_node(ob, nodes[n],
|
||||
@ -3099,6 +3112,13 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush)
|
||||
}
|
||||
|
||||
MEM_freeN(nodes);
|
||||
|
||||
/* update average stroke position */
|
||||
copy_v3_v3(location, ss->cache->true_location);
|
||||
mul_m4_v3(ob->obmat, location);
|
||||
|
||||
add_v3_v3(ob->sculpt->average_stroke_accum, location);
|
||||
ob->sculpt->average_stroke_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4143,6 +4163,9 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
|
||||
is_smooth = sculpt_any_smooth_mode(brush, NULL, mode);
|
||||
sculpt_update_mesh_elements(scene, sd, ob, is_smooth, need_mask);
|
||||
|
||||
zero_v3(ob->sculpt->average_stroke_accum);
|
||||
ob->sculpt->average_stroke_counter = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -441,11 +441,18 @@ static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *even
|
||||
Object *ob = OBACT;
|
||||
|
||||
if (ob && (ob->mode & OB_MODE_ALL_PAINT) && (BKE_object_pose_armature_get(ob) == NULL)) {
|
||||
/* transformation is disabled for painting modes, which will make it
|
||||
* so previous offset is used. This is annoying when you open file
|
||||
* saved with active object in painting mode
|
||||
/* in case of sculpting use last average stroke position as a rotation
|
||||
* center, in other cases it's not clear what rotation center shall be
|
||||
* so just rotate around object origin
|
||||
*/
|
||||
copy_v3_v3(lastofs, ob->obmat[3]);
|
||||
if (ob->mode & OB_MODE_SCULPT) {
|
||||
float stroke[3];
|
||||
ED_sculpt_get_average_stroke(ob, stroke);
|
||||
copy_v3_v3(lastofs, stroke);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(lastofs, ob->obmat[3]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If there's no selection, lastofs is unmodified and last value since static */
|
||||
|
Loading…
Reference in New Issue
Block a user