[Bf-blender-cvs] [46839d1f438] sculpt-dev: sculpt-dev: Roll mapping

Joseph Eagar noreply at git.blender.org
Fri Oct 21 00:21:19 CEST 2022


Commit: 46839d1f4386f3639caaef6d6c00e9503c9ca396
Author: Joseph Eagar
Date:   Thu Oct 20 15:19:54 2022 -0700
Branches: sculpt-dev
https://developer.blender.org/rB46839d1f4386f3639caaef6d6c00e9503c9ca396

sculpt-dev: Roll mapping

* Fixed errors in second derivative of stroke spline
* Fix error on surfaces at an oblique angle to the viewport
* Fix roll mapping not working for sculpt texture paint

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

M	source/blender/blenkernel/BKE_brush_engine.h
M	source/blender/blenlib/BLI_arc_spline.hh
M	source/blender/editors/sculpt_paint/paint_intern.h
M	source/blender/editors/sculpt_paint/paint_stroke.cc
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_paint_color.c

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

diff --git a/source/blender/blenkernel/BKE_brush_engine.h b/source/blender/blenkernel/BKE_brush_engine.h
index 6c3a3384deb..93be0de672f 100644
--- a/source/blender/blenkernel/BKE_brush_engine.h
+++ b/source/blender/blenkernel/BKE_brush_engine.h
@@ -207,6 +207,7 @@ typedef struct BrushCommand {
   struct BrushChannelSet *params_mapped; /* with pressure etc applied */
 
   BrushTex *texture_slots[MAKE_BRUSHTEX_SLOTS]; /* currently unused */
+  float initial_radius;
 } BrushCommand;
 
 typedef struct BrushCommandList {
diff --git a/source/blender/blenlib/BLI_arc_spline.hh b/source/blender/blenlib/BLI_arc_spline.hh
index 8f88c281b5c..9c7078a4970 100644
--- a/source/blender/blenlib/BLI_arc_spline.hh
+++ b/source/blender/blenlib/BLI_arc_spline.hh
@@ -10,6 +10,8 @@
 #include <cstdio>
 #include <utility>
 
+//#define FINITE_DIFF
+
 /*
  * Arc length parameterized spline library.
  */
@@ -263,7 +265,7 @@ template<typename Float, int axes = 2, int table_size = 512> class CubicBezier {
 #endif
   }
 
-  Vector evaluate(Float s)
+  inline Vector evaluate(Float s)
   {
     Float t = arc_to_t(s);
     Vector r;
@@ -298,13 +300,31 @@ template<typename Float, int axes = 2, int table_size = 512> class CubicBezier {
 
   Vector derivative2(Float s)
   {
+#ifdef FINITE_DIFF
+    const Float df = 0.0005;
+    Float s1, s2;
+
+    if (s >= 1.0 - df) {
+      s1 = s - df;
+      s2 = s;
+    }
+    else {
+      s1 = s;
+      s2 = s + df;
+    }
+
+    Vector a = derivative(s1);
+    Vector b = derivative(s2);
+
+    return (b - a) / df;
+#else
     Float t = arc_to_t(s);
     Vector r;
 
     Float dx = dcubic(ps[0][0], ps[1][0], ps[2][0], ps[3][0], t);
-    Float d2x = dcubic(ps[0][0], ps[1][0], ps[2][0], ps[3][0], t);
+    Float d2x = d2cubic(ps[0][0], ps[1][0], ps[2][0], ps[3][0], t);
     Float dy = dcubic(ps[0][1], ps[1][1], ps[2][1], ps[3][1], t);
-    Float d2y = dcubic(ps[0][1], ps[1][1], ps[2][1], ps[3][1], t);
+    Float d2y = d2cubic(ps[0][1], ps[1][1], ps[2][1], ps[3][1], t);
 
     /*
     comment: arc length second derivative;
@@ -344,7 +364,7 @@ template<typename Float, int axes = 2, int table_size = 512> class CubicBezier {
       r[0] = ((d2x * dy - d2y * dx) * dy) / div;
       r[1] = (-(d2x * dy - d2y * dx) * dx) / div;
     }
-    else if (constexpr(axes == 3)) {
+    else if constexpr (axes == 3) {
       Float dz = dcubic(ps[0][2], ps[1][2], ps[2][2], ps[3][2], t);
       Float d2z = d2cubic(ps[0][2], ps[1][2], ps[2][2], ps[3][2], t);
 
@@ -361,6 +381,7 @@ template<typename Float, int axes = 2, int table_size = 512> class CubicBezier {
     }
 
     return r;
+#endif
   }
 
   Float curvature(Float s)
@@ -510,12 +531,8 @@ template<typename Float, int axes = 2> class BezierSpline {
     }
   }
 
-  Vector evaluate(Float s)
+  inline Vector evaluate(Float s)
   {
-    if (segments.size() == 0) {
-      return Vector();
-    }
-
     if (s == 0.0) {
       return segments[0].bezier.ps[0];
     }
@@ -565,8 +582,16 @@ template<typename Float, int axes = 2> class BezierSpline {
     return seg->bezier.curvature(s - seg->start);
   }
 
+  /* Find the closest point on the spline.  Uses a bisecting root finding approach.
+   * Note: in thoery we could split the spline into quadratic segments and solve
+   * for the closest point directy.
+   */
   Vector closest_point(const Vector p, Float &r_s, Vector &r_tan, Float &r_dis)
   {
+    if (segments.size() == 0) {
+      return Vector();
+    }
+
     const int steps = 5;
     Float s = 0.0, ds = length / steps;
     Float mindis = FLT_MAX;
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 871d7de0f84..8fbf2ff1804 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -128,7 +128,8 @@ typedef struct PaintStroke {
   /* space distance covered so far */
   int stroke_sample_index;
   float stroke_distance;
-  float stroke_distance_t;  // divided by brush radius
+  float stroke_distance_t;     /* Divided by brush radius. */
+  float stroke_distance_world; /* Created by .world_spline. */
 
   /* Set whether any stroke step has yet occurred
    * e.g. in sculpt mode, stroke doesn't start until cursor
@@ -656,8 +657,11 @@ void paint_project_spline(struct bContext *C,
                           struct StrokeCache *cache,
                           struct PaintStroke *stroke);
 ;
-void paint_calc_cubic_uv_v3(
-    PaintStroke *stroke, struct StrokeCache *cache, const float co[3], float r_out[3], float r_tan[3]);
+void paint_calc_cubic_uv_v3(PaintStroke *stroke,
+                            struct StrokeCache *cache,
+                            const float co[3],
+                            float r_out[3],
+                            float r_tan[3]);
 float paint_stroke_spline_length(PaintStroke *stroke);
 
 #ifdef __cplusplus
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.cc b/source/blender/editors/sculpt_paint/paint_stroke.cc
index f4043d6ea8f..388140903ce 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.cc
+++ b/source/blender/editors/sculpt_paint/paint_stroke.cc
@@ -112,7 +112,7 @@ static void paint_brush_cubic_vis(const bContext *C, ARegion *region, void *user
   immVertex3fv(pos, ss->cache->world_cubic[3]);
   immEnd();
 
-  const int steps = 256;
+  int steps = 256;
   float t = 0.0f, dt = 1.0f / (float)(steps - 1);
 
   immUniformColor4ub(45, 75, 255, 255);
@@ -145,8 +145,43 @@ static void paint_brush_cubic_vis(const bContext *C, ARegion *region, void *user
   }
   immEnd();
 
-  immUniformColor4ub(0, 255, 25, 55);
+#  if 1
+
+  s = 0.0f;
+  ds = 0.1f;
+  steps = (int)floorf(stroke->world_spline->length / ds + 0.5f);
+
+  immUniformColor4ub(255, 0, 0, 170);
+  immBegin(GPU_PRIM_POINTS, steps);
+  for (int i = 0; i < steps; i++, s += ds) {
+    float3 co = stroke->world_spline->evaluate(s);
+    mul_v3_m4v3(co, ob->obmat, co);
+
+    immVertex3fv(pos, co);
+  }
+
+  immEnd();
+
+  s = 0.0f;
+  immUniformColor4ub(255, 0, 0, 170);
+  immBegin(GPU_PRIM_LINES, steps * 2);
+  for (int i = 0; i < steps; i++, s += ds) {
+    float3 co = stroke->world_spline->evaluate(s);
+    float3 dv2 = stroke->world_spline->derivative2(s);
+
+    mul_v3_m4v3(co, ob->obmat, co);
+
+    immVertex3fv(pos, co);
+
+    co += dv2;
+    immVertex3fv(pos, co);
+  }
 
+  immEnd();
+
+#  endif
+
+  immUniformColor4ub(0, 255, 25, 55);
   for (int is_points = 0; is_points < 2; is_points++) {
     immBegin(is_points ? GPU_PRIM_POINTS : GPU_PRIM_LINE_STRIP, stroke->num_points);
     for (int i = 0; i < stroke->num_points; i++) {
@@ -366,10 +401,37 @@ static void paint_stroke_add_point(const Paint *paint,
   }
 }
 
-static void paint_brush_make_cubic(PaintStroke *stroke)
+static void paint_project_cubic(bContext *C,
+                                PaintStroke *stroke,
+                                blender::CubicBezier<float, 2> &bezier2d,
+                                blender::CubicBezier<float, 3> &bezier3d)
+{
+  Object *ob = CTX_data_active_object(C);
+  float2 mvals[4];
+
+  for (int i = 0; i < 4; i++) {
+    for (int j = 0; j < 2; j++) {
+      mvals[i][j] = bezier2d.ps[i][j];
+    }
+  }
+
+  for (int i = 0; i < 4; i++) {
+    if (!SCULPT_stroke_get_location(C, bezier3d.ps[i], mvals[i], true)) {
+      ED_view3d_win_to_3d(CTX_wm_view3d(C),
+                          CTX_wm_region(C),
+                          stroke->last_world_space_position,
+                          mvals[i],
+                          bezier3d.ps[i]);
+    }
+  }
+
+  bezier3d.update();
+}
+
+static void paint_brush_make_cubic(bContext *C, PaintStroke *stroke)
 {
   float a[2], b[2], c[2], d[2];
-  int count = paint_stroke_max_points(NULL, stroke);
+  int count = paint_stroke_max_points(nullptr, stroke);
 
   if (stroke->num_points < 4) {
     return;
@@ -432,13 +494,25 @@ static void paint_brush_make_cubic(PaintStroke *stroke)
   bez.update();
   stroke->spline->add(bez);
 
+  blender::CubicBezier<float, 3> bez3d;
+  paint_project_cubic(C, stroke, bez, bez3d);
+  bez3d.update();
+
+  stroke->world_spline->add(bez3d);
+
   while (stroke->spline->segments.size() > paint_stroke_max_points(nullptr, stroke) + 1) {
     stroke->spline->pop_front();
   }
+
+  while (stroke->world_spline->segments.size() > paint_stroke_max_points(nullptr, stroke) + 1) {
+    stroke->stroke_distance_world += stroke->world_spline->segments[0].bezier.length;
+    stroke->world_spline->pop_front();
+  }
 }
 
 void paint_project_spline(bContext *C, StrokeCache *cache, PaintStroke *stroke)
 {
+  return;
   Object *ob = CTX_data_active_object(C);
 
   stroke->world_spline->clear();
@@ -488,6 +562,8 @@ void paint_calc_cubic_uv_v3(
   if (dot_v3v3(vec2, cache->view_normal) < 0.0f) {
     r_out[0] = -r_out[0];
   }
+
+  r_out[1] += stroke->stroke_distance_world;
 }
 
 float paint_stroke_spline_length(struct PaintStroke *stroke)
@@ -881,7 +957,7 @@ static void paint_brush_stroke_add_step(
                              stroke->x_tilt,
                              stroke->y_tilt);
       if (stroke->has_cubic_stroke) {
-        paint_brush_make_cubic(stroke);
+        paint_brush_make_cubic(C, stroke);
       }
     }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 44f71677573..6276000b207 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4130,20 +4130,12 @@ float SCULPT_brush_strength_factor(SculptSession *ss,
       // calc_cubic_uv_v3(ss->cache->world_cubic, SCULPT_vertex_co_get(ss, vertex), point_3d);
       float tan[3], curv[3];
 
-      paint_calc_cubic_uv_v3(
-          ss->cache->stroke, ss->cache, SCULPT_vertex_co_get(ss, vertex), point_3d, tan);
-
-      /* Calc global distance. */
-      float t1 = ss->cache->last_stroke_distance_t;
-      float t2 = point_3d[1] / ss->cache->radius;
-
-      point_3d[1] = t1 + t2;
-      point_3d[1] *= ss->cache->radius;
+      paint_calc_cubic_uv_v3(ss->cache->stroke, ss->cache, brush_point, point_3d, tan);
 
 #if 0
       if (SCULPT_has_colors(ss)) {
         float color[4] = {point_3d[0], point_3d[1], 0.0f, 1.0f};
-        mul_v3_fl(color, 0.25f 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list