WIP: Added popup to UV merge by distance operator #110884

Draft
Melissa-Goon wants to merge 2 commits from Melissa-Goon/blender:gsoc2023-merge-popup into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.

View File

@ -35,6 +35,7 @@
#include "BKE_material.h" #include "BKE_material.h"
#include "BKE_mesh_mapping.hh" #include "BKE_mesh_mapping.hh"
#include "BKE_node.h" #include "BKE_node.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h" #include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h" #include "DEG_depsgraph_query.h"
@ -724,6 +725,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
blender::Vector<int> duplicates; blender::Vector<int> duplicates;
blender::Vector<float *> mloopuv_arr; blender::Vector<float *> mloopuv_arr;
blender::Set<std::pair<float, float>> uvs_set;
int mloopuv_count = 0; /* Also used for *duplicates count. */ int mloopuv_count = 0; /* Also used for *duplicates count. */
@ -752,6 +754,9 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
duplicates.append(-1); duplicates.append(-1);
mloopuv_arr.append(luv); mloopuv_arr.append(luv);
mloopuv_count++; mloopuv_count++;
std::pair<float, float> uv = {luv[0], luv[1]};
uvs_set.add(uv);
} }
} }
} }
@ -759,6 +764,10 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
ob_mloopuv_max_idx[ob_index] = mloopuv_count - 1; ob_mloopuv_max_idx[ob_index] = mloopuv_count - 1;
} }
/*Save initial unique uv count*/
int count_inital = uvs_set.size();
uvs_set.clear();
BLI_kdtree_2d_balance(tree); BLI_kdtree_2d_balance(tree);
int found_duplicates = BLI_kdtree_2d_calc_duplicates_fast( int found_duplicates = BLI_kdtree_2d_calc_duplicates_fast(
tree, threshold, false, duplicates.data()); tree, threshold, false, duplicates.data());
@ -809,13 +818,36 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
} }
for (ob_index = 0; ob_index < objects_len; ob_index++) { for (ob_index = 0; ob_index < objects_len; ob_index++) {
BMIter iter, liter;
BMFace *efa;
BMLoop *l;
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (changed[ob_index]) { if (changed[ob_index]) {
Object *obedit = objects[ob_index]; Object *obedit = objects[ob_index];
uvedit_live_unwrap_update(sima, scene, obedit); uvedit_live_unwrap_update(sima, scene, obedit);
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0); DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
} }
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
std::pair<float, float> uv = {luv[0], luv[1]};
uvs_set.add(uv);
}
}
}
} }
int count = count_inital - uvs_set.size();
BKE_reportf(op->reports, RPT_INFO, "Merged %d UV(s)", count);
} }
BLI_kdtree_2d_free(tree); BLI_kdtree_2d_free(tree);
@ -851,6 +883,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen); KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
blender::Vector<float *> mloopuv_arr; blender::Vector<float *> mloopuv_arr;
blender::Set<std::pair<float, float>> uvs_set;
int mloopuv_count = 0; int mloopuv_count = 0;
@ -874,18 +907,24 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
} }
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (!uvedit_uv_select_test(scene, l, offsets)) { if (!uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
BLI_kdtree_2d_insert(tree, mloopuv_count, luv); BLI_kdtree_2d_insert(tree, mloopuv_count, luv);
mloopuv_arr.append(luv); mloopuv_arr.append(luv);
mloopuv_count++; mloopuv_count++;
} }
std::pair<float, float> uv = {luv[0], luv[1]};
uvs_set.add(uv);
} }
} }
} }
BLI_kdtree_2d_balance(tree); BLI_kdtree_2d_balance(tree);
/*Save initial unique uv count*/
int count_inital = uvs_set.size();
uvs_set.clear();
/* For each selected uv, find duplicate non selected uv. */ /* For each selected uv, find duplicate non selected uv. */
for (uint ob_index = 0; ob_index < objects_len; ob_index++) { for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
BMIter iter, liter; BMIter iter, liter;
@ -907,16 +946,18 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
} }
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (uvedit_uv_select_test(scene, l, offsets)) { if (uvedit_uv_select_test(scene, l, offsets)) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
KDTreeNearest_2d nearest; KDTreeNearest_2d nearest;
const int i = BLI_kdtree_2d_find_nearest(tree, luv, &nearest); const int i = BLI_kdtree_2d_find_nearest(tree, luv, &nearest);
if (i != -1 && nearest.dist < threshold) { if (i != -1 && nearest.dist < threshold) {
copy_v2_v2(luv, mloopuv_arr[i]); copy_v2_v2(luv, mloopuv_arr[i]);
changed = true; changed = true;
} }
} }
std::pair<float, float> uv = {luv[0], luv[1]};
uvs_set.add(uv);
} }
} }
@ -927,6 +968,9 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
} }
} }
int count = count_inital - uvs_set.size();
BKE_reportf(op->reports, RPT_INFO, "Merged %d UV(s)", count);
BLI_kdtree_2d_free(tree); BLI_kdtree_2d_free(tree);
MEM_freeN(objects); MEM_freeN(objects);