[Bf-blender-cvs] [6a689b5047b] blender-v2.90-release: Transform: Correct Face Attributes: Option to merge attributes

Germano Cavalcante noreply at git.blender.org
Tue Jul 28 14:54:40 CEST 2020


Commit: 6a689b5047b23bccd5e36ae9cbd74cc64f4427b3
Author: Germano Cavalcante
Date:   Tue Jul 28 09:35:58 2020 -0300
Branches: blender-v2.90-release
https://developer.blender.org/rB6a689b5047b23bccd5e36ae9cbd74cc64f4427b3

Transform: Correct Face Attributes: Option to merge attributes

Keeping face attributes connected is now optional.

Keeping UV's connected is useful for organic modeling, but bad for
architectural.

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

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/transform/transform_convert.h
M	source/blender/editors/transform/transform_convert_mesh.c
M	source/blender/editors/transform/transform_mode.c
M	source/blender/makesdna/DNA_scene_types.h
M	source/blender/makesrna/intern/rna_scene.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 39e4ee2beac..6e31808d27d 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -208,6 +208,10 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel):
         row = layout.row(align=True, heading="Transform")
         row.prop(tool_settings, "use_transform_correct_face_attributes")
 
+        row = layout.row(align=True)
+        row.active = tool_settings.use_transform_correct_face_attributes
+        row.prop(tool_settings, "use_transform_correct_keep_connected")
+
         row = layout.row(heading="Mirror")
         sub = row.row(align=True)
         sub.prop(mesh, "use_mirror_x", text="X", toggle=True)
diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h
index ee478ad8567..70017d5560b 100644
--- a/source/blender/editors/transform/transform_convert.h
+++ b/source/blender/editors/transform/transform_convert.h
@@ -47,7 +47,7 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize);
 void clipUVData(TransInfo *t);
 
 /* transform_convert_mesh.c */
-void trans_mesh_customdata_correction_init(TransInfo *t);
+void mesh_customdatacorrect_init(TransInfo *t);
 
 /* transform_convert_sequencer.c */
 int transform_convert_sequencer_get_snap_bound(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 31b9b771047..289057b612e 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -958,41 +958,44 @@ void createTransEditVerts(TransInfo *t)
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name CustomData Layer Correction (for meshes)
+/** \name CustomData Layer Correction
  *
  * \{ */
 
-struct TransCustomDataLayerVert {
-  BMVert *v;
-  float co_orig_3d[3];
+struct TransCustomDataMergeGroup {
+  /** map {BMVert: TransCustomDataLayerVert} */
   struct LinkNode **cd_loop_groups;
 };
 
 struct TransCustomDataLayer {
   BMesh *bm;
+  struct MemArena *arena;
 
-  int cd_loop_mdisp_offset;
-
-  /** map {BMVert: TransCustomDataLayerVert} */
-  struct GHash *origverts;
   struct GHash *origfaces;
   struct BMesh *bm_origfaces;
 
-  struct MemArena *arena;
-  /** Number of math BMLoop layers. */
-  int layer_math_map_num;
-  /** Array size of 'layer_math_map_num'
-   * maps TransCustomDataLayerVert.cd_group index to absolute CustomData layer index */
-  int *layer_math_map;
-
-  /* Array with all elements transformed. */
-  struct TransCustomDataLayerVert *data;
-  int data_len;
+  /* Special handle for multi-resolution. */
+  int cd_loop_mdisp_offset;
+
+  /* Optionally merge custom-data groups (this keeps UVs connected for example). */
+  struct {
+    /** map {BMVert: TransDataBasic} */
+    struct GHash *origverts;
+    struct TransCustomDataMergeGroup *data;
+    int data_len;
+    /** Array size of 'layer_math_map_len'
+     * maps #TransCustomDataLayerVert.cd_group index to absolute #CustomData layer index */
+    int *customdatalayer_map;
+    /** Number of math BMLoop layers. */
+    int customdatalayer_map_len;
+  } merge_group;
+
+  bool use_merge_group;
 };
 
-static void trans_mesh_customdata_free_cb(struct TransInfo *UNUSED(t),
-                                          struct TransDataContainer *UNUSED(tc),
-                                          struct TransCustomData *custom_data)
+static void mesh_customdatacorrect_free_cb(struct TransInfo *UNUSED(t),
+                                           struct TransDataContainer *UNUSED(tc),
+                                           struct TransCustomData *custom_data)
 {
   struct TransCustomDataLayer *tcld = custom_data->data;
   bmesh_edit_end(tcld->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
@@ -1003,77 +1006,129 @@ static void trans_mesh_customdata_free_cb(struct TransInfo *UNUSED(t),
   if (tcld->origfaces) {
     BLI_ghash_free(tcld->origfaces, NULL, NULL);
   }
-  if (tcld->origverts) {
-    BLI_ghash_free(tcld->origverts, NULL, NULL);
+  if (tcld->merge_group.origverts) {
+    BLI_ghash_free(tcld->merge_group.origverts, NULL, NULL);
   }
   if (tcld->arena) {
     BLI_memarena_free(tcld->arena);
   }
-  if (tcld->layer_math_map) {
-    MEM_freeN(tcld->layer_math_map);
+  if (tcld->merge_group.customdatalayer_map) {
+    MEM_freeN(tcld->merge_group.customdatalayer_map);
   }
 
   MEM_freeN(tcld);
   custom_data->data = NULL;
 }
 
-static void create_trans_vert_customdata_layer(BMVert *v,
-                                               struct TransCustomDataLayer *tcld,
-                                               struct TransCustomDataLayerVert *r_tcld_vert)
+static void mesh_customdatacorrect_init_vert(struct TransCustomDataLayer *tcld,
+                                             BMVert *v,
+                                             const int index)
 {
   BMesh *bm = tcld->bm;
   BMIter liter;
   int j, l_num;
   float *loop_weights;
 
-  /* copy face data */
   // BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
   BM_iter_init(&liter, bm, BM_LOOPS_OF_VERT, v);
   l_num = liter.count;
-  loop_weights = BLI_array_alloca(loop_weights, l_num);
+  loop_weights = tcld->use_merge_group ? BLI_array_alloca(loop_weights, l_num) : NULL;
   for (j = 0; j < l_num; j++) {
     BMLoop *l = BM_iter_step(&liter);
     BMLoop *l_prev, *l_next;
+
+    /* Generic custom-data correction. Copy face data. */
     void **val_p;
     if (!BLI_ghash_ensure_p(tcld->origfaces, l->f, &val_p)) {
       BMFace *f_copy = BM_face_copy(tcld->bm_origfaces, bm, l->f, true, true);
       *val_p = f_copy;
     }
 
-    if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
-        (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) {
-      loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
+    if (tcld->use_merge_group) {
+      if ((l_prev = BM_loop_find_prev_nodouble(l, l->next, FLT_EPSILON)) &&
+          (l_next = BM_loop_find_next_nodouble(l, l_prev, FLT_EPSILON))) {
+        loop_weights[j] = angle_v3v3v3(l_prev->v->co, l->v->co, l_next->v->co);
+      }
+      else {
+        loop_weights[j] = 0.0f;
+      }
+    }
+  }
+
+  if (tcld->use_merge_group) {
+    /* Store cd_loop_groups. */
+    struct TransCustomDataMergeGroup *merge_data = &tcld->merge_group.data[index];
+    if (l_num != 0) {
+      merge_data->cd_loop_groups = BLI_memarena_alloc(
+          tcld->arena, tcld->merge_group.customdatalayer_map_len * sizeof(void *));
+      for (j = 0; j < tcld->merge_group.customdatalayer_map_len; j++) {
+        const int layer_nr = tcld->merge_group.customdatalayer_map[j];
+        merge_data->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(
+            bm, v, layer_nr, loop_weights, tcld->arena);
+      }
     }
     else {
-      loop_weights[j] = 0.0f;
+      merge_data->cd_loop_groups = NULL;
     }
+
+    BLI_ghash_insert(tcld->merge_group.origverts, v, merge_data);
   }
+}
+
+static void mesh_customdatacorrect_init_container_generic(TransDataContainer *UNUSED(tc),
+                                                          struct TransCustomDataLayer *tcld)
+{
+  BMesh *bm = tcld->bm;
+
+  struct GHash *origfaces = BLI_ghash_ptr_new(__func__);
+  struct BMesh *bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default,
+                                              &((struct BMeshCreateParams){
+                                                  .use_toolflags = false,
+                                              }));
 
-  /* store cd_loop_groups */
-  if (tcld->layer_math_map_num && (l_num != 0)) {
-    r_tcld_vert->cd_loop_groups = BLI_memarena_alloc(tcld->arena,
-                                                     tcld->layer_math_map_num * sizeof(void *));
-    for (j = 0; j < tcld->layer_math_map_num; j++) {
-      const int layer_nr = tcld->layer_math_map[j];
-      r_tcld_vert->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(
-          bm, v, layer_nr, loop_weights, tcld->arena);
+  /* We need to have matching custom-data. */
+  BM_mesh_copy_init_customdata(bm_origfaces, bm, NULL);
+  tcld->origfaces = origfaces;
+  tcld->bm_origfaces = bm_origfaces;
+
+  bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES);
+  tcld->cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+}
+
+static void mesh_customdatacorrect_init_container_merge_group(TransDataContainer *tc,
+                                                              struct TransCustomDataLayer *tcld)
+{
+  BMesh *bm = tcld->bm;
+  BLI_assert(CustomData_has_math(&bm->ldata));
+
+  /* TODO: We don't need `layer_math_map` when there are no loops linked
+   * to one of the sliding vertices. */
+
+  /* Over allocate, only 'math' layers are indexed. */
+  int *customdatalayer_map = MEM_mallocN(sizeof(int) * bm->ldata.totlayer, __func__);
+  int layer_math_map_len = 0;
+  for (int i = 0; i < bm->ldata.totlayer; i++) {
+    if (CustomData_layer_has_math(&bm->ldata, i)) {
+      customdatalayer_map[layer_math_map_len++] = i;
     }
   }
-  else {
-    r_tcld_vert->cd_loop_groups = NULL;
-  }
-
-  r_tcld_vert->v = v;
-  copy_v3_v3(r_tcld_vert->co_orig_3d, v->co);
-  BLI_ghash_insert(tcld->origverts, v, r_tcld_vert);
+  BLI_assert(layer_math_map_len != 0);
+
+  tcld->merge_group.data_len = tc->data_len + tc->data_mirror_len;
+  tcld->merge_group.customdatalayer_map = customdatalayer_map;
+  tcld->merge_group.customdatalayer_map_len = layer_math_map_len;
+  tcld->merge_group.origverts = BLI_ghash_ptr_new_ex(__func__, tcld->merge_group.data_len);
+  tcld->merge_group.data = BLI_memarena_alloc(
+      tcld->arena, tcld->merge_group.data_len * sizeof(*tcld->merge_group.data));
 }
 
-static void trans_mesh_customdata_correction_init_container(TransDataContainer *tc)
+static void mesh_customdatacorrect_init_container(TransDataContainer *tc,
+                                                  const bool use_merge_group)
 {
   if (tc->custom.type.data) {
-    /* Custom data

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list