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:
Sergey Sharybin 2013-04-19 13:26:17 +00:00
parent e430ee20d5
commit 1d008de24f
4 changed files with 38 additions and 4 deletions

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