[Bf-blender-cvs] [e0c792135ad] master: Sculpt: New brush cursor, active vertex and normal radius

Pablo Dobarro noreply at git.blender.org
Fri Aug 30 16:46:55 CEST 2019


Commit: e0c792135adf8de3e6a54ddcbab53cab95b2b019
Author: Pablo Dobarro
Date:   Fri Aug 30 16:27:31 2019 +0200
Branches: master
https://developer.blender.org/rBe0c792135adf8de3e6a54ddcbab53cab95b2b019

Sculpt: New brush cursor, active vertex and normal radius

This commit includes the new brush cursor, active vertex updates and the normal radius brush property for all sculpt brushes.
  -The new brush cursor previews the real stroke radius over the mesh and the sampled sculpt normal.
  -The active vertex is used in sculpt tools and brushes as a starting point for an operation, similar to a preselection. It is also mirrored following the enabled symmetry options to preview the stroke symmetry.
  -The normal radius brush property limits the radius that is going to be used to sample the sculpt normal and area center. It controls how closely the cursor follows the surface and it improves the behavior of most brushes, making them suitable for hard surface sculpting.

Reviewed By: campbellbarton, brecht

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

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/brush.c
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/blenkernel/intern/pbvh_bmesh.c
M	source/blender/blenkernel/intern/pbvh_intern.h
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/editors/sculpt_paint/paint_cursor.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index a3c8f759f06..89d771b7026 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -364,6 +364,11 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
             if not self.is_popover:
                 brush_basic_sculpt_settings(col, context, brush)
 
+            # normal_radius_factor
+            col.separator()
+            row = col.row()
+            row.prop(brush, "normal_radius_factor", slider=True)
+
             # topology_rake_factor
             if (
                     capabilities.has_topology_rake and
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 8db27bd4118..ed02a34196f 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -257,8 +257,15 @@ typedef struct SculptSession {
 
   struct StrokeCache *cache;
 
+  /* Cursor data and active vertex for tools */
   int active_vertex_index;
 
+  float cursor_radius;
+  float cursor_location[3];
+  float cursor_normal[3];
+  float cursor_view_normal[3];
+  struct RegionView3D *rv3d;
+
   union {
     struct {
       struct SculptVertexPaintGeomMap gmap;
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 93a826f3324..f02d41d3c65 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -132,8 +132,11 @@ bool BKE_pbvh_node_raycast(PBVH *bvh,
                            float (*origco)[3],
                            bool use_origco,
                            const float ray_start[3],
+                           const float ray_normal[3],
                            struct IsectRayPrecalc *isect_precalc,
-                           float *depth);
+                           float *depth,
+                           int *active_vertex_index,
+                           float *face_normal);
 
 bool BKE_pbvh_bmesh_node_raycast_detail(PBVHNode *node,
                                         const float ray_start[3],
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index b2d3ccfebc3..83e4a582ff1 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -72,6 +72,7 @@ static void brush_defaults(Brush *brush)
   brush->autosmooth_factor = 0.0f;
   brush->topology_rake_factor = 0.0f;
   brush->crease_pinch_factor = 0.5f;
+  brush->normal_radius_factor = 0.5f;
   brush->sculpt_plane = SCULPT_DISP_DIR_AREA;
   /* How far above or below the plane that is found by averaging the faces. */
   brush->plane_offset = 0.0f;
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index cea68a0c525..7a8c082842e 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1753,14 +1753,21 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
                                     const PBVHNode *node,
                                     float (*origco)[3],
                                     const float ray_start[3],
+                                    const float ray_normal[3],
                                     struct IsectRayPrecalc *isect_precalc,
-                                    float *depth)
+                                    float *depth,
+                                    int *r_active_vertex_index,
+                                    float *r_face_normal)
 {
   const MVert *vert = bvh->verts;
   const MLoop *mloop = bvh->mloop;
   const int *faces = node->prim_indices;
   int i, totface = node->totprim;
   bool hit = false;
+  float min_depth = FLT_MAX;
+  float location[3] = {0.0f};
+  float nearest_vertex_co[3];
+  copy_v3_fl(nearest_vertex_co, 0.0f);
 
   for (i = 0; i < totface; ++i) {
     const MLoopTri *lt = &bvh->looptri[faces[i]];
@@ -1787,6 +1794,22 @@ static bool pbvh_faces_node_raycast(PBVH *bvh,
                                        vert[mloop[lt->tri[1]].v].co,
                                        vert[mloop[lt->tri[2]].v].co,
                                        depth);
+
+      if (hit && *depth < min_depth) {
+        min_depth = *depth;
+        normal_tri_v3(r_face_normal,
+                      vert[mloop[lt->tri[0]].v].co,
+                      vert[mloop[lt->tri[1]].v].co,
+                      vert[mloop[lt->tri[2]].v].co);
+        madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
+        for (int j = 0; j < 3; j++) {
+          if (len_squared_v3v3(location, vert[mloop[lt->tri[j]].v].co) <
+              len_squared_v3v3(location, nearest_vertex_co)) {
+            copy_v3_v3(nearest_vertex_co, vert[mloop[lt->tri[j]].v].co);
+            *r_active_vertex_index = mloop[lt->tri[j]].v;
+          }
+        }
+      }
     }
   }
 
@@ -1857,8 +1880,11 @@ bool BKE_pbvh_node_raycast(PBVH *bvh,
                            float (*origco)[3],
                            bool use_origco,
                            const float ray_start[3],
+                           const float ray_normal[3],
                            struct IsectRayPrecalc *isect_precalc,
-                           float *depth)
+                           float *depth,
+                           int *active_vertex_index,
+                           float *face_normal)
 {
   bool hit = false;
 
@@ -1868,13 +1894,29 @@ bool BKE_pbvh_node_raycast(PBVH *bvh,
 
   switch (bvh->type) {
     case PBVH_FACES:
-      hit |= pbvh_faces_node_raycast(bvh, node, origco, ray_start, isect_precalc, depth);
+      hit |= pbvh_faces_node_raycast(bvh,
+                                     node,
+                                     origco,
+                                     ray_start,
+                                     ray_normal,
+                                     isect_precalc,
+                                     depth,
+                                     active_vertex_index,
+                                     face_normal);
       break;
     case PBVH_GRIDS:
       hit |= pbvh_grids_node_raycast(bvh, node, origco, ray_start, isect_precalc, depth);
       break;
     case PBVH_BMESH:
-      hit = pbvh_bmesh_node_raycast(node, ray_start, isect_precalc, depth, use_origco);
+      BM_mesh_elem_index_ensure(bvh->bm, BM_VERT);
+      hit = pbvh_bmesh_node_raycast(node,
+                                    ray_start,
+                                    ray_normal,
+                                    isect_precalc,
+                                    depth,
+                                    use_origco,
+                                    active_vertex_index,
+                                    face_normal);
       break;
   }
 
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 1d8088c6605..c04e172f116 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -1508,12 +1508,18 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
 
 bool pbvh_bmesh_node_raycast(PBVHNode *node,
                              const float ray_start[3],
+                             const float ray_normal[3],
                              struct IsectRayPrecalc *isect_precalc,
                              float *depth,
-                             bool use_original)
+                             bool use_original,
+                             int *r_active_vertex_index,
+                             float *r_face_normal)
 {
   bool hit = false;
 
+  float min_depth = FLT_MAX;
+  float nearest_vertex_co[3] = {0.0f};
+  float location[3] = {0.0f};
   if (use_original && node->bm_tot_ortri) {
     for (int i = 0; i < node->bm_tot_ortri; i++) {
       const int *t = node->bm_ortri[i];
@@ -1538,6 +1544,19 @@ bool pbvh_bmesh_node_raycast(PBVHNode *node,
         BM_face_as_array_vert_tri(f, v_tri);
         hit |= ray_face_intersection_tri(
             ray_start, isect_precalc, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co, depth);
+
+        if (hit && *depth < min_depth) {
+          min_depth = *depth;
+          normal_tri_v3(r_face_normal, v_tri[0]->co, v_tri[1]->co, v_tri[2]->co);
+          madd_v3_v3v3fl(location, ray_start, ray_normal, *depth);
+          for (int j = 0; j < 3; j++) {
+            if (len_squared_v3v3(location, v_tri[j]->co) <
+                len_squared_v3v3(location, nearest_vertex_co)) {
+              copy_v3_v3(nearest_vertex_co, v_tri[j]->co);
+              *r_active_vertex_index = BM_elem_index_get(v_tri[j]);
+            }
+          }
+        }
       }
     }
   }
diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h
index e74a8d43c68..bad103743eb 100644
--- a/source/blender/blenkernel/intern/pbvh_intern.h
+++ b/source/blender/blenkernel/intern/pbvh_intern.h
@@ -206,9 +206,12 @@ void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
 /* pbvh_bmesh.c */
 bool pbvh_bmesh_node_raycast(PBVHNode *node,
                              const float ray_start[3],
+                             const float ray_normal[3],
                              struct IsectRayPrecalc *isect_precalc,
                              float *dist,
-                             bool use_original);
+                             bool use_original,
+                             int *r_active_vertex_index,
+                             float *r_face_normal);
 bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node,
                                     const float ray_start[3],
                                     const float ray_normal[3],
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index a66b9336632..ed3b1613b2a 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -3706,5 +3706,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
 
   {
     /* Versioning code until next subversion bump

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list