diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2020-08-10 18:57:01 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2020-08-10 19:04:00 +0300 |
commit | ed9c0464bae66411384c216ba3f34f65658e0f68 (patch) | |
tree | b0a5004801180bbf67ae220f92932d007397671f /source/blender/editors/sculpt_paint/sculpt.c | |
parent | 71639cc8627fb26e50233b9bb942776a950b6ab1 (diff) |
Sculpt: Boundary Brush
This brush includes a set of deformation modes designed to deform and
control the shape of the mesh boundaries, which are really hard to do
with regular sculpt brushes (and even in edit mode). This is useful
for creating cloth assets and hard surface base meshes.
The brush detects the mesh boundary closest to the active vertex and
propagates the deformation using the brush falloff into the mesh.
It includes bend, expand, inflate, grab and twist deform modes.
The main use cases of this brush are the Bend and Expand deformation
modes, which depend on a grid topology to create the best results.
In order to do further adjustments and tweaks to the result of these
deformation modes, the brush also includes the Inflate, Grab and
Twist deformation modes, which do not depend that much on the topology.
Grab and Inflate are the same operation that is implemented in the
Grab and Inflate tools, they are also available in the boundary brush
as producing deformations with regular brushes in these areas is very
hard to control.
Even if this brush can produce deformations in triangle meshes and
meshes with a non-regular quad grid, the more regular and clean the
topology is, the better. Most of the assets this brush is intended to
deform are always created from a cylindrical or plane quad grid, so it
should be fine. Also, its algorithms can be improved in future versions
to handle more corner cases and topology patterns.
Reviewed By: sergey
Differential Revision: https://developer.blender.org/D8356
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d0b834a3dc0..c87189997f2 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1126,6 +1126,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool) SCULPT_TOOL_DRAW_SHARP, SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_SMOOTH, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE); } @@ -1135,6 +1136,7 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool) SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_CLOTH, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR, @@ -2338,6 +2340,7 @@ static float brush_strength(const Sculpt *sd, case SCULPT_TOOL_ELASTIC_DEFORM: case SCULPT_TOOL_POSE: + case SCULPT_TOOL_BOUNDARY: return root_alpha * feather; default: @@ -5510,7 +5513,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe /* Pose needs all nodes because it applies all symmetry iterations at the same time and the IK * chain can grow to any area of the model. */ /* This can be optimized by filtering the nodes after calculating the chain. */ - if (ELEM(brush->sculpt_tool, SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_POSE)) { + if (ELEM(brush->sculpt_tool, + SCULPT_TOOL_ELASTIC_DEFORM, + SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY)) { BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { @@ -5690,6 +5696,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe case SCULPT_TOOL_SLIDE_RELAX: do_slide_relax_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_BOUNDARY: + SCULPT_do_boundary_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_CLOTH: SCULPT_do_cloth_brush(sd, ob, nodes, totnode); break; @@ -5724,8 +5733,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe } /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */ - if (ss->cache->supports_gravity && - !ELEM(brush->sculpt_tool, SCULPT_TOOL_CLOTH, SCULPT_TOOL_DRAW_FACE_SETS)) { + if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool, + SCULPT_TOOL_CLOTH, + SCULPT_TOOL_DRAW_FACE_SETS, + SCULPT_TOOL_BOUNDARY)) { do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); } @@ -5777,6 +5788,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata, SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_ELASTIC_DEFORM, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE); PBVHVertexIter vd; @@ -6238,6 +6250,8 @@ static const char *sculpt_tool_name(Sculpt *sd) return "Multi-plane Scrape Brush"; case SCULPT_TOOL_SLIDE_RELAX: return "Slide/Relax Brush"; + case SCULPT_TOOL_BOUNDARY: + return "Boundary Brush"; case SCULPT_TOOL_CLOTH: return "Cloth Brush"; case SCULPT_TOOL_DRAW_FACE_SETS: @@ -6266,6 +6280,12 @@ void SCULPT_cache_free(StrokeCache *cache) SCULPT_pose_ik_chain_free(cache->pose_ik_chain); } + for (int i = 0; i < PAINT_SYMM_AREAS; i++) { + if (cache->bdata[i]) { + SCULPT_boundary_data_free(cache->bdata[i]); + } + } + if (cache->cloth_sim) { SCULPT_cloth_simulation_free(cache->cloth_sim); } @@ -6494,6 +6514,7 @@ static bool sculpt_needs_delta_from_anchored_origin(Brush *brush) return ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_THUMB, SCULPT_TOOL_ELASTIC_DEFORM) || SCULPT_is_cloth_deform_brush(brush); @@ -6537,6 +6558,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru SCULPT_TOOL_CLAY_THUMB, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_THUMB) || sculpt_brush_use_topology_rake(ss, brush)) { float grab_location[3], imat[4][4], delta[3], loc[3]; @@ -6825,6 +6847,7 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd, (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) || ((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) || (brush->sculpt_tool == SCULPT_TOOL_POSE) || + (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) || (brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) || (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) || (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS)); |