Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py5
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c55
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h32
-rw-r--r--source/blender/makesdna/DNA_brush_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_brush.c19
5 files changed, 100 insertions, 21 deletions
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 3075d76d6fa..1ae1826b609 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -643,6 +643,11 @@ def brush_settings(layout, context, brush, popover=False):
layout.prop(brush, "elastic_deform_volume_preservation", slider=True)
layout.separator()
+ elif sculpt_tool == 'SNAKE_HOOK':
+ layout.separator()
+ layout.prop(brush, "snake_hook_deform_type")
+ layout.separator()
+
elif sculpt_tool == 'POSE':
layout.separator()
layout.prop(brush, "deform_target")
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index b9427677745..fd7ec1da497 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4232,6 +4232,8 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
(len_v3(grab_delta) / ss->cache->radius)) :
0.0f;
+ const bool do_elastic = brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC;
+
proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
SculptBrushTest test;
@@ -4239,18 +4241,28 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
ss, &test, data->brush->falloff_shape);
const int thread_id = BLI_task_parallel_thread_id(tls);
+ KelvinletParams params;
+ BKE_kelvinlet_init_params(&params, ss->cache->radius, bstrength, 1.0f, 0.4f);
+
BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
{
- if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const float fade = bstrength * SCULPT_brush_strength_factor(ss,
- brush,
- vd.co,
- sqrtf(test.dist),
- vd.no,
- vd.fno,
- vd.mask ? *vd.mask : 0.0f,
- vd.index,
- thread_id);
+ if (do_elastic || sculpt_brush_test_sq_fn(&test, vd.co)) {
+
+ float fade;
+ if (do_elastic) {
+ fade = 1.0f;
+ }
+ else {
+ fade = bstrength * SCULPT_brush_strength_factor(ss,
+ brush,
+ vd.co,
+ sqrtf(test.dist),
+ vd.no,
+ vd.fno,
+ vd.mask ? *vd.mask : 0.0f,
+ vd.index,
+ thread_id);
+ }
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -4289,6 +4301,17 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
add_v3_v3(proxy[vd.i], delta_rotate);
}
+ if (do_elastic) {
+ float disp[3];
+ BKE_kelvinlet_grab_triscale(disp, &params, vd.co, ss->cache->location, proxy[vd.i]);
+ mul_v3_fl(disp, bstrength * 20.0f);
+ if (vd.mask) {
+ mul_v3_fl(disp, 1.0f - *vd.mask);
+ }
+ mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index));
+ copy_v3_v3(proxy[vd.i], disp);
+ }
+
if (vd.mvert) {
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
}
@@ -5714,16 +5737,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
/* Build a list of all nodes that are potentially within the brush's area of influence */
- /* These brushes need to update all nodes as they are not constrained by the brush radius */
- /* Elastic deform needs all nodes to avoid artifacts as the effect of the brush is not
- * constrained by the radius. */
- /* 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,
- SCULPT_TOOL_BOUNDARY)) {
+ if (SCULPT_tool_needs_all_pbvh_nodes(brush)) {
+ /* These brushes need to update all nodes as they are not constrained by the brush radius */
BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
}
else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index 99ee22328ea..3b48207f461 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -434,6 +434,38 @@ BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush)
brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM);
}
+BLI_INLINE bool SCULPT_tool_needs_all_pbvh_nodes(const Brush *brush)
+{
+ if (brush->sculpt_tool == SCULPT_TOOL_ELASTIC_DEFORM) {
+ /* Elastic deformations in any brush need all nodes to avoid artifacts as the effect
+ * of the Kelvinlet is not constrained by the radius. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_POSE) {
+ /* 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. */
+ /* TODO: This can be optimized by filtering the nodes after calculating the chain. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) {
+ /* Boundary needs all nodes because it is not possible to know where the boundary
+ * deformation is going to be propagated before calculating it. */
+ /* TODO: after calculating the boudnary info in the first iteration, it should be
+ * possible to get the nodes that have vertices included in any boundary deformation
+ * and cache them. */
+ return true;
+ }
+
+ if (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK &&
+ brush->snake_hook_deform_type == BRUSH_SNAKE_HOOK_DEFORM_ELASTIC) {
+ /* Snake hook in elastic deform type has same requirements as the elastic deform tool. */
+ return true;
+ }
+ return false;
+}
+
/* Pose Brush. */
void SCULPT_do_pose_brush(struct Sculpt *sd,
struct Object *ob,
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 50aac69da19..7bd3c7d0117 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -402,6 +402,11 @@ typedef enum eBrushBoundaryFalloffType {
BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT = 3,
} eBrushBoundaryFalloffType;
+typedef enum eBrushSnakeHookDeformType {
+ BRUSH_SNAKE_HOOK_DEFORM_FALLOFF = 0,
+ BRUSH_SNAKE_HOOK_DEFORM_ELASTIC = 1,
+} eBrushSnakeHookDeformType;
+
/* Gpencilsettings.Vertex_mode */
typedef enum eGp_Vertex_Mode {
/* Affect to Stroke only. */
@@ -573,7 +578,7 @@ typedef struct Brush {
char gpencil_sculpt_tool;
/** Active grease pencil weight tool. */
char gpencil_weight_tool;
- char _pad1[2];
+ char _pad1[6];
float autosmooth_factor;
@@ -607,6 +612,9 @@ typedef struct Brush {
int elastic_deform_type;
float elastic_deform_volume_preservation;
+ /* snake hook */
+ int snake_hook_deform_type;
+
/* pose */
int pose_deform_type;
float pose_offset;
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index cf36c1a3742..b5ce7976fd8 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2072,6 +2072,20 @@ static void rna_def_brush(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem brush_snake_hook_deform_type_items[] = {
+ {BRUSH_SNAKE_HOOK_DEFORM_FALLOFF,
+ "FALLOFF",
+ 0,
+ "Radius Falloff",
+ "Applies the brush falloff in the tip of the brush"},
+ {BRUSH_SNAKE_HOOK_DEFORM_ELASTIC,
+ "ELASTIC",
+ 0,
+ "Elastic",
+ "Modifies the entire mesh using elastic deform"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem brush_cloth_deform_type_items[] = {
{BRUSH_CLOTH_DEFORM_DRAG, "DRAG", 0, "Drag", ""},
{BRUSH_CLOTH_DEFORM_PUSH, "PUSH", 0, "Push", ""},
@@ -2309,6 +2323,11 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "snake_hook_deform_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, brush_snake_hook_deform_type_items);
+ RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "cloth_deform_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, brush_cloth_deform_type_items);
RNA_def_property_ui_text(prop, "Deformation", "Deformation type that is used in the brush");