[Bf-blender-cvs] [cf003b5e30e] sculpt-dev: Sculpt: improve accuracy of tri in brush test for dyntopo

Joseph Eagar noreply at git.blender.org
Sat Oct 9 01:19:55 CEST 2021


Commit: cf003b5e30e7e1ae6054ef5de0a55172bf3c5ad0
Author: Joseph Eagar
Date:   Fri Oct 8 16:19:33 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBcf003b5e30e7e1ae6054ef5de0a55172bf3c5ad0

Sculpt: improve accuracy of tri in brush
        test for dyntopo

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

M	source/blender/blenkernel/intern/brush_engine_presets.c
M	source/blender/blenkernel/intern/dyntopo.c
M	source/blender/editors/sculpt_paint/sculpt.c

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

diff --git a/source/blender/blenkernel/intern/brush_engine_presets.c b/source/blender/blenkernel/intern/brush_engine_presets.c
index 2ad013e5c40..ea2e3d64dfe 100644
--- a/source/blender/blenkernel/intern/brush_engine_presets.c
+++ b/source/blender/blenkernel/intern/brush_engine_presets.c
@@ -1739,6 +1739,8 @@ void BKE_brush_builtin_create(Brush *brush, int tool)
       break;
     case SCULPT_TOOL_DRAW_FACE_SETS:
       BRUSHSET_SET_FLOAT(chset, strength, 0.5f);
+      BRUSHSET_LOOKUP(chset, radius)->flag &= ~BRUSH_CHANNEL_INHERIT;
+      BRUSHSET_LOOKUP(chset, strength)->flag &= ~BRUSH_CHANNEL_INHERIT;
       BRUSHSET_LOOKUP(chset, strength)->mappings[BRUSH_MAPPING_PRESSURE].flag &=
           ~BRUSH_MAPPING_ENABLED;
       BRUSHSET_SET_BOOL(chset, use_space_attenuation, false);
diff --git a/source/blender/blenkernel/intern/dyntopo.c b/source/blender/blenkernel/intern/dyntopo.c
index 8818299ea33..5163568cdf8 100644
--- a/source/blender/blenkernel/intern/dyntopo.c
+++ b/source/blender/blenkernel/intern/dyntopo.c
@@ -1363,7 +1363,7 @@ typedef struct EdgeQueue {
   float limit_len;
 #endif
 
-  bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMFace *f);
+  bool (*edge_queue_tri_in_range)(const struct EdgeQueue *q, BMVert *vs[3], float no[3]);
   bool (*edge_queue_vert_in_range)(const struct EdgeQueue *q, BMVert *v);
 
   const float *view_normal;
@@ -1535,10 +1535,106 @@ static bool edge_queue_vert_in_sphere(const EdgeQueue *q, BMVert *v)
   Profiling revealed the accurate distance to tri in blenlib was too slow,
   so we use a simpler version here
   */
+/* reduce script
+
+on factor;
+off period;
+
+load_package "avector";
+
+comment: origin at p;
+
+p := avec(0, 0, 0);
+n :=- avec(nx, ny, nz);
+v1 := avec(v1x, v1y, v1z);
+v2 := avec(v2x, v2y, v2z);
+v3 := avec(v3x, v3y, v3z);
+
+comment: -((p - v1) dot n);simplified to this;
+fac := v1 dot n;
+
+co := fac*n;
+
+a := co - v1;
+b := co - v2;
+c := co - v3;
+
+a := v1;
+b := v2;
+c := v3;
+
+t1 := a cross b;
+t2 := b cross c;
+t3 := c cross a;
+
+on fort;
+w1 := t1 dot n;
+w2 := t2 dot n;
+w3 := t3 dot n;
+off fort;
+
+inside := sign(a dot n) + sign(b dot n) + sign(c dot n);
+
+
+*/
+static float point_in_tri_v3(float p[3], float v1[3], float v2[3], float v3[3], float n[3])
+{
+  float t1[3], t2[3], t3[3];
+  sub_v3_v3v3(t1, v1, p);
+  sub_v3_v3v3(t2, v2, p);
+  sub_v3_v3v3(t3, v3, p);
+
+  float c1[3], c2[3], c3[3];
+  cross_v3_v3v3(c1, t1, t2);
+  cross_v3_v3v3(c2, t2, t3);
+  cross_v3_v3v3(c3, t3, t1);
+
+  bool w1 = dot_v3v3(c1, n) >= 0.0f;
+  bool w2 = dot_v3v3(c2, n) >= 0.0f;
+  bool w3 = dot_v3v3(c3, n) >= 0.0f;
+
+  return w1 == w2 && w2 == w3;
+
+#if 0
+  const float nx = n[0], ny = n[1], nz = n[2];
+
+  float v1x = v1[0] - p[0], v1y = v1[1] - p[1], v1z = v1[2] - p[2];
+  float v2x = v2[0] - p[0], v2y = v2[1] - p[1], v2z = v2[2] - p[2];
+  float v3x = v3[0] - p[0], v3y = v3[1] - p[1], v3z = v3[2] - p[2];
+
+  const float w1 = -(nx * v1y * v2z - nx * v1z * v2y - ny * v1x * v2z + ny * v1z * v2x +
+                     nz * v1x * v2y - nz * v1y * v2x);
+  const float w2 = -(nx * v2y * v3z - nx * v2z * v3y - ny * v2x * v3z + ny * v2z * v3x +
+                     nz * v2x * v3y - nz * v2y * v3x);
+  const float w3 = nx * v1y * v3z - nx * v1z * v3y - ny * v1x * v3z + ny * v1z * v3x +
+                   nz * v1x * v3y - nz * v1y * v3x;
+  return !((w1 >= 0.0f) && (w2 >= 0.0f) && (w3 >= 0.0f));
+#endif
+}
+
 static float dist_to_tri_sphere_simple(
     float p[3], float v1[3], float v2[3], float v3[3], float n[3])
 {
   float co[3];
+  float t1[3], t2[3], t3[3];
+
+  if (dot_v3v3(n, n) == 0.0f) {
+    normal_tri_v3(n, v1, v2, v3);
+  }
+
+  if (point_in_tri_v3(p, v1, v2, v3, n)) {
+    sub_v3_v3v3(co, p, v2);
+
+    float dist = dot_v3v3(co, n);
+    return dist * dist;
+  }
+
+  sub_v3_v3v3(co, p, v1);
+  madd_v3_v3fl(co, n, -dot_v3v3(n, co));
+
+  sub_v3_v3v3(t1, v1, co);
+  sub_v3_v3v3(t2, v2, co);
+  sub_v3_v3v3(t3, v3, co);
 
   float dis = len_squared_v3v3(p, v1);
   dis = fmin(dis, len_squared_v3v3(p, v2));
@@ -1587,10 +1683,8 @@ static bool bm_elem_is_free(BMElem *elem, int htype)
   return ret;
 }
 
-static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
+static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMVert *vs[3], float no[3])
 {
-  BMLoop *l = f->l_first;
-
 #if 0
   float cent[3];
 
@@ -1605,11 +1699,8 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
 
   /* Check if triangle intersects the sphere */
 #if 1
-  float dis = dist_to_tri_sphere_simple((float *)q->center,
-                                        (float *)l->v->co,
-                                        (float *)l->next->v->co,
-                                        (float *)l->prev->v->co,
-                                        (float *)f->no);
+  float dis = dist_to_tri_sphere_simple(
+      (float *)q->center, (float *)vs[0]->co, (float *)vs[1]->co, (float *)vs[2]->co, (float *)no);
 #else
   float dis = len_squared_v3v3(q->center, l->v->co);
 #endif
@@ -1617,15 +1708,11 @@ static bool edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
   return dis <= q->radius_squared;
 }
 
-static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMFace *f)
+static bool edge_queue_tri_in_circle(const EdgeQueue *q, BMVert *v_tri[3], float no[3])
 {
-  BMVert *v_tri[3];
   float c[3];
   float tri_proj[3][3];
 
-  /* Get closest point in triangle to sphere center */
-  BM_face_as_array_vert_tri(f, v_tri);
-
   project_plane_normalized_v3_v3v3(tri_proj[0], v_tri[0]->co, q->view_normal);
   project_plane_normalized_v3_v3v3(tri_proj[1], v_tri[1]->co, q->view_normal);
   project_plane_normalized_v3_v3v3(tri_proj[2], v_tri[2]->co, q->view_normal);
@@ -1811,7 +1898,9 @@ static void long_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f, bool i
   }
 #endif
 
-  if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
+  BMVert *vs[3] = {f->l_first->v, f->l_first->next->v, f->l_first->next->next->v};
+
+  if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, vs, f->no)) {
     /* Check each edge of the face */
     BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
     BMLoop *l_iter = l_first;
@@ -1848,7 +1937,9 @@ static void short_edge_queue_face_add(EdgeQueueContext *eq_ctx, BMFace *f)
   }
 #endif
 
-  if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
+  BMVert *vs[3] = {f->l_first->v, f->l_first->next->v, f->l_first->next->next->v};
+
+  if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, vs, f->no)) {
     BMLoop *l_iter;
     BMLoop *l_first;
 
@@ -2009,6 +2100,10 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
   const int cd_sculpt_vert = tdata->pbvh->cd_sculpt_vert;
   bool do_smooth = eq_ctx->surface_smooth_fac > 0.0f;
 
+  BKE_pbvh_bmesh_check_tris(tdata->pbvh, node);
+
+  const char facetag = BM_ELEM_TAG_ALT;
+
 #if 1
 #  if 0
   // try to be nice to branch predictor
@@ -2024,6 +2119,8 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
   TGSET_ITER (f, node->bm_faces) {
     BMLoop *l = f->l_first;
 
+    f->head.hflag &= ~facetag;
+
 #  if 0
     if ((stepi++) & 3) {
       continue;
@@ -2041,7 +2138,15 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
   TGSET_ITER_END
 #endif
 
-  TGSET_ITER (f, node->bm_faces) {
+  PBVHTriBuf *tribuf = node->tribuf;
+  for (int i = 0; i < node->tribuf->tottri; i++) {
+    PBVHTri *tri = node->tribuf->tris + i;
+    BMFace *f = (BMFace *)tri->f.i;
+
+    if (f->head.hflag & facetag) {
+      continue;
+    }
+
 #ifdef USE_EDGEQUEUE_FRONTFACE
     if (eq_ctx->q->use_view_normal) {
       if (dot_v3v3(f->no, eq_ctx->q->view_normal) < 0.0f) {
@@ -2050,7 +2155,12 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
     }
 #endif
 
-    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
+    BMVert *vs[3] = {(BMVert *)tribuf->verts[tri->v[0]].i,
+                     (BMVert *)tribuf->verts[tri->v[1]].i,
+                     (BMVert *)tribuf->verts[tri->v[2]].i};
+    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, vs, f->no)) {
+      f->head.hflag |= facetag;
+
       /* Check each edge of the face */
       BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
       BMLoop *l_iter = l_first;
@@ -2094,7 +2204,6 @@ static void long_edge_queue_task_cb(void *__restrict userdata,
       } while ((l_iter = l_iter->next) != l_first);
     }
   }
-  TGSET_ITER_END
 
   BLI_rng_free(rng);
   BLI_array_free(faces);
@@ -2145,7 +2254,8 @@ static void short_edge_queue_task_cb(void *__restrict userdata,
     }
 #endif
 
-    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
+    BMVert *vs[3] = {f->l_first->v, f->l_first->next->v, f->l_first->next->next->v};
+    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, vs, f->no)) {
       /* Check each edge of the face */
       BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
       BMLoop *l_iter = l_first;
@@ -2188,7 +2298,8 @@ static void short_edge_queue_task_cb_local(void *__restrict userdata,
     }
 #endif
 
-    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, f)) {
+    BMVert *vs[3] = {f->l_first->v, f->l_first->next->v, f->l_first->next->next->v};
+    if (eq_ctx->q->edge_queue_tri_in_range(eq_ctx->q, vs, f->no)) {
       BMLoop *l = f->l_first;
 
       do {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 0e86caadb50..41793243d9c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -5347,6 +5347,8 @@ static void do_draw_sharp_brush_task_cb_ex_plane(void *__restrict userdata,
   copy_v3_v3(noffset, offset);
   normalize_v3(noffset);
 
+  const float bstrength = fabsf(ss->cache->bstrength);
+
   BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) {
     // SCULPT_orig_vert_data_update(&orig_data, vd.vertex);
     SCULPT_vertex_check_origdata(ss, vd.vertex);
@@ -5356,21 +5358,22 @@ static void do_draw_sharp_brush_task_cb_ex_plane(void *__restrict userdata,
       continue;
     }
     /* Offset vertex. */
-    const float fade = SCULPT_brush_strength_factor(ss,
-                                                    brush,
-                                                    mv->origco,
-   

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list