[Bf-blender-cvs] [5d7f7b7065c] sculpt-dev: Sculpt: Initial support for bend deformations in Pose
Pablo Dobarro
noreply at git.blender.org
Tue Feb 23 17:33:46 CET 2021
Commit: 5d7f7b7065c13920cbd5c76e321402eb6d46ef24
Author: Pablo Dobarro
Date: Tue Feb 23 17:33:21 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rB5d7f7b7065c13920cbd5c76e321402eb6d46ef24
Sculpt: Initial support for bend deformations in Pose
===================================================================
M source/blender/blenkernel/BKE_paint.h
M source/blender/editors/sculpt_paint/sculpt_pose.c
M source/blender/makesdna/DNA_brush_enums.h
M source/blender/makesdna/DNA_object_types.h
M source/blender/makesrna/intern/rna_brush.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 605b16f1575..f1cb15d3ed5 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -260,6 +260,11 @@ typedef struct SculptPoseIKChain {
SculptPoseIKChainSegment *segments;
int tot_segments;
float grab_delta_offset[3];
+ float bend_mat[4][4];
+ float bend_mat_inv[4][4];
+ float bend_factor;
+ float bend_limit;
+ float bend_upper_limit;
} SculptPoseIKChain;
/* Cloth Brush */
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c
index a85f805894b..e4c0cceb0d6 100644
--- a/source/blender/editors/sculpt_paint/sculpt_pose.c
+++ b/source/blender/editors/sculpt_paint/sculpt_pose.c
@@ -157,6 +157,76 @@ static void pose_solve_scale_chain(SculptPoseIKChain *ik_chain, const float scal
}
}
+static void do_pose_brush_bend_task_cb_ex(void *__restrict userdata,
+ const int n,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
+ SculptPoseIKChainSegment *segments = ik_chain->segments;
+ const Brush *brush = data->brush;
+
+ if (fabsf(ik_chain->bend_factor) <= 0.00001f) {
+ return;
+ }
+
+ float final_pos[3];
+
+ SculptOrigVertData orig_data;
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+
+ const float ik_chain_weight = segments[0].weights[vd.index] *
+ (1.0f - SCULPT_vertex_mask_get(ss, vd.index));
+ if (ik_chain_weight == 0.0f) {
+ continue;
+ }
+
+ float orig_co[3];
+ mul_v3_m4v3(orig_co, ik_chain->bend_mat_inv, orig_data.co);
+
+ const float bend_factor = ik_chain->bend_factor;
+
+ if (fabsf(bend_factor) <= 0.0000001f) {
+ continue;
+ }
+
+ if (orig_co[0] < 0.0f) {
+ continue;
+ }
+
+ const float theta = orig_co[0] * bend_factor;
+ const float sint = sinf(theta);
+ const float cost = cosf(theta);
+
+ float new_co[3];
+ new_co[0] = -(orig_co[1] - 1.0f / bend_factor) * sint;
+ new_co[1] = (orig_co[1] - 1.0f / bend_factor) * cost + 1.0f / bend_factor;
+ new_co[2] = orig_co[2];
+
+ float final_co[3];
+ float disp[3];
+ mul_v3_m4v3(final_co, ik_chain->bend_mat, new_co);
+
+ sub_v3_v3v3(disp, final_co, orig_data.co);
+ mul_v3_fl(disp, ik_chain_weight);
+ add_v3_v3v3(final_pos, orig_data.co, disp);
+
+ float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+ copy_v3_v3(target_co, final_pos);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
static void do_pose_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict UNUSED(tls))
@@ -667,6 +737,7 @@ static int pose_brush_num_effective_segments(const Brush *brush)
* artifacts in the areas affected by multiple segments. */
if (ELEM(brush->pose_deform_type,
BRUSH_POSE_DEFORM_SCALE_TRASLATE,
+ BRUSH_POSE_DEFORM_BEND,
BRUSH_POSE_DEFORM_SQUASH_STRETCH)) {
return 1;
}
@@ -1111,6 +1182,59 @@ static void sculpt_pose_do_squash_stretch_deform(SculptSession *ss, Brush *UNUSE
pose_solve_scale_chain(ik_chain, scale);
}
+static void sculpt_pose_do_bend_deform(SculptSession *ss, Brush *UNUSED(brush))
+{
+ const int totvert = SCULPT_vertex_count_get(ss);
+ SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain;
+
+ if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
+ sub_v3_v3v3(ik_chain->bend_mat[0],
+ ik_chain->segments[0].initial_head,
+ ik_chain->segments[0].initial_orig);
+ normalize_v3(ik_chain->bend_mat[0]);
+ copy_v3_v3(ik_chain->bend_mat[2], ss->cache->view_normal);
+ normalize_v3(ik_chain->bend_mat[2]);
+ cross_v3_v3v3(ik_chain->bend_mat[1], ik_chain->bend_mat[0], ik_chain->bend_mat[2]);
+ normalize_v3(ik_chain->bend_mat[1]);
+ copy_v3_v3(ik_chain->bend_mat[3], ik_chain->segments[0].initial_orig);
+ ik_chain->bend_mat[3][3] = 1.0f;
+ invert_m4_m4(ik_chain->bend_mat_inv, ik_chain->bend_mat);
+
+ float lower = FLT_MAX;
+ float upper = -FLT_MAX;
+
+ float smd_limit[2];
+
+ for (int i = 0; i < totvert; i++) {
+ if (ik_chain->segments[0].weights[i] == 0.0f) {
+ continue;
+ }
+ float bend_space_vert_co[3];
+ mul_v3_m4v3(bend_space_vert_co, ik_chain->bend_mat_inv, SCULPT_vertex_co_get(ss, i));
+ lower = min_ff(lower, bend_space_vert_co[0]);
+ upper = max_ff(upper, bend_space_vert_co[0]);
+ }
+
+ ik_chain->bend_upper_limit = upper;
+ smd_limit[1] = lower + (upper - lower) * 1.0f;
+ smd_limit[0] = lower + (upper - lower) * 0.0f;
+ ik_chain->bend_limit = max_ff(FLT_EPSILON, smd_limit[1] - smd_limit[0]);
+ }
+
+ float *original_dir = ik_chain->bend_mat[0];
+ float current_dir[3];
+ float brush_location[3];
+ add_v3_v3v3(brush_location, ss->cache->initial_location, ss->cache->grab_delta);
+ sub_v3_v3v3(current_dir, brush_location, ik_chain->segments[0].initial_orig);
+ ik_chain->bend_factor = angle_signed_on_axis_v3v3_v3(
+ original_dir, current_dir, ss->cache->view_normal);
+ if (ik_chain->bend_factor > M_PI) {
+ ik_chain->bend_factor = ik_chain->bend_factor - (M_PI * 2.0f);
+ }
+
+ ik_chain->bend_factor = 2.0f * (ik_chain->bend_factor / ik_chain->bend_limit);
+}
+
static void sculpt_pose_align_pivot_local_space(float r_mat[4][4],
ePaintSymmetryFlags symm,
ePaintSymmetryAreas symm_area,
@@ -1159,6 +1283,9 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
case BRUSH_POSE_DEFORM_SQUASH_STRETCH:
sculpt_pose_do_squash_stretch_deform(ss, brush);
break;
+ case BRUSH_POSE_DEFORM_BEND:
+ sculpt_pose_do_bend_deform(ss, brush);
+ break;
}
/* Flip the segment chain in all symmetry axis and calculate the transform matrices for each
@@ -1229,7 +1356,13 @@ void SCULPT_do_pose_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
TaskParallelSettings settings;
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings);
+
+ if (brush->pose_deform_type == BRUSH_POSE_DEFORM_BEND) {
+ BLI_task_parallel_range(0, totnode, &data, do_pose_brush_bend_task_cb_ex, &settings);
+ }
+ else {
+ BLI_task_parallel_range(0, totnode, &data, do_pose_brush_task_cb_ex, &settings);
+ }
}
void SCULPT_pose_ik_chain_free(SculptPoseIKChain *ik_chain)
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index e64a5bc4ea7..9db37306af2 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -252,6 +252,7 @@ typedef enum eBrushPoseDeformType {
BRUSH_POSE_DEFORM_ROTATE_TWIST = 0,
BRUSH_POSE_DEFORM_SCALE_TRASLATE = 1,
BRUSH_POSE_DEFORM_SQUASH_STRETCH = 2,
+ BRUSH_POSE_DEFORM_BEND = 3,
} eBrushPoseDeformType;
typedef enum eBrushPoseOriginType {
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 5f414aa2bdd..f6372a0c240 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -630,7 +630,7 @@ enum {
*/
#define BA_TRANSFORM_LOCKED_IN_PLACE (1 << 7)
-#define BA_TRANSFORM_CHILD (1 << 8) /* child of a transformed object */
+#define BA_TRANSFORM_CHILD (1 << 8) /* child of a transformed object */
#define BA_TRANSFORM_PARENT (1 << 13) /* parent of a transformed object */
#define OB_FROMDUPLI (1 << 9)
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 90444e7f4ce..165f3f342d7 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2197,6 +2197,7 @@ static void rna_def_brush(BlenderRNA *brna)
{BRUSH_POSE_DEFORM_ROTATE_TWIST, "ROTATE_TWIST", 0, "Rotate/Twist", ""},
{BRUSH_POSE_DEFORM_SCALE_TRASLATE, "SCALE_TRANSLATE", 0, "Scale/Translate", ""},
{BRUSH_POSE_DEFORM_SQUASH_STRETCH, "SQUASH_STRETCH", 0, "Squash & Stretch", ""},
+ {BRUSH_POSE_DEFORM_BEND, "BEND", 0, "Bend", ""},
{0, NULL, 0, NULL, NULL},
};
More information about the Bf-blender-cvs
mailing list