[Bf-blender-cvs] [23cf808585b] sculpt-dev: Sculpt: Boundary circle deformation mode

Pablo Dobarro noreply at git.blender.org
Sun Feb 7 17:50:15 CET 2021


Commit: 23cf808585b34bbaf03ee154b3ad20420c93a869
Author: Pablo Dobarro
Date:   Sun Feb 7 17:42:51 2021 +0100
Branches: sculpt-dev
https://developer.blender.org/rB23cf808585b34bbaf03ee154b3ad20420c93a869

Sculpt: Boundary circle deformation mode

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/editors/sculpt_paint/sculpt_boundary.c
M	source/blender/makesdna/DNA_brush_enums.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e04b4634bf6..534d46a22fb 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -432,6 +432,12 @@ typedef struct SculptBoundary {
     float rotation_axis[3];
     float pivot_position[3];
   } twist;
+
+  /* Cicrle Deform type. */
+  struct {
+    float (*origin)[3];
+    float *radius;
+  } circle;
 } SculptBoundary;
 
 typedef struct SculptFakeNeighbors {
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index 982342679e3..84e24caa59b 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -537,6 +537,8 @@ void SCULPT_boundary_data_free(SculptBoundary *boundary)
   MEM_SAFE_FREE(boundary->bend.pivot_positions);
   MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis);
   MEM_SAFE_FREE(boundary->slide.directions);
+  MEM_SAFE_FREE(boundary->circle.origin);
+  MEM_SAFE_FREE(boundary->circle.radius);
   MEM_SAFE_FREE(boundary);
 }
 
@@ -622,6 +624,45 @@ static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *b
   MEM_freeN(poly_verts);
 }
 
+static void sculpt_boundary_circle_data_init(SculptSession *ss, SculptBoundary *boundary)
+{
+
+  const int totvert = SCULPT_vertex_count_get(ss);
+  const int totcircles = boundary->max_propagation_steps + 1;
+
+  boundary->circle.radius = MEM_calloc_arrayN(totcircles, sizeof(float), "radius");
+  boundary->circle.origin = MEM_calloc_arrayN(totcircles, sizeof(float) * 3, "origin");
+
+  int *count = MEM_calloc_arrayN(totcircles, sizeof(int), "count");
+  for (int i = 0; i < totvert; i++) {
+    const int propagation_step_index = boundary->edit_info[i].num_propagation_steps;
+    if (propagation_step_index == -1) {
+      continue;
+    }
+    add_v3_v3(boundary->circle.origin[propagation_step_index], SCULPT_vertex_co_get(ss, i));
+    count[propagation_step_index]++;
+  }
+
+  for (int i = 0; i < totcircles; i++) {
+    mul_v3_fl(boundary->circle.origin[i], 1.0f / count[i]);
+  }
+
+  for (int i = 0; i < totvert; i++) {
+    const int propagation_step_index = boundary->edit_info[i].num_propagation_steps;
+    if (propagation_step_index == -1) {
+      continue;
+    }
+    boundary->circle.radius[propagation_step_index] += len_v3v3(
+        boundary->circle.origin[propagation_step_index], SCULPT_vertex_co_get(ss, i));
+  }
+
+  for (int i = 0; i < totcircles; i++) {
+    boundary->circle.radius[i] *= 1.0f / count[i];
+  }
+
+  MEM_freeN(count);
+}
+
 static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss,
                                                               SculptBoundary *boundary)
 {
@@ -931,6 +972,61 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata,
   BKE_pbvh_vertex_iter_end;
 }
 
+static void do_boundary_brush_circle_task_cb_ex(void *__restrict userdata,
+                                                const int n,
+                                                const TaskParallelTLS *__restrict UNUSED(tls))
+{
+  SculptThreadedTaskData *data = userdata;
+  SculptSession *ss = data->ob->sculpt;
+  const int symmetry_pass = ss->cache->mirror_symmetry_pass;
+  const SculptBoundary *boundary = ss->cache->boundaries[symmetry_pass];
+  const ePaintSymmetryFlags symm = SCULPT_mesh_symmetry_xyz_get(data->ob);
+  const Brush *brush = data->brush;
+
+  const float strength = ss->cache->bstrength;
+
+  PBVHVertexIter vd;
+  SculptOrigVertData orig_data;
+  SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+  BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+  {
+    if (boundary->edit_info[vd.index].num_propagation_steps == -1) {
+      continue;
+    }
+
+    SCULPT_orig_vert_data_update(&orig_data, &vd);
+    if (!SCULPT_check_vertex_pivot_symmetry(
+            orig_data.co, boundary->initial_vertex_position, symm)) {
+      continue;
+    }
+
+    const int propagation_steps = boundary->edit_info[vd.index].num_propagation_steps;
+    float *circle_origin = boundary->circle.origin[propagation_steps];
+    float circle_disp[3];
+    sub_v3_v3v3(circle_disp, circle_origin, orig_data.co);
+    normalize_v3(circle_disp);
+    mul_v3_fl(circle_disp, -boundary->circle.radius[propagation_steps]);
+    float target_circle_co[3];
+    add_v3_v3v3(target_circle_co, circle_origin, circle_disp);
+
+    float disp[3];
+    sub_v3_v3v3(disp, target_circle_co, vd.co);
+    float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd);
+    const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f;
+    const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index);
+    madd_v3_v3v3fl(target_co,
+                   vd.co,
+                   disp,
+                   boundary->edit_info[vd.index].strength_factor * mask * automask * strength);
+
+    if (vd.mvert) {
+      vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+    }
+  }
+  BKE_pbvh_vertex_iter_end;
+}
+
 /* Main Brush Function. */
 void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
 {
@@ -966,6 +1062,9 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
         case BRUSH_BOUNDARY_DEFORM_TWIST:
           sculpt_boundary_twist_data_init(ss, ss->cache->boundaries[symm_area]);
           break;
+        case BRUSH_BOUNDARY_DEFORM_CIRCLE:
+          sculpt_boundary_circle_data_init(ss, ss->cache->boundaries[symm_area]);
+          break;
         case BRUSH_BOUNDARY_DEFORM_INFLATE:
         case BRUSH_BOUNDARY_DEFORM_GRAB:
           /* Do nothing. These deform modes don't need any extra data to be precomputed. */
@@ -1011,6 +1110,9 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn
     case BRUSH_BOUNDARY_DEFORM_SMOOTH:
       BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_smooth_task_cb_ex, &settings);
       break;
+    case BRUSH_BOUNDARY_DEFORM_CIRCLE:
+      BLI_task_parallel_range(0, totnode, &data, do_boundary_brush_circle_task_cb_ex, &settings);
+      break;
   }
 }
 
diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h
index 20d5be6e5fb..12171597017 100644
--- a/source/blender/makesdna/DNA_brush_enums.h
+++ b/source/blender/makesdna/DNA_brush_enums.h
@@ -275,6 +275,7 @@ typedef enum eBrushBoundaryDeformType {
   BRUSH_BOUNDARY_DEFORM_GRAB = 3,
   BRUSH_BOUNDARY_DEFORM_TWIST = 4,
   BRUSH_BOUNDARY_DEFORM_SMOOTH = 5,
+  BRUSH_BOUNDARY_DEFORM_CIRCLE = 6,
 } eBrushBushBoundaryDeformType;
 
 typedef enum eBrushBoundaryFalloffType {
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 274edc9e48b..c091328d6f8 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -2220,6 +2220,7 @@ static void rna_def_brush(BlenderRNA *brna)
       {BRUSH_BOUNDARY_DEFORM_GRAB, "GRAB", 0, "Grab", ""},
       {BRUSH_BOUNDARY_DEFORM_TWIST, "TWIST", 0, "Twist", ""},
       {BRUSH_BOUNDARY_DEFORM_SMOOTH, "SMOOTH", 0, "Smooth", ""},
+      {BRUSH_BOUNDARY_DEFORM_CIRCLE, "CIRCLE", 0, "Circle", ""},
       {0, NULL, 0, NULL, NULL},
   };



More information about the Bf-blender-cvs mailing list