[Bf-blender-cvs] [309cd047ef4] master: Sculpt: Transform tool

Pablo Dobarro noreply at git.blender.org
Wed Sep 11 13:06:16 CEST 2019


Commit: 309cd047ef46fcbd21b26b2509b40c55c5dab61e
Author: Pablo Dobarro
Date:   Tue Sep 10 19:55:15 2019 +0200
Branches: master
https://developer.blender.org/rB309cd047ef46fcbd21b26b2509b40c55c5dab61e

Sculpt: Transform tool

The sculpt mode transform tool applies the sculpt pivot transformation to all vertices, taking XYZ symmetry into account.
This commit also includes an operator to set the pivot point initial position.

Reviewed By: brecht

Differential Revision: https://developer.blender.org/D5717

===================================================================

M	release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/editors/include/ED_sculpt.h
M	source/blender/editors/include/ED_transform.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_undo.c
M	source/blender/editors/transform/CMakeLists.txt
M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform_convert.c
M	source/blender/editors/transform/transform_convert.h
A	source/blender/editors/transform/transform_convert_sculpt.c
M	source/blender/editors/transform/transform_generics.c
M	source/blender/editors/transform/transform_gizmo_3d.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 8ec2733ff34..de05a357211 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -1986,6 +1986,11 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             None,
             _defs_sculpt.mesh_filter,
             None,
+            _defs_transform.translate,
+            _defs_transform.rotate,
+            _defs_transform.scale,
+            _defs_transform.transform,
+            None,
             *_tools_annotate,
         ],
         'PAINT_TEXTURE': [
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index ed4bcee3541..5ce16e8b906 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -267,12 +267,19 @@ typedef struct SculptSession {
   float cursor_view_normal[3];
   struct RegionView3D *rv3d;
 
-  float pivot_pos[3];
-
   /* Dynamic mesh preview */
   int *preview_vert_index_list;
   int preview_vert_index_count;
 
+  /* Transform operator */
+  float pivot_pos[3];
+  float pivot_rot[4];
+  float pivot_scale[3];
+
+  float init_pivot_pos[3];
+  float init_pivot_rot[4];
+  float init_pivot_scale[3];
+
   union {
     struct {
       struct SculptVertexPaintGeomMap gmap;
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index d907ba4e581..0273c8c73ab 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -39,6 +39,11 @@ bool ED_sculpt_mask_box_select(struct bContext *C,
                                const struct rcti *rect,
                                bool select);
 
+/* transform */
+void ED_sculpt_update_modal_transform(struct bContext *C);
+void ED_sculpt_init_transform(struct bContext *C);
+void ED_sculpt_end_transform(struct bContext *C);
+
 /* sculpt_undo.c */
 void ED_sculpt_undosys_type(struct UndoType *ut);
 
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index d8b65aa5975..8c70fc9a157 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -94,6 +94,7 @@ enum TfmMode {
 #define CTX_OBMODE_XFORM_OBDATA (1 << 11)
 /** Transform object parents without moving their children. */
 #define CTX_OBMODE_XFORM_SKIP_CHILDREN (1 << 12)
+#define CTX_SCULPT (1 << 13)
 
 /* Standalone call to get the transformation center corresponding to the current situation
  * returns 1 if successful, 0 otherwise (usually means there's no selection)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 44927a3052b..6235b60ea74 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -8737,7 +8737,8 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *
       for (int i = 0; i < vertex_count; i++) {
         if (sculpt_vertex_mask_get(ss, i) < (0.5f + threshold) &&
             sculpt_vertex_mask_get(ss, i) > (0.5f - threshold) &&
-            check_vertex_pivot_symmetry(sculpt_vertex_co_get(ss, i), ss->pivot_pos, symm)) {
+            check_vertex_pivot_symmetry(
+                sculpt_vertex_co_get(ss, i), ss->filter_cache->mask_expand_initial_co, symm)) {
           total++;
           add_v3_v3(avg, sculpt_vertex_co_get(ss, i));
         }
@@ -8859,6 +8860,9 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent
   ss->filter_cache->mask_update_current_it = 1;
   ss->filter_cache->mask_update_it[(int)sculpt_active_vertex_get(ss)] = 1;
 
+  copy_v3_v3(ss->filter_cache->mask_expand_initial_co,
+             sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)));
+
   char *visited_vertices = MEM_callocN(vertex_count * sizeof(char), "visited vertices");
 
   sculpt_vertex_normal_get(ss, sculpt_active_vertex_get(ss), original_normal);
@@ -9074,6 +9078,364 @@ void sculpt_geometry_preview_lines_update(bContext *C, SculptSession *ss, float
 
   ss->preview_vert_index_count = totpoints;
 }
+void ED_sculpt_init_transform(struct bContext *C)
+{
+  Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+  Object *ob = CTX_data_active_object(C);
+  SculptSession *ss = ob->sculpt;
+  Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+
+  copy_v3_v3(ss->init_pivot_pos, ss->pivot_pos);
+  copy_v4_v4(ss->init_pivot_rot, ss->pivot_rot);
+
+  ss->init_pivot_scale[0] = 1.0f;
+  ss->init_pivot_scale[1] = 1.0f;
+  ss->init_pivot_scale[2] = 1.0f;
+
+  ss->pivot_scale[0] = 1.0f;
+  ss->pivot_scale[1] = 1.0f;
+  ss->pivot_scale[2] = 1.0f;
+
+  sculpt_undo_push_begin("Transform");
+  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+
+  ss->pivot_rot[3] = 1.0f;
+
+  sculpt_vertex_random_access_init(ss);
+  sculpt_filter_cache_init(ob, sd);
+}
+
+typedef enum PaintSymmetryAreas {
+  AREA_SYMM_X = (1 << 0),
+  AREA_SYMM_Y = (1 << 1),
+  AREA_SYMM_Z = (1 << 2),
+} PaintSymmetryAreas;
+
+static char sculpt_get_vertex_symm_area(float co[3])
+{
+  float vco[3];
+  char symm_area = 0;
+  copy_v3_v3(vco, co);
+  if (vco[0] < 0) {
+    symm_area |= AREA_SYMM_X;
+  }
+  if (vco[1] < 0) {
+    symm_area |= AREA_SYMM_Y;
+  }
+  if (vco[2] < 0) {
+    symm_area |= AREA_SYMM_Z;
+  }
+  return symm_area;
+}
+
+static void flip_qt(float qt[4], char symm)
+{
+  float euler[3];
+  if (symm & PAINT_SYMM_X) {
+    quat_to_eul(euler, qt);
+    euler[1] = -euler[1];
+    euler[2] = -euler[2];
+    eul_to_quat(qt, euler);
+  }
+  if (symm & PAINT_SYMM_Y) {
+    quat_to_eul(euler, qt);
+    euler[0] = -euler[0];
+    euler[2] = -euler[2];
+    eul_to_quat(qt, euler);
+  }
+  if (symm & PAINT_SYMM_Z) {
+    quat_to_eul(euler, qt);
+    euler[0] = -euler[0];
+    euler[1] = -euler[1];
+    eul_to_quat(qt, euler);
+  }
+}
+
+static void sculpt_flip_transform_by_symm_area(
+    float disp[3], float rot[4], char symm, char symmarea, float pivot[3])
+{
+
+  for (char i = 0; i < 3; i++) {
+    char symm_it = 1 << i;
+    if (symm & symm_it) {
+      if (symmarea & symm_it) {
+        if (disp) {
+          flip_v3(disp, symm_it);
+        }
+        if (rot) {
+          flip_qt(rot, symm_it);
+        }
+      }
+      if (pivot[0] < 0) {
+        if (disp) {
+          flip_v3(disp, symm_it);
+        }
+        if (rot) {
+          flip_qt(rot, symm_it);
+        }
+      }
+    }
+  }
+}
+
+static void sculpt_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];
+
+  SculptOrigVertData orig_data;
+  sculpt_orig_vert_data_init(&orig_data, data->ob, data->nodes[i]);
+
+  PBVHVertexIter vd;
+
+  sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_ALL)
+  {
+    sculpt_orig_vert_data_update(&orig_data, &vd);
+    float transformed_co[3], orig_co[3], disp[3];
+    float fade = vd.mask ? *vd.mask : 0.0f;
+    copy_v3_v3(orig_co, orig_data.co);
+    char symm_area = sculpt_get_vertex_symm_area(orig_co);
+
+    copy_v3_v3(transformed_co, orig_co);
+    mul_m4_v3(data->transform_mats[(int)symm_area], transformed_co);
+    sub_v3_v3v3(disp, transformed_co, orig_co);
+    mul_v3_fl(disp, 1.0f - fade);
+
+    add_v3_v3v3(vd.co, orig_co, disp);
+
+    if (vd.mvert) {
+      vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+
+  BKE_pbvh_node_mark_redraw(node);
+  BKE_pbvh_node_mark_normals_update(node);
+}
+
+void ED_sculpt_update_modal_transform(struct bContext *C)
+{
+  Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+  Object *ob = CTX_data_active_object(C);
+  SculptSession *ss = ob->sculpt;
+  Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+  const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+
+  sculpt_vertex_random_access_init(ss);
+  BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false);
+
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .nodes = ss->filter_cache->nodes,
+  };
+
+  float final_pivot_pos[3], d_t[3], d_r[4];
+  float t_mat[4][4], r_mat[4][4], s_mat[4][4], pivot_mat[4][4], pivot_imat[4][4],
+      transform_mat[4][4];
+
+  copy_v3_v3(final_pivot_pos, ss->pivot_pos);
+  for (int i = 0; i < 8; i++) {
+    copy_v3_v3(final_pivot_pos, ss->pivot_pos);
+
+    unit_m4(pivot_mat);
+
+    unit_m4(t_mat);
+    unit_m4(r_mat);
+    unit_m4(s_mat);
+
+    /* Translation matrix */
+    sub_v3_v3v3(d_t, ss->pivot_pos, ss->init_pivot_pos);
+    sculpt_flip_transform_by_symm_area(d_t, NULL, symm, (char)i, ss->init_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, ss->init_pivot_rot);
+    normalize_qt(d_r);
+    sculpt_flip_transform_by_symm_area(NULL, d_r, symm, (char)i, ss->init_pivot_pos);
+    quat_to_mat4(r_mat, d_r);
+
+    /* Scale matrix */
+    size_to_mat4(s_mat, ss->pivot_scale);
+
+    /* Pivot matrix */
+    sculpt_flip_transform_by_symm_area(final_pivot_pos, NULL, symm, (char)i, ss->init_pivot_pos);
+    translate_m4(pivot_mat, final_pivot_pos[0], final_pivot_pos[1], final_pivot_pos[2]);
+    invert_m4_m4(pivot_imat, pivot_mat);
+
+    /* Final transform matrix */
+    mul_m4_m4m4(transform_mat, r_mat, t_mat);
+    mul_m4_m4m4(transform_mat, transform_mat, s_mat);
+    mul_m4_m4m4(data.transform_mats[i], transform_mat, pivot_imat);
+    mul_m4_m4m4(data.transform_mats[i], pivot_mat, data.transform_mats[i]);
+  }
+
+  TaskParallelSettings settings;
+  BLI_parallel_range_settings_defaults(&settings);
+  settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) &&
+                            ss->filter_cache->totnode > SCULPT_THREADED_LIMIT);
+  BLI_task_parallel_range(
+      0, ss->filter_cache->totnode, &data, sculpt_transform_task_cb, &settings);
+
+  if (ss->modifiers_active || ss->kb) {
+    scul

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list