diff options
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 3 | ||||
-rw-r--r-- | source/blender/editors/include/ED_sculpt.h | 1 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 23 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_edit.c | 15 |
4 files changed, 38 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index f616da4985f..ff5efd3b02b 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -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); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index 0381ecc1fb3..a50a8a50eaa 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -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); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 75a00ba4f76..d1702c8f505 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -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; } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 17d467e593e..643e08ab405 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -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 */ |