[Bf-blender-cvs] [5775efba2f3] sculpt-dev: Sculpt: Elastic Transform
Pablo Dobarro
noreply at git.blender.org
Wed Dec 16 21:36:53 CET 2020
Commit: 5775efba2f32afa0d2f79b6890caeb35c24ad48f
Author: Pablo Dobarro
Date: Tue Dec 15 21:38:07 2020 +0100
Branches: sculpt-dev
https://developer.blender.org/rB5775efba2f32afa0d2f79b6890caeb35c24ad48f
Sculpt: Elastic Transform
===================================================================
M release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_transform.c
M source/blender/makesdna/DNA_scene_types.h
M source/blender/makesrna/intern/rna_sculpt_paint.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 507a9d0c036..c107f67dd29 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -266,9 +266,15 @@ class _defs_annotate:
class _defs_transform:
+ def draw_transform_sculpt_tool_settings(context, layout):
+ if context.mode != 'SCULPT':
+ return
+ layout.prop(context.tool_settings.sculpt, "transform_mode")
+
@ToolDef.from_fn
def translate():
def draw_settings(context, layout, _tool):
+ _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
return dict(
idname="builtin.move",
@@ -284,6 +290,7 @@ class _defs_transform:
@ToolDef.from_fn
def rotate():
def draw_settings(context, layout, _tool):
+ _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 2)
return dict(
idname="builtin.rotate",
@@ -299,6 +306,7 @@ class _defs_transform:
@ToolDef.from_fn
def scale():
def draw_settings(context, layout, _tool):
+ _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 3)
return dict(
idname="builtin.scale",
@@ -354,6 +362,7 @@ class _defs_transform:
props = tool.gizmo_group_properties("VIEW3D_GGT_xform_gizmo")
layout.prop(props, "drag_action")
+ _defs_transform.draw_transform_sculpt_tool_settings(context, layout)
_template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
return dict(
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 37ac2015992..70779882dc5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -6177,15 +6177,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata,
SculptSession *ss = data->ob->sculpt;
Sculpt *sd = data->sd;
Object *ob = data->ob;
-
- /* These brushes start from original coordinates. */
- const bool use_orco = ELEM(data->brush->sculpt_tool,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_THUMB,
- SCULPT_TOOL_ELASTIC_DEFORM,
- SCULPT_TOOL_BOUNDARY,
- SCULPT_TOOL_POSE);
+ const bool use_orco = data->use_proxies_orco;
PBVHVertexIter vd;
PBVHProxyNode *proxies;
@@ -6240,11 +6232,20 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
/* First line is tools that don't support proxies. */
if (ss->cache->supports_gravity || (sculpt_tool_is_proxy_used(brush->sculpt_tool) == false)) {
+ const bool use_orco = ELEM(brush->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_ELASTIC_DEFORM,
+ SCULPT_TOOL_BOUNDARY,
+ SCULPT_TOOL_POSE);
+
SculptThreadedTaskData data = {
.sd = sd,
.ob = ob,
.brush = brush,
.nodes = nodes,
+ .use_proxies_orco = use_orco,
};
TaskParallelSettings settings;
@@ -6255,6 +6256,27 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
MEM_SAFE_FREE(nodes);
}
+void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVHNode **nodes;
+ int totnode;
+
+ BKE_pbvh_gather_proxies(ss->pbvh, &nodes, &totnode);
+ SculptThreadedTaskData data = {
+ .sd = sd,
+ .ob = ob,
+ .nodes = nodes,
+ .use_proxies_orco = false,
+ };
+
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, totnode);
+ BLI_task_parallel_range(0, totnode, &data, sculpt_combine_proxies_task_cb, &settings);
+
+ MEM_SAFE_FREE(nodes);
+}
+
/**
* Copy the modified vertices from the #PBVH to the active key.
*/
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index b0a208446ad..df722bf0617 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -706,6 +706,10 @@ typedef struct SculptThreadedTaskData {
float (*mat)[4];
float (*vertCos)[3];
+ /* When true, the displacement stored in the proxies will be aplied to the original coordinates
+ * instead of to the current coordinates. */
+ bool use_proxies_orco;
+
/* X and Z vectors aligned to the stroke direction for operations where perpendicular vectors to
* the stroke direction are needed. */
float (*stroke_xz)[3];
@@ -749,6 +753,9 @@ typedef struct SculptThreadedTaskData {
bool mask_expand_create_face_set;
float transform_mats[8][4][4];
+ float elastic_transform_mat[4][4];
+ float elastic_transform_pivot[3];
+ float elastic_transform_radius;
/* Boundary brush */
float boundary_deform_strength;
@@ -833,6 +840,8 @@ bool SCULPT_brush_test_circle_sq(SculptBrushTest *test, const float co[3]);
bool SCULPT_search_sphere_cb(PBVHNode *node, void *data_v);
bool SCULPT_search_circle_cb(PBVHNode *node, void *data_v);
+void SCULPT_combine_transform_proxies(Sculpt *sd, Object *ob);
+
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss,
SculptBrushTest *test,
char falloff_shape);
diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c
index f74d59e1987..4b7639bdeb3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_transform.c
+++ b/source/blender/editors/sculpt_paint/sculpt_transform.c
@@ -32,6 +32,7 @@
#include "BKE_brush.h"
#include "BKE_context.h"
+#include "BKE_kelvinlet.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_object.h"
@@ -83,7 +84,12 @@ void ED_sculpt_init_transform(struct bContext *C)
SCULPT_vertex_random_access_ensure(ss);
SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS);
- ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_ORIGINAL;
+ if (sd->transform_mode == SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC) {
+ ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL;
+ }
+ else {
+ ss->filter_cache->transform_displacement_mode = SCULPT_TRANSFORM_DISPLACEMENT_ORIGINAL;
+ }
}
static void sculpt_transform_matrices_init(SculptSession *ss,
@@ -123,13 +129,13 @@ static void sculpt_transform_matrices_init(SculptSession *ss,
/* Translation matrix. */
sub_v3_v3v3(d_t, ss->pivot_pos, start_pivot_pos);
- SCULPT_flip_v3_by_symm_area(d_t, symm, v_symm, ss->init_pivot_pos);
+ SCULPT_flip_v3_by_symm_area(d_t, symm, v_symm, start_pivot_pos);
translate_m4(t_mat, d_t[0], d_t[1], d_t[2]);
/* Rotation matrix. */
sub_qt_qtqt(d_r, ss->pivot_rot, start_pivot_rot);
normalize_qt(d_r);
- SCULPT_flip_quat_by_symm_area(d_r, symm, v_symm, ss->init_pivot_pos);
+ SCULPT_flip_quat_by_symm_area(d_r, symm, v_symm, start_pivot_pos);
quat_to_mat4(r_mat, d_r);
/* Scale matrix. */
@@ -220,6 +226,94 @@ static void sculpt_transform_all_vertices(Sculpt *sd, Object *ob)
0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings);
}
+static void sculpt_elastic_transform_task_cb(void *__restrict userdata,
+ const int i,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+ PBVHNode *node = data->nodes[i];
+
+ float(*proxy)[3] = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[i])->co;
+
+ SculptOrigVertData orig_data;
+ SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i]);
+
+ KelvinletParams params;
+ /* TODO(pablodp606): These parameters can be exposed if needed as transform strength and volume
+ * preservation like in the elastic deform brushes. Setting them to the same default as elastic
+ * deform triscale grab because they work well in most cases. */
+ const float force = 1.0f;
+ const float shear_modulus = 1.0f;
+ const float poisson_ratio = 0.4f;
+ BKE_kelvinlet_init_params(
+ ¶ms, data->elastic_transform_radius, force, shear_modulus, poisson_ratio);
+
+ SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+ {
+ SCULPT_orig_vert_data_update(&orig_data, &vd);
+ float transformed_co[3], orig_co[3], disp[3];
+ const float fade = vd.mask ? *vd.mask : 0.0f;
+ copy_v3_v3(orig_co, orig_data.co);
+
+ copy_v3_v3(transformed_co, vd.co);
+ mul_m4_v3(data->elastic_transform_mat, transformed_co);
+ sub_v3_v3v3(disp, transformed_co, vd.co);
+
+ float final_disp[3];
+ BKE_kelvinlet_grab_triscale(final_disp, ¶ms, vd.co, data->elastic_transform_pivot, disp);
+ mul_v3_fl(final_disp, 20.0f * (1.0f - fade));
+
+ copy_v3_v3(proxy[vd.i], final_disp);
+
+ if (vd.mvert) {
+ vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+
+ BKE_pbvh_node_mark_update(node);
+}
+
+static void sculpt_transform_radius_elastic(Sculpt *sd, Object *ob, const float transform_radius)
+{
+ BLI_assert(ss->filter_cache->transform_displacement_mode ==
+ SCULPT_TRANSFORM_DISPLACEMENT_INCREMENTAL);
+
+ SculptSession *ss = ob->sculpt;
+ const char symm = SCULPT_mesh_sy
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list