[Bf-blender-cvs] [d6d51674a2f] sculpt-mode-features: Sculpt: Pose brush
Pablo Dobarro
noreply at git.blender.org
Fri Aug 16 00:11:12 CEST 2019
Commit: d6d51674a2fee3a1110d241b96d31480ce440cf1
Author: Pablo Dobarro
Date: Fri Aug 16 00:12:43 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rBd6d51674a2fee3a1110d241b96d31480ce440cf1
Sculpt: Pose brush
This commit also includes the MOUSE_INBETWEEN events fix for other
brushes.
===================================================================
M source/blender/blenkernel/intern/brush.c
M source/blender/editors/sculpt_paint/paint_stroke.c
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/makesdna/DNA_brush_types.h
M source/blender/makesrna/intern/rna_brush.c
===================================================================
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 56ebfe72162..262f47655f6 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -895,6 +895,7 @@ void BKE_brush_sculpt_reset(Brush *br)
br->add_col[2] = 0.750000;
break;
case SCULPT_TOOL_GRAB:
+ case SCULPT_TOOL_POSE:
case SCULPT_TOOL_SNAKE_HOOK:
case SCULPT_TOOL_THUMB:
br->size = 75;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 5f3075b12f5..7df06d99509 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -219,6 +219,7 @@ static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
case PAINT_MODE_SCULPT:
if (ELEM(brush->sculpt_tool,
SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_POSE,
SCULPT_TOOL_ROTATE,
SCULPT_TOOL_SNAKE_HOOK,
SCULPT_TOOL_THUMB)) {
@@ -234,6 +235,27 @@ static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
return true;
}
+static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode mode)
+{
+ switch (mode) {
+ case PAINT_MODE_SCULPT:
+ if (ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_POSE)) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ default:
+ break;
+ }
+
+ return true;
+}
+
/* Initialize the stroke cache variants from operator properties */
static bool paint_brush_update(bContext *C,
Brush *brush,
@@ -872,6 +894,7 @@ static bool sculpt_is_grab_tool(Brush *br)
{
return ELEM(br->sculpt_tool,
SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_POSE,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_ROTATE,
SCULPT_TOOL_SNAKE_HOOK);
@@ -1206,6 +1229,10 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
bool redraw = false;
float pressure;
+ if (event->type == INBETWEEN_MOUSEMOVE && !paint_tool_require_inbetween_mouse_events(br, mode)) {
+ return OPERATOR_RUNNING_MODAL;
+ }
+
/* see if tablet affects event. Line, anchored and drag dot strokes do not support pressure */
pressure = ((br->flag & (BRUSH_LINE | BRUSH_ANCHORED | BRUSH_DRAG_DOT)) ?
1.0f :
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 6803f01a26c..701ccb799d0 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -426,8 +426,12 @@ static bool sculpt_has_active_modifiers(Scene *scene, Object *ob)
static bool sculpt_tool_needs_original(const char sculpt_tool)
{
- return ELEM(
- sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_LAYER);
+ return ELEM(sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER,
+ SCULPT_TOOL_POSE);
}
static bool sculpt_tool_is_proxy_used(const char sculpt_tool)
@@ -1528,6 +1532,9 @@ static float brush_strength(const Sculpt *sd,
case SCULPT_TOOL_GRAB:
return root_alpha * feather;
+ case SCULPT_TOOL_POSE:
+ return root_alpha * feather;
+
case SCULPT_TOOL_ROTATE:
return alpha * pressure * feather;
@@ -3420,6 +3427,94 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
BLI_task_parallel_range(0, totnode, &data, do_pinch_brush_task_cb_ex, &settings);
}
+static bool check_vertex_pivot_symmetry(float vco[3], float pco[3], char symm);
+static void do_pose_brush_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const ParallelRangeTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+
+ PBVHVertexIter vd;
+ float disp[3], val[3];
+ float final_pos[3];
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+
+ if (check_vertex_pivot_symmetry(ss->cache->pose_orco[vd.index],
+ data->pose_initial_co,
+ ss->cache->mirror_symmetry_pass)) {
+ copy_v3_v3(val, ss->cache->pose_orco[vd.index]);
+ mul_m4_v3(data->transform_trans_inv, val);
+ mul_m4_v3(data->transform_rot, val);
+ mul_m4_v3(data->transform_trans, val);
+ sub_v3_v3v3(disp, val, ss->cache->pose_orco[vd.index]);
+
+ mul_v3_fl(disp, ss->cache->pose_factor[vd.index]);
+ float mask = vd.mask ? *vd.mask : 0.0f;
+ mul_v3_fl(disp, 1.0f - mask);
+ add_v3_v3v3(final_pos, ss->cache->pose_orco[vd.index], disp);
+ sculpt_vertex_co_set(ss, vd.index, final_pos);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static void do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ float grab_delta[3], rot_quat[4], initial_v[3], current_v[3], temp[3];
+ float pose_origin[3];
+ float pose_initial_co[3];
+ float transform_rot[4][4], transform_trans[4][4], transform_trans_inv[4][4];
+
+ copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry);
+
+ copy_v3_v3(pose_origin, ss->cache->pose_origin);
+ flip_v3(pose_origin, (char)ss->cache->mirror_symmetry_pass);
+
+ copy_v3_v3(pose_initial_co, ss->cache->pose_initial_co);
+ flip_v3(pose_initial_co, (char)ss->cache->mirror_symmetry_pass);
+
+ sub_v3_v3v3(initial_v, pose_initial_co, pose_origin);
+ normalize_v3(initial_v);
+
+ add_v3_v3v3(temp, pose_initial_co, grab_delta);
+ sub_v3_v3v3(current_v, temp, pose_origin);
+ normalize_v3(current_v);
+
+ rotation_between_vecs_to_quat(rot_quat, initial_v, current_v);
+ unit_m4(transform_rot);
+ unit_m4(transform_trans);
+ quat_to_mat4(transform_rot, rot_quat);
+ translate_m4(transform_trans, pose_origin[0], pose_origin[1], pose_origin[2]);
+ invert_m4_m4(transform_trans_inv, transform_trans);
+
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .brush = brush,
+ .nodes = nodes,
+ .grab_delta = grab_delta,
+ .pose_origin = pose_origin,
+ .pose_initial_co = pose_initial_co,
+ .transform_rot = transform_rot,
+ .transform_trans = transform_trans,
+ .transform_trans_inv = transform_trans_inv,
+ };
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
+ BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings);
+}
+
static void do_grab_brush_task_cb_ex(void *__restrict userdata,
const int n,
const ParallelRangeTLS *__restrict tls)
@@ -5074,6 +5169,151 @@ static float *sculpt_topology_automasking_init(Sculpt *sd, Object *ob, int initi
return automask_factor;
}
+static void pose_brush_init_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const ParallelRangeTLS *__restrict tls)
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ const Brush *brush = data->brush;
+
+ PBVHVertexIter vd;
+
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SculptVertexNeighbourIter ni;
+ float avg = 0;
+ int total = 0;
+ sculpt_vertex_neighbours_iter_begin(ss, vd.index, ni)
+ {
+ avg += ss->cache->pose_factor[ni.index];
+ total++;
+ }
+ sculpt_vertex_neighbours_iter_end(ni)
+
+ if (total > 0)
+ {
+ ss->cache->pose_factor[vd.index] = avg / (float)total;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+static bool sculpt_pose_brush_is_vertex_inside_brush_radius(float vertex[3],
+ float br_co[3],
+ float radius,
+ char symm)
+{
+ int i;
+ for (i = 0; i <= symm; ++i) {
+ if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
+ float location[3];
+ flip_v3_v3(location, br_co, i);
+ if (len_v3v3(location, vertex) < radius) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+static void sculpt_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br)
+{
+ ss->cache->pose_factor = MEM_callocN(sculpt_vertex_count_get(ss) * sizeof(float), "Pose factor");
+ ss->cache->pose_orco = MEM_callocN(sculpt_vertex_count_get(ss) * 3 * sizeof(float), "Pose orco");
+
+ copy_v3_v3(ss->cache->pose_initial_co, ss->cache->location);
+
+ char *visited_vertices = MEM_callocN(sculpt_vertex_count_get(ss) * sizeof(char), "prevmask");
+ GSQueue *queue = BLI_gsqueue_new(sizeof(vertex_topology_it));
+
+ float tot_co = 0;
+ zero_v3(ss->cache->pose_origin);
+
+ for (int i = 0; i < sculpt_vertex_count_get(ss); i++) {
+ copy_v3_v3(ss->cache->pose_orco[i], sculpt_vertex_co_get(ss, i));
+ }
+
+ vertex_topology_it mevit;
+
+ const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+ int i;
+ for (i = 0; i <= symm; ++i) {
+ if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
+ float location[3];
+ flip_v3_v3(location, sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)), i);
+ if (i == 0) {
+ mevit.v = sculpt_active_vertex_get(ss);
+ }
+ else {
+ mevit.v = sculpt_nearest_vertex_get(sd, ob, location, FLT_MAX, false);
+ }
+ if (mevit.v != -1) {
+ mevit.it = 1;
+ BLI_gsqueue_push(queue, &mevit);
+ }
+ }
+ }
+
+ while (!BLI_gsqueue_is_empty(queue)) {
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list