[Bf-blender-cvs] [b701cd63add] sculpt-dev: Sculpt: various bugfixes

Joseph Eagar noreply at git.blender.org
Thu Oct 28 19:58:09 CEST 2021


Commit: b701cd63adddda402d1e0206008e9c1d55eb6639
Author: Joseph Eagar
Date:   Thu Oct 28 10:50:38 2021 -0700
Branches: sculpt-dev
https://developer.blender.org/rBb701cd63adddda402d1e0206008e9c1d55eb6639

Sculpt: various bugfixes

* BMLog now saves face material indices
* Fixed id corruption in join mesh edge case.
* The mesh->bmesh conversion function now checks
  if IDs are corrupted in a bit smarter way:
  + Any id that's greater then 5 times the sum of
    total elements with ids is assumed to be corrupt.
    Avoids very large allocations for the fast element->id
    map, which is a simple lookup table.
  + Alternative is to automatically switch to the slower
    GHash id->element map.
  + Sculpt code would have to detect this case and regenerate
    IDs?
* The slide relax brush is now internally split into two
  seperate commands.
* Basic smoothing now uses fewer iterations, velocity smooth
  is used to speed up convergence.

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

M	source/blender/blenkernel/intern/brush_engine.c
M	source/blender/bmesh/intern/bmesh_log.c
M	source/blender/bmesh/intern/bmesh_mesh_convert.c
M	source/blender/editors/mesh/meshtools.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/editors/sculpt_paint/sculpt_brushes.c
M	source/blender/editors/sculpt_paint/sculpt_intern.h
M	source/blender/editors/sculpt_paint/sculpt_smooth.c
M	source/blender/makesdna/DNA_brush_enums.h

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

diff --git a/source/blender/blenkernel/intern/brush_engine.c b/source/blender/blenkernel/intern/brush_engine.c
index 7fce1d8ab5c..717bcad902e 100644
--- a/source/blender/blenkernel/intern/brush_engine.c
+++ b/source/blender/blenkernel/intern/brush_engine.c
@@ -1699,11 +1699,11 @@ void BKE_builtin_apply_hard_edge_mode(BrushChannelSet *chset, bool do_apply)
   }
 }
 
-void BKE_builtin_commandlist_create(Brush *brush,
-                                    BrushChannelSet *chset,
-                                    BrushCommandList *cl,
-                                    int tool,
-                                    BrushMappingData *mapdata)
+ATTR_NO_OPT void BKE_builtin_commandlist_create(Brush *brush,
+                                                BrushChannelSet *chset,
+                                                BrushCommandList *cl,
+                                                int tool,
+                                                BrushMappingData *mapdata)
 {
   BrushCommand *cmd;
   BrushChannel *ch;
@@ -1736,7 +1736,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
   float autosmooth_projection = BKE_brush_channelset_get_float(
       chset, "autosmooth_projection", NULL);
 
-  bool is_cloth = tool = SCULPT_TOOL_CLOTH;
+  bool is_cloth = tool == SCULPT_TOOL_CLOTH;
   is_cloth = is_cloth ||
              (ELEM(tool, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE) &&
               BRUSHSET_GET_INT(chset, deform_target, NULL) == BRUSH_DEFORM_TARGET_CLOTH_SIM);
@@ -1761,7 +1761,9 @@ void BKE_builtin_commandlist_create(Brush *brush,
 
   float autosmooth = BKE_brush_channelset_get_float(chset, "autosmooth", NULL);
   if (!no_autosmooth && autosmooth > 0.0f) {
-    cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), SCULPT_TOOL_SMOOTH);
+    int smooth_tool = tool != SCULPT_TOOL_SLIDE_RELAX ? SCULPT_TOOL_SMOOTH : SCULPT_TOOL_RELAX;
+
+    cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), smooth_tool);
     BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
     BKE_brush_commandset_inherit_all_mappings(cmd->params);
 
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 7ea7c76557f..cc0074aa8f8 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -464,7 +464,8 @@ typedef struct {
   void *customdata_f;
   char hflag;
 
-  size_t len;
+  uint len;
+  short mat_nr;
 
   void *customdata_res[MAX_FACE_RESERVED];
   uint v_ids_res[MAX_FACE_RESERVED];
@@ -844,6 +845,7 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
 
   lf->len = (size_t)f->len;
   lf->id = (uint)BM_ELEM_GET_ID(log->bm, f);
+  lf->mat_nr = f->mat_nr;
 
   SET_TRACE(lf);
 
@@ -1379,7 +1381,9 @@ static void bm_log_faces_restore(
 
     BMFace *f = BM_face_create_verts(
         bm, vs_tmp, (int)BLI_array_len(vs_tmp), NULL, BM_CREATE_SKIP_ID, true);
+
     f->head.hflag = lf->hflag;
+    f->mat_nr = lf->mat_nr;
 
     copy_v3_v3(f->no, lf->no);
 
@@ -1515,6 +1519,7 @@ static void bm_log_face_values_swap(BMLog *log,
 
     swap_v3_v3(f->no, lf->no);
     SWAP(char, f->head.hflag, lf->hflag);
+    SWAP(short, f->mat_nr, lf->mat_nr);
 
     void *old_cdata = NULL;
 
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c b/source/blender/bmesh/intern/bmesh_mesh_convert.c
index fe8b58658da..4deaa9f6802 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c
@@ -280,9 +280,9 @@ void BM_enter_multires_space(Object *ob, BMesh *bm, int space)
  */
 
 void BM_mesh_bm_from_me(Object *ob,
-                                    BMesh *bm,
-                                    const Mesh *me,
-                                    const struct BMeshFromMeshParams *params)
+                        BMesh *bm,
+                        const Mesh *me,
+                        const struct BMeshFromMeshParams *params)
 {
   const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
                                         bm->pdata.totlayer || bm->ldata.totlayer));
@@ -500,18 +500,30 @@ void BM_mesh_bm_from_me(Object *ob,
     BM_mesh_cd_flag_apply(bm, me->cd_flag);
   }
 
+#define IS_GARBAGE_ID(id) ((id) < 0 || (id) > id_garbage_threshold)
+
   int *existing_id_layers[4] = {NULL, NULL, NULL, NULL};
+
+  /* threshold to detect garbage IDs, number of elements with ids multiplied by 5 */
+  int id_garbage_threshold = 0;
+
   int use_exist_ids = 0;
   int has_ids = bm->idmap.flag & BM_HAS_IDS ?
                     (bm->idmap.flag & (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE)) :
                     0;
-
   if (bm->idmap.flag & BM_HAS_IDS) {
+    int tots[4] = {me->totvert + bm->totvert,
+                   me->totedge + bm->totedge,
+                   me->totloop + bm->totloop,
+                   me->totpoly + bm->totface};
+
     if (!params->ignore_id_layers) {
       for (int i = 0; i < 4; i++) {
         existing_id_layers[i] = (int *)CustomData_get_layer(cdatas[i], CD_MESH_ID);
 
         if (existing_id_layers[i]) {
+          id_garbage_threshold += tots[i];
+
           use_exist_ids |= 1 << i;
         }
       }
@@ -522,6 +534,8 @@ void BM_mesh_bm_from_me(Object *ob,
     bm_init_idmap_cdlayers(bm);
   }
 
+  id_garbage_threshold *= 5;
+
   const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
   const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
   const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
@@ -560,7 +574,7 @@ void BM_mesh_bm_from_me(Object *ob,
     bm_elem_check_toolflags(bm, (BMElem *)v);
 
     if (has_ids & BM_VERT) {
-      if (use_exist_ids & BM_VERT) {
+      if ((use_exist_ids & BM_VERT) && !IS_GARBAGE_ID(existing_id_layers[0][i])) {
         bm_assign_id(bm, (BMElem *)v, existing_id_layers[0][i], false);
       }
       else {
@@ -611,7 +625,7 @@ void BM_mesh_bm_from_me(Object *ob,
     bm_elem_check_toolflags(bm, (BMElem *)e);
 
     if (has_ids & BM_EDGE) {
-      if (use_exist_ids & BM_EDGE) {
+      if ((use_exist_ids & BM_EDGE) && !IS_GARBAGE_ID(existing_id_layers[1][i])) {
         bm_assign_id(bm, (BMElem *)e, existing_id_layers[1][i], false);
       }
       else {
@@ -682,7 +696,7 @@ void BM_mesh_bm_from_me(Object *ob,
       CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
 
       if (has_ids & BM_LOOP) {
-        if (use_exist_ids & BM_LOOP) {
+        if ((use_exist_ids & BM_LOOP) && !IS_GARBAGE_ID(existing_id_layers[2][j - 1])) {
           bm_assign_id(bm, (BMElem *)l_iter, existing_id_layers[2][j - 1], false);
         }
         else {
@@ -697,7 +711,7 @@ void BM_mesh_bm_from_me(Object *ob,
     bm_elem_check_toolflags(bm, (BMElem *)f);
 
     if (has_ids & BM_FACE) {
-      if (use_exist_ids & BM_FACE) {
+      if ((use_exist_ids & BM_FACE) && !IS_GARBAGE_ID(existing_id_layers[3][i])) {
         bm_assign_id(bm, (BMElem *)f, existing_id_layers[3][i], false);
       }
       else {
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 1b720f2c14d..a26a74a9cb7 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -77,6 +77,134 @@
 /* join selected meshes into the active mesh, context sensitive
  * return 0 if no join is made (error) and 1 if the join is done */
 
+static void get_id_range(Mesh *mesh,
+                         CustomData *vdata,
+                         CustomData *edata,
+                         CustomData *ldata,
+                         CustomData *pdata,
+                         int totvert,
+                         int totedge,
+                         int totloop,
+                         int totpoly,
+                         int *r_min,
+                         int *r_max)
+{
+  const CustomData *datas[4] = {vdata, edata, ldata, pdata};
+  int tots[4] = {totvert, totedge, totloop, totpoly};
+  int min_id = 0, max_id = 0;
+
+  for (int i = 0; i < 4; i++) {
+    int *ids = CustomData_get_layer(datas[i], CD_MESH_ID);
+    if (!ids) {
+      continue;
+    }
+
+    if (!tots[i]) {
+      continue;
+    }
+
+    if (i == 0) {
+      min_id = max_id = *ids;
+    }
+    else {
+      min_id = MIN2(min_id, *ids);
+      max_id = MAX2(max_id, *ids);
+    }
+
+    ids++;
+
+    for (int j = 1; j < tots[i]; j++, ids++) {
+      min_id = MIN2(min_id, *ids);
+      max_id = MAX2(max_id, *ids);
+    }
+  }
+
+  *r_min = min_id;
+  *r_max = max_id;
+}
+
+static void handle_missing_id_layers(Mesh *src,
+                                     Mesh *dst,
+                                     CustomData *vdata,
+                                     CustomData *edata,
+                                     CustomData *ldata,
+                                     CustomData *pdata,
+                                     int totvert,
+                                     int totedge,
+                                     int totloop,
+                                     int totpoly)
+{
+  const CustomData *src_datas[4] = {&src->vdata, &src->edata, &src->ldata, &src->pdata};
+  const CustomData *dst_datas[4] = {vdata, edata, ldata, pdata};
+  int srctots[4] = {src->totvert, src->totedge, src->totloop, src->totpoly};
+  int dsttots[4] = {totvert, totedge, totloop, totpoly};
+
+  // find starting max id in dst
+  int dst_range[2], src_range[2];
+
+  get_id_range(src,
+               &src->vdata,
+               &src->edata,
+               &src->ldata,
+               &src->pdata,
+               src->totvert,
+               src->totedge,
+               src->totloop,
+               src->totpoly,
+               src_range,
+               src_range + 1);
+
+  get_id_range(dst,
+               vdata,
+               edata,
+               ldata,
+               pdata,
+               totvert,
+               totedge,
+               totloop,
+               totpoly,
+               dst_range,
+               dst_range + 1);
+
+  for (int i = 0; i < 4; i++) {
+    const CustomData *srcdata = src_datas[i];
+    const CustomData *dstdata = dst_datas[i];
+
+    const bool haveid_src = Cus

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list