Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_merge_customdata.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| /** \file | /** \file | ||||
| * \ingroup bke | * \ingroup bke | ||||
| */ | */ | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_math_vector_types.hh" | |||||
| #include "BLI_task.hh" | #include "BLI_task.hh" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_customdata.h" | #include "BKE_customdata.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_mesh_mapping.h" | #include "BKE_mesh_mapping.h" | ||||
| #include "BLI_memarena.h" | #include "BLI_memarena.h" | ||||
| Show All 31 Lines | static int compare_v2_classify(const float uv_a[2], const float uv_b[2]) | ||||
| if (compare_ff_relative(uv_a[0], uv_b[0], diff_abs, diff_ulp) && | if (compare_ff_relative(uv_a[0], uv_b[0], diff_abs, diff_ulp) && | ||||
| compare_ff_relative(uv_a[1], uv_b[1], diff_abs, diff_ulp)) { | compare_ff_relative(uv_a[1], uv_b[1], diff_abs, diff_ulp)) { | ||||
| return CMP_CLOSE; | return CMP_CLOSE; | ||||
| } | } | ||||
| return CMP_APART; | return CMP_APART; | ||||
| } | } | ||||
| static void merge_uvs_for_vertex(const Span<int> loops_for_vert, Span<MLoopUV *> mloopuv_layers) | static void merge_uvs_for_vertex(const Span<int> loops_for_vert, Span<float2 *> mloopuv_layers) | ||||
| { | { | ||||
| if (loops_for_vert.size() <= 1) { | if (loops_for_vert.size() <= 1) { | ||||
| return; | return; | ||||
| } | } | ||||
| /* Manipulate a copy of the loop indices, de-duplicating UV's per layer. */ | /* Manipulate a copy of the loop indices, de-duplicating UV's per layer. */ | ||||
| Vector<int, 32> loops_merge; | Vector<int, 32> loops_merge; | ||||
| loops_merge.reserve(loops_for_vert.size()); | loops_merge.reserve(loops_for_vert.size()); | ||||
| for (MLoopUV *mloopuv : mloopuv_layers) { | for (float2 *mloopuv : mloopuv_layers) { | ||||
| BLI_assert(loops_merge.is_empty()); | BLI_assert(loops_merge.is_empty()); | ||||
| loops_merge.extend_unchecked(loops_for_vert); | loops_merge.extend_unchecked(loops_for_vert); | ||||
| while (loops_merge.size() > 1) { | while (loops_merge.size() > 1) { | ||||
| uint i_last = uint(loops_merge.size()) - 1; | uint i_last = uint(loops_merge.size()) - 1; | ||||
| const float *uv_src = mloopuv[loops_merge[0]].uv; | const float *uv_src = mloopuv[loops_merge[0]]; | ||||
| for (uint i = 1; i <= i_last;) { | for (uint i = 1; i <= i_last;) { | ||||
| float *uv_dst = mloopuv[loops_merge[i]].uv; | float *uv_dst = mloopuv[loops_merge[i]]; | ||||
| switch (compare_v2_classify(uv_src, uv_dst)) { | switch (compare_v2_classify(uv_src, uv_dst)) { | ||||
| case CMP_CLOSE: { | case CMP_CLOSE: { | ||||
| uv_dst[0] = uv_src[0]; | uv_dst[0] = uv_src[0]; | ||||
| uv_dst[1] = uv_src[1]; | uv_dst[1] = uv_src[1]; | ||||
| ATTR_FALLTHROUGH; | ATTR_FALLTHROUGH; | ||||
| } | } | ||||
| case CMP_EQUAL: { | case CMP_EQUAL: { | ||||
| loops_merge[i] = loops_merge[i_last--]; | loops_merge[i] = loops_merge[i_last--]; | ||||
| Show All 17 Lines | static void merge_uvs_for_vertex(const Span<int> loops_for_vert, Span<float2 *> mloopuv_layers) | ||||
| } | } | ||||
| } | } | ||||
| void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) | void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) | ||||
| { | { | ||||
| if (me->totloop == 0) { | if (me->totloop == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| const int mloopuv_layers_num = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); | const int mloopuv_layers_num = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); | ||||
| if (mloopuv_layers_num == 0) { | if (mloopuv_layers_num == 0) { | ||||
| return; | return; | ||||
| } | } | ||||
| int *vert_map_mem; | int *vert_map_mem; | ||||
| struct MeshElemMap *vert_to_loop; | struct MeshElemMap *vert_to_loop; | ||||
| BKE_mesh_vert_loop_map_create(&vert_to_loop, | BKE_mesh_vert_loop_map_create(&vert_to_loop, | ||||
| &vert_map_mem, | &vert_map_mem, | ||||
| BKE_mesh_polys(me), | BKE_mesh_polys(me), | ||||
| BKE_mesh_loops(me), | BKE_mesh_loops(me), | ||||
| me->totvert, | me->totvert, | ||||
| me->totpoly, | me->totpoly, | ||||
| me->totloop); | me->totloop); | ||||
| Vector<MLoopUV *> mloopuv_layers; | Vector<float2 *> mloopuv_layers; | ||||
| mloopuv_layers.reserve(mloopuv_layers_num); | mloopuv_layers.reserve(mloopuv_layers_num); | ||||
| for (int a = 0; a < mloopuv_layers_num; a++) { | for (int a = 0; a < mloopuv_layers_num; a++) { | ||||
| MLoopUV *mloopuv = static_cast<MLoopUV *>(CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a)); | float2 *mloopuv = static_cast<float2 *>(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a)); | ||||
| mloopuv_layers.append_unchecked(mloopuv); | mloopuv_layers.append_unchecked(mloopuv); | ||||
| } | } | ||||
| Span<MLoopUV *> mloopuv_layers_as_span = mloopuv_layers.as_span(); | Span<float2 *> mloopuv_layers_as_span = mloopuv_layers.as_span(); | ||||
HooglyBoogly: `blender::float2` should be used as a replacement for `MLoopUV` here, rather than `float[2]`… | |||||
| threading::parallel_for(IndexRange(me->totvert), 1024, [&](IndexRange range) { | threading::parallel_for(IndexRange(me->totvert), 1024, [&](IndexRange range) { | ||||
| for (const int64_t v_index : range) { | for (const int64_t v_index : range) { | ||||
| MeshElemMap &loops_for_vert = vert_to_loop[v_index]; | MeshElemMap &loops_for_vert = vert_to_loop[v_index]; | ||||
| Span<int> loops_for_vert_span(loops_for_vert.indices, loops_for_vert.count); | Span<int> loops_for_vert_span(loops_for_vert.indices, loops_for_vert.count); | ||||
| merge_uvs_for_vertex(loops_for_vert_span, mloopuv_layers_as_span); | merge_uvs_for_vertex(loops_for_vert_span, mloopuv_layers_as_span); | ||||
| } | } | ||||
| }); | }); | ||||
| MEM_freeN(vert_to_loop); | MEM_freeN(vert_to_loop); | ||||
| MEM_freeN(vert_map_mem); | MEM_freeN(vert_map_mem); | ||||
| } | } | ||||
blender::float2 should be used as a replacement for MLoopUV here, rather than float[2]
Other C++ files are barely converted from C, so that' sokay, but this is a new file that does use new data structures