diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2020-06-23 17:10:47 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2020-06-30 18:43:37 +0300 |
commit | 438bd823714a24475962ab89ad38b0d7e36349fe (patch) | |
tree | c8abded5be18609bbad57f561efc01990dc35fdf /source/blender/editors/sculpt_paint/sculpt_pose.c | |
parent | 6ac235a6f75b71ec3d37dabc2e86b032e07c868e (diff) |
Sculpt: Pose Brush option to affect loose parts
This option allows posing meshes with different disconnected elements
using the Pose Brush.
This is achieved by doing the following:
- Creating an ID per vertex that stores the connected component of that vertex.
- By using those IDs, one fake topology connection is created per vertex to the nearest vertex in a different ID. The maximum distance to create that connection is determined by the "Max Element Distance" property. These fake connectivity neighbors are used in the Sculpt API functions iterators, so all the algorithms of the Pose Brush can run without modifications as if everything was part of the same mesh.
In order to make this work, the "Connected only" property of the Pose Brush needs to be disabled. This will add an extra performance cost to the Pose Brush and its preview. To achieve optimal results, max element distance should be as low as possible.
Reviewed By: sergey, campbellbarton
Differential Revision: https://developer.blender.org/D7282
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt_pose.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_pose.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index 0acf90cd1df..c9e2b7318d6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -937,18 +937,32 @@ SculptPoseIKChain *SCULPT_pose_ik_chain_init(Sculpt *sd, const float initial_location[3], const float radius) { + SculptPoseIKChain *ik_chain = NULL; + + const bool use_fake_neighbors = !(br->flag2 & BRUSH_USE_CONNECTED_ONLY); + + if (use_fake_neighbors) { + SCULPT_fake_neighbors_ensure(sd, ob, br->disconnected_distance_max); + SCULPT_fake_neighbors_enable(ob); + } + switch (br->pose_origin_type) { case BRUSH_POSE_ORIGIN_TOPOLOGY: - return pose_ik_chain_init_topology(sd, ob, ss, br, initial_location, radius); + ik_chain = pose_ik_chain_init_topology(sd, ob, ss, br, initial_location, radius); break; case BRUSH_POSE_ORIGIN_FACE_SETS: - return pose_ik_chain_init_face_sets(sd, ob, ss, br, radius); + ik_chain = pose_ik_chain_init_face_sets(sd, ob, ss, br, radius); break; case BRUSH_POSE_ORIGIN_FACE_SETS_FK: return pose_ik_chain_init_face_sets_fk(sd, ob, ss, radius, initial_location); break; } - return NULL; + + if (use_fake_neighbors) { + SCULPT_fake_neighbors_disable(ob); + } + + return ik_chain; } void SCULPT_pose_brush_init(Sculpt *sd, Object *ob, SculptSession *ss, Brush *br) |