[Bf-blender-cvs] [d7c762d2f75] master: Cleanup: Rearrange the functions in 'transform_convert_mesh.c'
Germano Cavalcante
noreply at git.blender.org
Mon Apr 26 14:35:19 CEST 2021
Commit: d7c762d2f7533a6f77a912f82937e79fb046362e
Author: Germano Cavalcante
Date: Mon Apr 26 09:35:03 2021 -0300
Branches: master
https://developer.blender.org/rBd7c762d2f7533a6f77a912f82937e79fb046362e
Cleanup: Rearrange the functions in 'transform_convert_mesh.c'
The creation of `TransCustomData` is best located at the beginning of the
file as it is a specific struct of the file and can be used a lot locally.
===================================================================
M source/blender/editors/transform/transform_convert_mesh.c
===================================================================
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index 872f3e1385a..59f314f5301 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -48,1530 +48,1551 @@
#include "transform_convert.h"
-#define USE_FACE_SUBSTITUTE
-
/* -------------------------------------------------------------------- */
-/** \name Island Creation
+/** \name Container TransCustomData Creation
* \{ */
-void transform_convert_mesh_islands_calc(struct BMEditMesh *em,
- const bool calc_single_islands,
- const bool calc_island_center,
- const bool calc_island_axismtx,
- struct TransIslandData *r_island_data)
-{
- struct TransIslandData data = {NULL};
+struct TransCustomDataMergeGroup {
+ /** map {BMVert: TransCustomDataLayerVert} */
+ struct LinkNode **cd_loop_groups;
+};
- BMesh *bm = em->bm;
- char htype;
- char itype;
- int i;
+struct TransCustomDataLayer {
+ BMesh *bm;
+ struct MemArena *arena;
- /* group vars */
- int *groups_array = NULL;
- int(*group_index)[2] = NULL;
+ struct GHash *origfaces;
+ struct BMesh *bm_origfaces;
- bool has_only_single_islands = bm->totedgesel == 0 && bm->totfacesel == 0;
- if (has_only_single_islands && !calc_single_islands) {
- return;
+ /* 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 tc_mesh_customdatacorrect_free_fn(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);
+
+ if (tcld->bm_origfaces) {
+ BM_mesh_free(tcld->bm_origfaces);
+ }
+ if (tcld->origfaces) {
+ BLI_ghash_free(tcld->origfaces, 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->merge_group.customdatalayer_map) {
+ MEM_freeN(tcld->merge_group.customdatalayer_map);
}
- data.island_vert_map = MEM_mallocN(sizeof(*data.island_vert_map) * bm->totvert, __func__);
- /* we shouldn't need this, but with incorrect selection flushing
- * its possible we have a selected vertex that's not in a face,
- * for now best not crash in that case. */
- copy_vn_i(data.island_vert_map, bm->totvert, -1);
+ MEM_freeN(tcld);
+ custom_data->data = NULL;
+}
- if (!has_only_single_islands) {
- if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) {
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__);
- data.island_tot = BM_mesh_calc_edge_groups(
- bm, groups_array, &group_index, NULL, NULL, BM_ELEM_SELECT);
+#define USE_FACE_SUBSTITUTE
+#ifdef USE_FACE_SUBSTITUTE
+# define FACE_SUBSTITUTE_INDEX INT_MIN
- htype = BM_EDGE;
- itype = BM_VERTS_OF_EDGE;
+/**
+ * Search for a neighboring face with area and preferably without selected vertex.
+ * Used to replace area-less faces in custom-data correction.
+ */
+static BMFace *tc_mesh_customdatacorrect_find_best_face_substitute(BMFace *f)
+{
+ BMFace *best_face = NULL;
+ BMLoop *l;
+ BMIter liter;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ BMLoop *l_radial_next = l->radial_next;
+ BMFace *f_test = l_radial_next->f;
+ if (f_test == f) {
+ continue;
}
- else { /* (bm->selectmode & SCE_SELECT_FACE) */
- groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
- data.island_tot = BM_mesh_calc_face_groups(
- bm, groups_array, &group_index, NULL, NULL, NULL, BM_ELEM_SELECT, BM_VERT);
-
- htype = BM_FACE;
- itype = BM_VERTS_OF_FACE;
+ if (is_zero_v3(f_test->no)) {
+ continue;
}
- BLI_assert(data.island_tot);
- if (calc_island_center) {
- data.center = MEM_mallocN(sizeof(*data.center) * data.island_tot, __func__);
+ /* Check the loops edge isn't selected. */
+ if (!BM_elem_flag_test(l_radial_next->v, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(l_radial_next->next->v, BM_ELEM_SELECT)) {
+ /* Prefer edges with unselected vertices.
+ * Useful for extrude. */
+ best_face = f_test;
+ break;
}
-
- if (calc_island_axismtx) {
- data.axismtx = MEM_mallocN(sizeof(*data.axismtx) * data.island_tot, __func__);
+ if (best_face == NULL) {
+ best_face = f_test;
}
+ }
+ return best_face;
+}
- BM_mesh_elem_table_ensure(bm, htype);
-
- void **ele_array;
- ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- /* may be an edge OR a face array */
- for (i = 0; i < data.island_tot; i++) {
- BMEditSelection ese = {NULL};
-
- const int fg_sta = group_index[i][0];
- const int fg_len = group_index[i][1];
- float co[3], no[3], tangent[3];
- int j;
+static void tc_mesh_customdatacorrect_face_substitute_set(struct TransCustomDataLayer *tcld,
+ BMFace *f,
+ BMFace *f_copy)
+{
+ BLI_assert(is_zero_v3(f->no));
+ BMesh *bm = tcld->bm;
+ /* It is impossible to calculate the loops weights of a face without area.
+ * Find a substitute. */
+ BMFace *f_substitute = tc_mesh_customdatacorrect_find_best_face_substitute(f);
+ if (f_substitute) {
+ /* Copy the custom-data from the substitute face. */
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_loop_interp_from_face(bm, l_iter, f_substitute, false, false);
+ } while ((l_iter = l_iter->next) != l_first);
- zero_v3(co);
- zero_v3(no);
- zero_v3(tangent);
+ /* Use the substitute face as the reference during the transformation. */
+ BMFace *f_substitute_copy = BM_face_copy(tcld->bm_origfaces, bm, f_substitute, true, true);
- ese.htype = htype;
+ /* Hack: reference substitute face in `f_copy->no`.
+ * `tcld->origfaces` is already used to restore the initial value. */
+ BM_elem_index_set(f_copy, FACE_SUBSTITUTE_INDEX);
+ *((BMFace **)&f_copy->no[0]) = f_substitute_copy;
+ }
+}
- /* loop on each face or edge in this group:
- * - assign r_vert_map
- * - calculate (co, no)
- */
- for (j = 0; j < fg_len; j++) {
- ese.ele = ele_array[groups_array[fg_sta + j]];
+static BMFace *tc_mesh_customdatacorrect_face_substitute_get(BMFace *f_copy)
+{
+ BLI_assert(BM_elem_index_get(f_copy) == FACE_SUBSTITUTE_INDEX);
+ return *((BMFace **)&f_copy->no[0]);
+}
- if (data.center) {
- float tmp_co[3];
- BM_editselection_center(&ese, tmp_co);
- add_v3_v3(co, tmp_co);
- }
+#endif /* USE_FACE_SUBSTITUTE */
- if (data.axismtx) {
- float tmp_no[3], tmp_tangent[3];
- BM_editselection_normal(&ese, tmp_no);
- BM_editselection_plane(&ese, tmp_tangent);
- add_v3_v3(no, tmp_no);
- add_v3_v3(tangent, tmp_tangent);
- }
+static void tc_mesh_customdatacorrect_init_vert(struct TransCustomDataLayer *tcld,
+ struct TransDataBasic *td,
+ const int index)
+{
+ BMesh *bm = tcld->bm;
+ BMVert *v = td->extra;
+ BMIter liter;
+ int j, l_num;
+ float *loop_weights;
- {
- /* setup vertex map */
- BMIter iter;
- BMVert *v;
+ // 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 = 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;
- /* connected edge-verts */
- BM_ITER_ELEM (v, &iter, ese.ele, itype) {
- data.island_vert_map[BM_elem_index_get(v)] = i;
- }
- }
+ /* 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;
+#ifdef USE_FACE_SUBSTITUTE
+ if (is_zero_v3(l->f->no)) {
+ tc_mesh_customdatacorrect_face_substitute_set(tcld, l->f, f_copy);
}
+#endif
+ }
- if (data.center) {
- mul_v3_v3fl(data.center[i], co, 1.0f / (float)fg_len);
+ 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);
}
-
- if (data.axismtx) {
- if (createSpaceNormalTangent(data.axismtx[i], no, tangent)) {
- /* pass */
- }
- else {
- if (normalize_v3(no) != 0.0f) {
- axis_dominant_v3_to_m3(data.axismtx[i], no);
- invert_m3(data.axismtx[i]);
- }
- else {
- unit_m3(data.axismtx[i]);
- }
- }
+ else {
+ loop_weights[j] = 0.0f;
}
}
-
- MEM_freeN(groups_array);
- MEM_freeN(group_index);
}
- /* for PET we need islands of 1 so connected vert
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list