[Bf-blender-cvs] [08c0e2a35d0] sculpt-mode-features: Sculpt mode transform tool: Initial implementation

Pablo Dobarro noreply at git.blender.org
Sun May 19 18:11:27 CEST 2019


Commit: 08c0e2a35d0159d8d771a24be1c452b0e700e4a3
Author: Pablo Dobarro
Date:   Sun May 19 18:10:41 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB08c0e2a35d0159d8d771a24be1c452b0e700e4a3

Sculpt mode transform tool: Initial implementation

Work in progress...
- Scaling and orientations are not implemented yet.
- The "move pivot only" option is ignored when the tool is used from the
gizmo.
- Only meshes, no multires or dyntopo.

This commit also includes the operator to set the pivot point position
automatically as well as a refactor of the mesh filter cache to be shared
with the transform tool.

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

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/CMakeLists.txt
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/transform.c
M	source/blender/editors/transform/transform_conversions.c
M	source/blender/editors/transform/transform_generics.c
M	source/blender/editors/transform/transform_gizmo_3d.c
M	source/blender/editors/transform/transform_ops.c

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

diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
index 7f85bc4b50a..63850a63ad4 100644
--- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py
@@ -966,6 +966,25 @@ class _defs_sculpt:
             draw_settings=draw_settings,
         )
 
+    @ToolDef.from_fn
+    def translate():
+        def draw_settings(context, layout, tool):
+            _template_widget.VIEW3D_GGT_xform_gizmo.draw_settings_with_index(context, layout, 1)
+            props = tool.operator_properties("transform.translate")
+            sub = layout.row()
+            sub.prop(props, "move_pivot_only")
+        return dict(
+            idname="builtin.move",
+            label="Move",
+            # cursor='SCROLL_XY',
+            icon="ops.transform.translate",
+            widget="VIEW3D_GGT_xform_gizmo",
+            operator="transform.translate",
+            keymap="3D View Tool: Move",
+            draw_settings=draw_settings,
+        )
+
+
 
 class _defs_vertex_paint:
 
@@ -1868,6 +1887,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
             _defs_sculpt.hide_border,
             _defs_sculpt.mask_border,
             _defs_sculpt.mesh_filter,
+            _defs_sculpt.translate,
+            _defs_transform.rotate,
             *_tools_annotate,
             None,
         ],
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index a492158c50e..7d8fd1f8beb 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -264,18 +264,25 @@ typedef struct SculptSession {
   float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
 
   struct StrokeCache *cache;
+  struct FilterCache *filter_cache;
 
   float cursor_radius;
   float cursor_location[3];
   float cursor_view_normal[3];
   float cursor_normal[3];
 
-  float (*orco)[3];
-
   /* Automasking active vertex */
   MVert *active_vertex_mesh;
   int active_vertex_mesh_index;
 
+  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];
+
   RegionView3D *rv3d;
 
   union {
diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h
index 86e108a26c6..7c72e06c791 100644
--- a/source/blender/editors/include/ED_sculpt.h
+++ b/source/blender/editors/include/ED_sculpt.h
@@ -42,6 +42,11 @@ bool ED_sculpt_mask_box_select(struct bContext *C,
                                const struct rcti *rect,
                                bool select);
 
+/* transform */
+void ED_sculpt_update_modal_transform(const struct bContext *C, bool transform_pivot_only);
+void ED_sculpt_init_transform(const struct bContext *C, bool transform_pivot_only);
+void ED_sculpt_end_transform(const struct bContext *C, bool transform_pivot_only);
+
 /* 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 3605a245187..1931ad8d39d 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -97,6 +97,8 @@ enum TfmMode {
 #define CTX_PAINT_CURVE (1 << 8)
 #define CTX_GPENCIL_STROKES (1 << 9)
 #define CTX_CURSOR (1 << 10)
+#define CTX_SCULPT (1 << 11)
+#define CTX_SCULPT_PIVOT (1 << 12)
 
 /* Standalone call to get the transformation center corresponding to the current situation
  * returns 1 if successful, 0 otherwise (usually means there's no selection)
@@ -158,6 +160,7 @@ int BIF_countTransformOrientation(const struct bContext *C);
 #define P_GPENCIL_EDIT (1 << 13)
 #define P_CURSOR_EDIT (1 << 14)
 #define P_CLNOR_INVALIDATE (1 << 15)
+#define P_SCULPT_EDIT (1 << 16)
 
 void Transform_Properties(struct wmOperatorType *ot, int flags);
 
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 23617e687ea..eb63dcb312c 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -18,6 +18,7 @@
 set(INC
   ../include
   ../uvedit
+  ../transform
   ../../blenkernel
   ../../blenlib
   ../../blentranslation
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index d7c389967da..415201ec9f5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2386,7 +2386,7 @@ static void relax_vertex(float final_dp[3], PBVHVertexIter vd, SculptSession *ss
       MVert *c_vert = &ss->mvert[vin];
       float connected_vert_co[3];
       if (use_ss_orco) {
-        copy_v3_v3(connected_vert_co, ss->orco[vin]);
+        copy_v3_v3(connected_vert_co, ss->filter_cache->orco[vin]);
       }
       else {
         copy_v3_v3(connected_vert_co, c_vert->co);
@@ -2410,7 +2410,7 @@ static void relax_vertex(float final_dp[3], PBVHVertexIter vd, SculptSession *ss
       float connected_vert_co[3];
       float connected_vert_disp[3];
       if (use_ss_orco) {
-        copy_v3_v3(connected_vert_co, ss->orco[vin]);
+        copy_v3_v3(connected_vert_co, ss->filter_cache->orco[vin]);
       }
       else {
         copy_v3_v3(connected_vert_co, c_vert->co);
@@ -7027,6 +7027,16 @@ static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
   else {
     ob->sculpt->vcol = CustomData_get_layer(&me->vdata, CD_MVERTCOL);
   }
+
+  /* init sculpt pivot */
+  zero_v3(ob->sculpt->pivot_pos);
+  zero_v4(ob->sculpt->pivot_rot);
+  ob->sculpt->pivot_rot[3] = 1.0f;
+
+  zero_v3(ob->sculpt->init_pivot_pos);
+  zero_v4(ob->sculpt->init_pivot_rot);
+  ob->sculpt->init_pivot_rot[3] = 1.0f;
+
   BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false);
 }
 
@@ -7545,6 +7555,124 @@ static void SCULPT_OT_set_detail_size(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+#define MESH_FILTER_RANDOM_MOD 50
+
+static void filter_cache_init_task_cb(void *__restrict userdata,
+                                      const int i,
+                                      const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  PBVHNode *node = data->nodes[i];
+
+  PBVHVertexIter vd;
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
+  {
+    int vi = vd.vert_indices[vd.i];
+    if (vd.mask && (*vd.mask) < 1.0f) {
+      data->node_mask[i] = 1;
+    }
+    copy_v3_v3(ss->filter_cache->orco[vi], ss->mvert[vi].co);
+    if (data->filter_type && vi < MESH_FILTER_RANDOM_MOD) {
+      data->random_disp[vi % MESH_FILTER_RANDOM_MOD] = (float)rand() / (float)(RAND_MAX);
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+
+  if (data->node_mask[i] == 1) {
+    sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS);
+  }
+}
+
+static void sculpt_filter_cache_init(Object *ob, Sculpt *sd, bool init_random)
+{
+  SculptSession *ss = ob->sculpt;
+  PBVH *pbvh = ob->sculpt->pbvh;
+  PBVHNode **nodes;
+  int totnode;
+
+  ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache");
+  ss->filter_cache->orco = MEM_mallocN(3 * ss->totvert * sizeof(float), "orco");
+  if (init_random) {
+    ss->filter_cache->random_disp = MEM_mallocN(MESH_FILTER_RANDOM_MOD * sizeof(float),
+                                                "random_disp");
+  }
+
+  SculptSearchSphereData searchdata = {
+      .ss = ss,
+      .sd = sd,
+      .radius_squared = FLT_MAX,
+  };
+  BKE_pbvh_search_gather(pbvh, sculpt_search_sphere_cb, &searchdata, &nodes, &totnode);
+
+  int *node_mask = MEM_callocN(totnode * sizeof(int), "node mask");
+  for (int i = 0; i < totnode; i++) {
+    node_mask[i] = 0;
+  }
+
+  int filter_type;
+  if (init_random) {
+    filter_type = 1;
+  }
+  else {
+    filter_type = 0;
+  }
+
+  SculptThreadedTaskData data = {
+      .sd = sd,
+      .ob = ob,
+      .nodes = nodes,
+      .filter_type = filter_type,
+      .random_disp = ss->filter_cache->random_disp,
+      .node_mask = node_mask,
+  };
+
+  ParallelRangeSettings settings;
+  BLI_parallel_range_settings_defaults(&settings);
+  settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
+  BLI_task_parallel_range(0, totnode, &data, filter_cache_init_task_cb, &settings);
+
+  int tot_active_nodes = 0;
+  int active_node_index = 0;
+  PBVHNode **active_nodes;
+
+  for (int i = 0; i < totnode; i++) {
+    if (node_mask[i] == 1) {
+      tot_active_nodes++;
+    }
+  }
+
+  active_nodes = MEM_callocN(tot_active_nodes * sizeof(PBVHNode *), "active nodes");
+
+  for (int i = 0; i < totnode; i++) {
+    if (node_mask[i] == 1) {
+      active_nodes[active_node_index] = nodes[i];
+      active_node_index++;
+    }
+  }
+
+  ss->filter_cache->nodes = active_nodes;
+  ss->filter_cache->totnode = tot_active_nodes;
+
+  if (nodes) {
+    MEM_freeN(nodes);
+  }
+
+  if (node_mask) {
+    MEM_freeN(node_mask);
+  }
+}
+
+static void sculpt_filter_cache_free(SculptSession *ss)
+{
+  MEM_freeN(ss->filter_cache->orco);
+  MEM_freeN(ss->filter_cache->nodes);
+  if (ss->filter_cache->random_disp) {
+    MEM_freeN(ss->filter_cache->random_disp);
+  }
+  MEM_freeN(ss->filter_cache);
+}
+
 typedef enum eSculptMeshFilterTypes {
   MESH_FILTER_SMOOTH = 0,
   MESH_FILTER_GROW = 1,
@@ -7566,14 +7694,6 @@ EnumPropertyItem prop_mesh_filter_types[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
-typedef struct MeshFilterData {
-  float *random_disp;
-  PBVHNode **nodes;
-  int totnode;
-} MeshFilterData;
-
-#define MESH_FILTER_RANDOM_MOD 50
-
 static void mesh_filter_task_cb(void *__restrict userdata,
                                 const int i,
                                 const ParallelRangeTLS *__restrict UNUSED(tls))
@@ -7591,7 +7711,7 @@ static void mesh_filter_task_cb(void *__restrict userdata,
     float fade = vd.mask ? *vd.mask : 1.0f;
     fade = 1 - fade;
     fade *= data->filter_strength;
-    copy_v3_v3(orig_co, ss->orco[vd.vert_indices[vd.i]]);
+    copy_v3_v3(orig_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list