[Bf-blender-cvs] [dabff9af7d9] temp_bmesh_multires: * Fix crash in boundary sculpt tool * For some reason boundary tool sometimes fails to match verts to boundary verts. It now simply freezes them in place if that happens

Joseph Eagar noreply at git.blender.org
Thu Apr 15 03:42:27 CEST 2021


Commit: dabff9af7d9ef74551e02cac36c736a84b89c333
Author: Joseph Eagar
Date:   Wed Apr 14 18:41:23 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rBdabff9af7d9ef74551e02cac36c736a84b89c333

* Fix crash in boundary sculpt tool
* For some reason boundary tool sometimes fails to match verts to
  boundary verts.  It now simply freezes them in place if that happens

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

M	source/blender/blenkernel/BKE_paint.h
M	source/blender/blenlib/BLI_compiler_attrs.h
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_boundary.c

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

diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 930c7b6f7e5..a7bbbac506b 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -427,7 +427,7 @@ typedef struct SculptBoundary {
   /* Bend Deform type. */
   struct {
     float (*pivot_rotation_axis)[3];
-    float (*pivot_positions)[3];
+    float (*pivot_positions)[4];
   } bend;
 
   /* Slide Deform type. */
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index 680c4bc78da..f976b32fcf6 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -98,3 +98,14 @@
 #else
 #  define ATTR_ALIGN(x) __attribute__((aligned(x)))
 #endif
+
+/* Disable optimization for a function (for debugging use only)*/
+#ifdef __clang__
+#define ATTR_NO_OPT __attribute__((optnone))
+#elif __MSC_VER
+#  define ATTR_NO_OPT __pragma(optimize("", off))
+#elif __GNUC__
+#define ATTR_NO_OPT _Pragma(optimize, "O0")
+#else
+#define ATTR_NO_OPT
+#endif
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 4ef4429013b..3faa5bbfae2 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -7328,6 +7328,7 @@ void SCULPT_cache_free(StrokeCache *cache)
   for (int i = 0; i < PAINT_SYMM_AREAS; i++) {
     if (cache->boundaries[i]) {
       SCULPT_boundary_data_free(cache->boundaries[i]);
+      cache->boundaries[i] = NULL;
     }
   }
 
diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c
index b200e1c3a6f..a0e9e52f7cc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_boundary.c
+++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c
@@ -58,9 +58,24 @@
 #include <math.h>
 #include <stdlib.h>
 
+#if 1
+#  ifdef NDEBUG
+#    define NDEBUG_UNDEFD
+#    undef NDEBUG
+#  endif
+
+#  include "BLI_assert.h"
+
+#  ifdef NDEBUG_UNDEFD
+#    define NDEBUG 1
+#  endif
+#endif
+
 #define BOUNDARY_VERTEX_NONE -1
 #define BOUNDARY_STEPS_NONE -1
 
+#define TSTN 4
+
 typedef struct BoundaryInitialVertexFloodFillData {
   SculptVertRef initial_vertex;
   int initial_vertex_index;
@@ -71,6 +86,31 @@ typedef struct BoundaryInitialVertexFloodFillData {
   int *floodfill_steps;
   float radius_sq;
 } BoundaryInitialVertexFloodFillData;
+#if 0
+__attribute__((optnone)) static bool validVert(SculptSession *ss, SculptVertRef v)
+{
+  if (v.i == -1) {
+    return false;
+  }
+
+  if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH && v.i < 1000000) {
+    return false;
+  }
+
+  int totvert = SCULPT_vertex_count_get(ss);
+  int idx = BKE_pbvh_vertex_index_to_table(ss->pbvh, v);
+
+  return idx >= 0 && idx < totvert;
+}
+__attribute__((optnone)) static void validateVert(SculptSession *ss, SculptVertRef v)
+{
+  if (!validVert(ss, v)) {
+    printf("Error! %p\n", v.i);
+  }
+}
+#endif
+// XXX remove all calls to validateVert before final merge
+#define validateVert(ss, vertex)
 
 static bool boundary_initial_vertex_floodfill_cb(SculptSession *ss,
                                                  SculptVertRef from_vref,
@@ -80,6 +120,9 @@ static bool boundary_initial_vertex_floodfill_cb(SculptSession *ss,
 {
   BoundaryInitialVertexFloodFillData *data = userdata;
 
+  validateVert(ss, from_vref);
+  validateVert(ss, to_vref);
+
   int to_v = BKE_pbvh_vertex_index_to_table(ss->pbvh, to_vref);
   int from_v = BKE_pbvh_vertex_index_to_table(ss->pbvh, from_vref);
 
@@ -114,6 +157,7 @@ static SculptVertRef sculpt_boundary_get_closest_boundary_vertex(
     const int initial_vertex_index,
     const float radius)
 {
+  validateVert(ss, initial_vertex);
 
   if (SCULPT_vertex_is_boundary(ss, initial_vertex)) {
     return initial_vertex;
@@ -132,7 +176,7 @@ static SculptVertRef sculpt_boundary_get_closest_boundary_vertex(
   };
 
   fdata.floodfill_steps = MEM_calloc_arrayN(
-      SCULPT_vertex_count_get(ss), sizeof(int), "floodfill steps");
+      SCULPT_vertex_count_get(ss), sizeof(int) * TSTN, "floodfill steps");
 
   SCULPT_floodfill_execute(ss, &flood, boundary_initial_vertex_floodfill_cb, &fdata);
   SCULPT_floodfill_free(&flood);
@@ -146,11 +190,11 @@ static SculptVertRef sculpt_boundary_get_closest_boundary_vertex(
  * deformations usually need in the boundary. */
 static int BOUNDARY_INDICES_BLOCK_SIZE = 300;
 
-static void sculpt_boundary_index_add(SculptSession *ss,
-                                      SculptBoundary *boundary,
-                                      const SculptVertRef new_index,
-                                      const float distance,
-                                      GSet *included_vertices)
+ATTR_NO_OPT static void sculpt_boundary_index_add(SculptSession *ss,
+                                                  SculptBoundary *boundary,
+                                                  const SculptVertRef new_index,
+                                                  const float distance,
+                                                  GSet *included_vertices)
 {
 
   boundary->vertices[boundary->num_vertices] = new_index;
@@ -167,10 +211,12 @@ static void sculpt_boundary_index_add(SculptSession *ss,
   if (boundary->num_vertices >= boundary->vertices_capacity) {
     boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
     boundary->vertices = MEM_reallocN_id(boundary->vertices,
-                                         boundary->vertices_capacity * sizeof(SculptVertRef),
+                                         boundary->vertices_capacity * sizeof(SculptVertRef) *
+                                             TSTN,
                                          "boundary vertrefs");
-    boundary->vertex_indices = MEM_reallocN_id(
-        boundary->vertex_indices, boundary->vertices_capacity * sizeof(int), "boundary indices");
+    boundary->vertex_indices = MEM_reallocN_id(boundary->vertex_indices,
+                                               boundary->vertices_capacity * sizeof(int) * TSTN,
+                                               "boundary indices");
   }
 };
 
@@ -186,7 +232,8 @@ static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary,
   if (boundary->num_edges >= boundary->edges_capacity) {
     boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE;
     boundary->edges = MEM_reallocN_id(boundary->edges,
-                                      boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge),
+                                      boundary->edges_capacity *
+                                          sizeof(SculptBoundaryPreviewEdge) * TSTN,
                                       "boundary edges");
   }
 };
@@ -260,9 +307,10 @@ static bool boundary_floodfill_cb(
                                              boundary->distance[from_v_i] + edge_len :
                                              0.0f;
   sculpt_boundary_index_add(ss, boundary, to_v, distance_boundary_to_dst, data->included_vertices);
-  if (!is_duplicate) {
+  //if (!is_duplicate) {
     sculpt_boundary_preview_edge_add(boundary, from_v, to_v);
-  }
+  //}
+
   return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v);
 }
 
@@ -272,17 +320,19 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
                                          const SculptVertRef initial_boundary_index)
 {
 
+  validateVert(ss, initial_boundary_index);
+
   const int totvert = SCULPT_vertex_count_get(ss);
   boundary->vertices = MEM_malloc_arrayN(
-      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptVertRef), "boundary vrefs");
+      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptVertRef) * TSTN, "boundary vrefs");
   boundary->vertex_indices = MEM_malloc_arrayN(
-      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices");
+      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int) * TSTN, "boundary indices");
 
   if (init_boundary_distances) {
-    boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances");
+    boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float) * TSTN, "boundary distances");
   }
   boundary->edges = MEM_malloc_arrayN(
-      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges");
+      BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge) * TSTN, "boundary edges");
 
   GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE);
   SculptFloodFill flood;
@@ -327,17 +377,19 @@ static void sculpt_boundary_indices_init(SculptSession *ss,
  * needed to go from a boundary vertex to an interior vertex and which vertex of the boundary is
  * the closest one.
  */
-static void sculpt_boundary_edit_data_init(SculptSession *ss,
-                                           SculptBoundary *boundary,
-                                           const SculptVertRef initial_vertex,
-                                           const float radius)
+ATTR_NO_OPT static void sculpt_boundary_edit_data_init(SculptSession *ss,
+                                                       SculptBoundary *boundary,
+                                                       const SculptVertRef initial_vertex,
+                                                       const float radius)
 {
   const int totvert = SCULPT_vertex_count_get(ss);
 
   const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS;
 
+  validateVert(ss, initial_vertex);
+
   boundary->edit_info = MEM_malloc_arrayN(
-      totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info");
+      totvert, sizeof(SculptBoundaryEditInfo) * TSTN, "Boundary edit info");
 
   for (int i = 0; i < totvert; i++) {
     boundary->edit_info[i].original_vertex.i = BOUNDARY_VERTEX_NONE;
@@ -366,8 +418,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss,
           int index = ni_duplis.index;
 
           boundary->edit_info[index].original_vertex = boundary->vertices[i];
-          boundary->edit_info[index].original_vertex_i = BKE_pbvh_vertex_index_to_table(
-              ss->pbvh, boundary->vertices[i]);
+          boundary->edit_info[index].original_vertex_i = boundary->vertex_indices[i];

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list