Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------release/scripts/addons0
-rw-r--r--release/scripts/startup/bl_ui/properties_data_mesh.py1
-rw-r--r--source/blender/blenkernel/BKE_attribute.h39
-rw-r--r--source/blender/blenkernel/BKE_customdata.h23
-rw-r--r--source/blender/blenkernel/BKE_editmesh_tangent.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh_legacy_convert.h8
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh_tangent.h29
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc2
-rw-r--r--source/blender/blenkernel/intern/attribute.cc20
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc104
-rw-r--r--source/blender/blenkernel/intern/attribute_access_intern.hh38
-rw-r--r--source/blender/blenkernel/intern/customdata.cc190
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c6
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c71
-rw-r--r--source/blender/blenkernel/intern/editmesh_tangent.cc12
-rw-r--r--source/blender/blenkernel/intern/fluid.c13
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc21
-rw-r--r--source/blender/blenkernel/intern/layer_utils.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.cc36
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc20
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc18
-rw-r--r--source/blender/blenkernel/intern/mesh_legacy_convert.cc228
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.cc28
-rw-r--r--source/blender/blenkernel/intern/mesh_merge_customdata.cc18
-rw-r--r--source/blender/blenkernel/intern/mesh_mirror.c20
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.cc75
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc10
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc17
-rw-r--r--source/blender/blenkernel/intern/object_update.cc2
-rw-r--r--source/blender/blenkernel/intern/paint_canvas.cc4
-rw-r--r--source/blender/blenkernel/intern/pbvh_pixels.cc13
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c4
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c14
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.cc16
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c24
-rw-r--r--source/blender/blenloader/intern/versioning_400.cc1
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.cc6
-rw-r--r--source/blender/bmesh/bmesh.h1
-rw-r--r--source/blender/bmesh/bmesh_class.h31
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c30
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.cc65
-rw-r--r--source/blender/bmesh/intern/bmesh_query_uv.h5
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c3
-rw-r--r--source/blender/bmesh/operators/bmo_mirror.c18
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c86
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c40
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c34
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c6
-rw-r--r--source/blender/bmesh/tools/bmesh_path_uv.c39
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.cc5
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c4
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.cc18
-rw-r--r--source/blender/draw/intern/draw_cache_impl_particles.c18
-rw-r--r--source/blender/draw/intern/draw_pbvh.cc13
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.cc20
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh.hh6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc6
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc25
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc38
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc9
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc8
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc14
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc9
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc25
-rw-r--r--source/blender/editors/curves/intern/curves_ops.cc2
-rw-r--r--source/blender/editors/geometry/geometry_attributes.cc19
-rw-r--r--source/blender/editors/include/ED_mesh.h11
-rw-r--r--source/blender/editors/include/ED_uvedit.h56
-rw-r--r--source/blender/editors/mesh/editmesh_select.cc4
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c79
-rw-r--r--source/blender/editors/mesh/mesh_data.cc185
-rw-r--r--source/blender/editors/mesh/meshtools.cc6
-rw-r--r--source/blender/editors/object/object_add.cc2
-rw-r--r--source/blender/editors/object/object_bake_api.c4
-rw-r--r--source/blender/editors/object/object_data_transfer.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c66
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c23
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c67
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.cc4
-rw-r--r--source/blender/editors/transform/transform_convert_mesh_uv.c33
-rw-r--r--source/blender/editors/uvedit/uvedit_buttons.c20
-rw-r--r--source/blender/editors/uvedit/uvedit_intern.h8
-rw-r--r--source/blender/editors/uvedit/uvedit_islands.cc49
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c281
-rw-r--r--source/blender/editors/uvedit/uvedit_path.c104
-rw-r--r--source/blender/editors/uvedit/uvedit_rip.c93
-rw-r--r--source/blender/editors/uvedit/uvedit_select.c954
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c173
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c241
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp39
-rw-r--r--source/blender/gpu/GPU_material.h6
-rw-r--r--source/blender/gpu/intern/gpu_vertex_format.cc2
-rw-r--r--source/blender/io/alembic/exporter/abc_writer_mesh.cc8
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.cc31
-rw-r--r--source/blender/io/alembic/intern/abc_customdata.h5
-rw-r--r--source/blender/io/alembic/intern/abc_reader_mesh.cc13
-rw-r--r--source/blender/io/collada/EffectExporter.cpp4
-rw-r--r--source/blender/io/collada/GeometryExporter.cpp25
-rw-r--r--source/blender/io/collada/InstanceWriter.cpp6
-rw-r--r--source/blender/io/collada/MeshImporter.cpp12
-rw-r--r--source/blender/io/collada/MeshImporter.h2
-rw-r--r--source/blender/io/collada/collada_utils.cpp10
-rw-r--r--source/blender/io/usd/intern/usd_reader_mesh.cc14
-rw-r--r--source/blender/io/usd/intern/usd_writer_abstract.cc2
-rw-r--r--source/blender/io/usd/intern/usd_writer_mesh.cc7
-rw-r--r--source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc38
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_mesh.cc33
-rw-r--r--source/blender/io/wavefront_obj/tests/obj_importer_tests.cc6
-rw-r--r--source/blender/makesdna/DNA_customdata_types.h5
-rw-r--r--source/blender/makesdna/DNA_dynamicpaint_types.h8
-rw-r--r--source/blender/makesdna/DNA_fluid_types.h5
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h41
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h53
-rw-r--r--source/blender/makesdna/DNA_node_types.h5
-rw-r--r--source/blender/makesdna/DNA_particle_types.h5
-rw-r--r--source/blender/makesdna/DNA_texture_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c139
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c11
-rw-r--r--source/blender/makesrna/intern/rna_object.c2
-rw-r--r--source/blender/makesrna/intern/rna_particle.c4
-rw-r--r--source/blender/modifiers/intern/MOD_array.c8
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c4
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c24
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c26
-rw-r--r--source/blender/modifiers/intern/MOD_util.cc13
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.cc20
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.cc18
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_customdata.c27
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.c118
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.h6
-rw-r--r--source/blender/render/RE_bake.h1
-rw-r--r--source/blender/render/RE_texture_margin.h1
-rw-r--r--source/blender/render/intern/bake.c10
-rw-r--r--source/blender/render/intern/multires_bake.c66
-rw-r--r--source/blender/render/intern/texture_margin.cc24
140 files changed, 2691 insertions, 2450 deletions
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject c226f867affd12881533a54c8c90ac6eebfaca6
+Subproject 68419fb3659f09e8447d351a25b1bd8e56211a5
diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index fdc9b4572d3..7068a2b049d 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -595,7 +595,6 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
# Built-in names.
{"position": None, "shade_smooth": None, "normal": None, "crease": None},
mesh.attributes,
- mesh.uv_layers,
None if ob is None else ob.vertex_groups,
):
if collection is None:
diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h
index 3f4981993eb..236cc44a77f 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -8,6 +8,9 @@
#pragma once
+#include <string.h>
+
+#include "BLI_string.h"
#include "BLI_sys_types.h"
#include "BKE_customdata.h"
@@ -138,6 +141,42 @@ struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const
bool BKE_id_attribute_calc_unique_name(struct ID *id, const char *name, char *outname);
+inline char const *get_uv_map_vert_selection_name(char const *uv_map_name, char *buffer)
+{
+ size_t len = strlen(uv_map_name);
+
+ BLI_assert(strlen(UV_VERTSEL_NAME) == 2);
+ if (len >= MAX_CUSTOMDATA_LAYER_NAME - 5) {
+ /* TODO(martijn) come up with a way to generate a non-colliding shortening... */
+ }
+ BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_VERTSEL_NAME, uv_map_name);
+ return buffer;
+}
+
+inline char const *get_uv_map_edge_selection_name(char const *uv_map_name, char *buffer)
+{
+ size_t len = strlen(uv_map_name);
+
+ BLI_assert(strlen(UV_VERTSEL_NAME) == 2);
+ if (len >= MAX_CUSTOMDATA_LAYER_NAME - 5) {
+ /* TODO(martijn) come up with a way to generate a non-colliding shortening... */
+ }
+ BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_EDGESEL_NAME, uv_map_name);
+ return buffer;
+}
+
+inline char const *get_uv_map_pin_name(char const *uv_map_name, char *buffer)
+{
+ size_t len = strlen(uv_map_name);
+
+ BLI_assert(strlen(UV_VERTSEL_NAME) == 2);
+ if (len >= MAX_CUSTOMDATA_LAYER_NAME - 5) {
+ /* TODO(martijn) come up with a way to generate a non-colliding shortening... */
+ }
+ BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_PINNED_NAME, uv_map_name);
+ return buffer;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 1cdd3c02d8d..01ceee78497 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -32,6 +32,21 @@ struct CustomData_MeshMasks;
struct ID;
typedef uint64_t eCustomDataMask;
+#define UV_VERTSEL_NAME "vs"
+#define UV_EDGESEL_NAME "es"
+#define UV_PINNED_NAME "pn"
+
+/**
+ * UV map related customdata offsets into BMesh attribute blocks. See #BM_uv_map_get_offsets.
+ * Defined in #BKE_customdata.h to avoid including bmesh.h in many unrelated areas.
+ */
+typedef struct BMUVOffsets {
+ int uv;
+ int select_vert;
+ int select_edge;
+ int pin;
+} BMUVOffsets;
+
/* A data type large enough to hold 1 element from any custom-data layer type. */
typedef struct {
unsigned char data[64];
@@ -126,7 +141,7 @@ void CustomData_data_mix_value(
/**
* Compares if data1 is equal to data2. type is a valid CustomData type
- * enum (e.g. #CD_MLOOPUV). the layer type's equal function is used to compare
+ * enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
* the data, if it exists, otherwise #memcmp is used.
*/
bool CustomData_data_equals(int type, const void *data1, const void *data2);
@@ -607,8 +622,10 @@ enum {
CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */
/* Multiple types of mesh elements... */
- CD_FAKE_UV = CD_FAKE |
- CD_MLOOPUV, /* UV flag, because we handle both loop's UVs and poly's textures. */
+ CD_FAKE_BWEIGHT = CD_FAKE | CD_BWEIGHT, /* *sigh*. */
+ CD_FAKE_UV =
+ CD_FAKE |
+ CD_PROP_FLOAT2, /* UV flag, because we handle both loop's UVs and poly's textures. */
CD_FAKE_LNOR = CD_FAKE |
CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */
diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h
index ee1fda2e5db..5a44a9b5152 100644
--- a/source/blender/blenkernel/BKE_editmesh_tangent.h
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -19,7 +19,7 @@ extern "C" {
*/
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[68 /* MAX_CUSTOMDATA_LAYER_NAME*/],
int tangent_names_len,
const float (*poly_normals)[3],
const float (*loop_normals)[3],
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 8f6786d4113..efcac095e27 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -36,7 +36,6 @@ struct MEdge;
struct MFace;
struct MLoop;
struct MLoopTri;
-struct MLoopUV;
struct MPoly;
struct MVert;
struct Main;
@@ -738,7 +737,6 @@ float BKE_mesh_calc_poly_area(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray);
float BKE_mesh_calc_area(const struct Mesh *me);
-float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array);
void BKE_mesh_calc_poly_angles(const struct MPoly *mpoly,
const struct MLoop *loopstart,
const struct MVert *mvarray,
diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
index 5eae7bf3b22..1e499650264 100644
--- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
@@ -10,7 +10,10 @@
#include "BLI_utildefines.h"
#ifdef __cplusplus
+# include "BLI_array.hh"
+# include "BLI_resource_scope.hh"
# include "BLI_span.hh"
+# include "BLI_vector.hh"
# include "DNA_customdata_types.h"
#endif
@@ -24,6 +27,11 @@ struct MFace;
#ifdef __cplusplus
+void BKE_mesh_legacy_convert_uvs_to_struct(Mesh *mesh,
+ blender::ResourceScope &temp_mloopuv_for_convert,
+ blender::Vector<CustomDataLayer, 16> &layers_to_write);
+void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh);
+
/**
* Move face sets to the legacy type from a generic type.
*/
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index 705158bec0b..2f9d526f6fb 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -17,7 +17,6 @@ extern "C" {
struct MEdge;
struct MLoop;
struct MLoopTri;
-struct MLoopUV;
struct MPoly;
struct MVert;
@@ -106,7 +105,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly,
const bool *hide_poly,
const bool *select_poly,
const struct MLoop *mloop,
- const struct MLoopUV *mloopuv,
+ const float (*mloopuv)[2],
unsigned int totpoly,
unsigned int totvert,
const float limit[2],
@@ -290,7 +289,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts,
/**
* Calculate UV islands.
*
- * \note If no MLoopUV layer is passed, we only consider edges tagged as seams as UV boundaries.
+ * \note If no UV layer is passed, we only consider edges tagged as seams as UV boundaries.
* This has the advantages of simplicity, and being valid/common to all UV maps.
* However, it means actual UV islands without matching UV seams will not be handled correctly.
* If a valid UV layer is passed as \a luvs parameter,
@@ -308,7 +307,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(struct MVert *verts,
int totpoly,
struct MLoop *loops,
int totloop,
- const struct MLoopUV *luvs,
+ const float (*luvs)[2],
MeshIslandStore *r_island_store);
/**
diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h
index 58142653a90..28c54ccbc02 100644
--- a/source/blender/blenkernel/BKE_mesh_tangent.h
+++ b/source/blender/blenkernel/BKE_mesh_tangent.h
@@ -22,7 +22,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const struct MVert *mverts,
const struct MLoop *mloops,
float (*r_looptangent)[4],
const float (*loopnors)[3],
- const struct MLoopUV *loopuv,
+ const float (*loopuv)[2],
int numLoops,
const struct MPoly *mpolys,
int numPolys,
@@ -50,7 +50,7 @@ void BKE_mesh_calc_loop_tangent_ex(const struct MVert *mvert,
struct CustomData *loopdata,
bool calc_active_tangent,
- const char (*tangent_names)[64],
+ const char (*tangent_names)[68 /*MAX_CUSTOMDATA_LAYER_NAME */],
int tangent_names_len,
const float (*vert_normals)[3],
const float (*poly_normals)[3],
@@ -63,7 +63,7 @@ void BKE_mesh_calc_loop_tangent_ex(const struct MVert *mvert,
void BKE_mesh_calc_loop_tangents(struct Mesh *me_eval,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len);
/* Helpers */
@@ -79,17 +79,18 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(struct CustomData *uv_data,
* Also, we calculate tangent_mask that works as a descriptor of tangents state.
* If tangent_mask has changed, then recalculate tangents.
*/
-void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
- bool calc_active_tangent,
- const char (*tangent_names)[64],
- int tangent_names_count,
- bool *rcalc_act,
- bool *rcalc_ren,
- int *ract_uv_n,
- int *rren_uv_n,
- char *ract_uv_name,
- char *rren_uv_name,
- short *rtangent_mask);
+void BKE_mesh_calc_loop_tangent_step_0(
+ const struct CustomData *loopData,
+ bool calc_active_tangent,
+ const char (*tangent_names)[68 /* MAX_CUSTOMDATA_LAYER_NAME */],
+ int tangent_names_count,
+ bool *rcalc_act,
+ bool *rcalc_ren,
+ int *ract_uv_n,
+ int *rren_uv_n,
+ char *ract_uv_name,
+ char *rren_uv_name,
+ short *rtangent_mask);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index bfdfc447baf..1d3e556db3e 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -1698,7 +1698,7 @@ static void object_get_datamask(const Depsgraph *depsgraph,
/* check if we need tfaces & mcols due to face select or texture paint */
if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) {
- r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR;
+ r_mask->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR;
r_mask->fmask |= CD_MASK_MTFACE;
}
diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc
index 80647362826..d9f8baeda1a 100644
--- a/source/blender/blenkernel/intern/attribute.cc
+++ b/source/blender/blenkernel/intern/attribute.cc
@@ -145,6 +145,7 @@ bool BKE_id_attribute_rename(ID *id,
const char *new_name,
ReportList *reports)
{
+ using namespace blender::bke;
if (BKE_id_attribute_required(id, old_name)) {
BLI_assert_msg(0, "Required attribute name is not editable");
return false;
@@ -166,6 +167,25 @@ bool BKE_id_attribute_rename(ID *id,
char result_name[MAX_CUSTOMDATA_LAYER_NAME];
BKE_id_attribute_calc_unique_name(id, new_name, result_name);
+
+ if (layer->type == CD_PROP_FLOAT2) {
+ /* Rename UV sub-attributes. */
+ char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
+ char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
+ BKE_id_attribute_rename(id,
+ get_uv_map_vert_selection_name(layer->name, buffer_src),
+ get_uv_map_vert_selection_name(result_name, buffer_dst),
+ reports);
+ BKE_id_attribute_rename(id,
+ get_uv_map_edge_selection_name(layer->name, buffer_src),
+ get_uv_map_edge_selection_name(result_name, buffer_dst),
+ reports);
+ BKE_id_attribute_rename(id,
+ get_uv_map_pin_name(layer->name, buffer_src),
+ get_uv_map_pin_name(result_name, buffer_dst),
+ reports);
+ }
+
BLI_strncpy_utf8(layer->name, result_name, sizeof(layer->name));
return true;
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index e5c43a3f90e..4bfd33bb5b5 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -58,8 +58,26 @@ const char *no_procedural_access_message =
bool allow_procedural_attribute_access(StringRef attribute_name)
{
- return !attribute_name.startswith(".sculpt") && !attribute_name.startswith(".select") &&
- !attribute_name.startswith(".hide");
+ if (attribute_name.startswith(".select")) {
+ return false;
+ }
+ if (attribute_name.startswith(".sculpt")) {
+ return false;
+ }
+ if (attribute_name.startswith(".hide")) {
+ return false;
+ }
+ if (attribute_name.startswith("." UV_VERTSEL_NAME ".")) {
+ return false;
+ }
+ if (attribute_name.startswith("." UV_EDGESEL_NAME ".")) {
+ return false;
+ }
+ if (attribute_name.startswith("." UV_PINNED_NAME ".")) {
+ return false;
+ }
+
+ return true;
}
static int attribute_data_type_complexity(const eCustomDataType data_type)
@@ -535,88 +553,6 @@ bool CustomDataAttributeProvider::foreach_attribute(const void *owner,
return true;
}
-GAttributeReader NamedLegacyCustomDataProvider::try_get_for_read(
- const void *owner, const AttributeIDRef &attribute_id) const
-{
- const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
- if (custom_data == nullptr) {
- return {};
- }
- for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
- if (layer.type == stored_type_) {
- if (custom_data_layer_matches_attribute_id(layer, attribute_id)) {
- const int domain_num = custom_data_access_.get_element_num(owner);
- return {as_read_attribute_(layer.data, domain_num), domain_};
- }
- }
- }
- return {};
-}
-
-GAttributeWriter NamedLegacyCustomDataProvider::try_get_for_write(
- void *owner, const AttributeIDRef &attribute_id) const
-{
- CustomData *custom_data = custom_data_access_.get_custom_data(owner);
- if (custom_data == nullptr) {
- return {};
- }
- for (CustomDataLayer &layer : MutableSpan(custom_data->layers, custom_data->totlayer)) {
- if (layer.type == stored_type_) {
- if (custom_data_layer_matches_attribute_id(layer, attribute_id)) {
- const int element_num = custom_data_access_.get_element_num(owner);
- void *data = CustomData_duplicate_referenced_layer_named(
- custom_data, stored_type_, layer.name, element_num);
- return {as_write_attribute_(data, element_num), domain_};
- }
- }
- }
- return {};
-}
-
-bool NamedLegacyCustomDataProvider::try_delete(void *owner,
- const AttributeIDRef &attribute_id) const
-{
- CustomData *custom_data = custom_data_access_.get_custom_data(owner);
- if (custom_data == nullptr) {
- return false;
- }
- for (const int i : IndexRange(custom_data->totlayer)) {
- const CustomDataLayer &layer = custom_data->layers[i];
- if (layer.type == stored_type_) {
- if (custom_data_layer_matches_attribute_id(layer, attribute_id)) {
- const int element_num = custom_data_access_.get_element_num(owner);
- CustomData_free_layer(custom_data, stored_type_, element_num, i);
- return true;
- }
- }
- }
- return false;
-}
-
-bool NamedLegacyCustomDataProvider::foreach_attribute(
- const void *owner, const AttributeForeachCallback callback) const
-{
- const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
- if (custom_data == nullptr) {
- return true;
- }
- for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
- if (layer.type == stored_type_) {
- AttributeMetaData meta_data{domain_, attribute_type_};
- if (!callback(layer.name, meta_data)) {
- return false;
- }
- }
- }
- return true;
-}
-
-void NamedLegacyCustomDataProvider::foreach_domain(
- const FunctionRef<void(eAttrDomain)> callback) const
-{
- callback(domain_);
-}
-
CustomDataAttributes::CustomDataAttributes()
{
CustomData_reset(&data);
diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh
index 33d415f1e0e..e6ae12af77d 100644
--- a/source/blender/blenkernel/intern/attribute_access_intern.hh
+++ b/source/blender/blenkernel/intern/attribute_access_intern.hh
@@ -170,44 +170,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider {
}
};
-/**
- * This attribute provider is used for uv maps and vertex colors.
- */
-class NamedLegacyCustomDataProvider final : public DynamicAttributesProvider {
- private:
- using AsReadAttribute = GVArray (*)(const void *data, int domain_num);
- using AsWriteAttribute = GVMutableArray (*)(void *data, int domain_num);
- const eAttrDomain domain_;
- const eCustomDataType attribute_type_;
- const eCustomDataType stored_type_;
- const CustomDataAccessInfo custom_data_access_;
- const AsReadAttribute as_read_attribute_;
- const AsWriteAttribute as_write_attribute_;
-
- public:
- NamedLegacyCustomDataProvider(const eAttrDomain domain,
- const eCustomDataType attribute_type,
- const eCustomDataType stored_type,
- const CustomDataAccessInfo custom_data_access,
- const AsReadAttribute as_read_attribute,
- const AsWriteAttribute as_write_attribute)
- : domain_(domain),
- attribute_type_(attribute_type),
- stored_type_(stored_type),
- custom_data_access_(custom_data_access),
- as_read_attribute_(as_read_attribute),
- as_write_attribute_(as_write_attribute)
- {
- }
-
- GAttributeReader try_get_for_read(const void *owner,
- const AttributeIDRef &attribute_id) const final;
- GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final;
- bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final;
- bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final;
- void foreach_domain(const FunctionRef<void(eAttrDomain)> callback) const final;
-};
-
template<typename T> GVArray make_array_read_attribute(const void *data, const int domain_num)
{
return VArray<T>::ForSpan(Span<T>((const T *)data, domain_num));
diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc
index bccb625feb2..b09ee75f1c6 100644
--- a/source/blender/blenkernel/intern/customdata.cc
+++ b/source/blender/blenkernel/intern/customdata.cc
@@ -59,6 +59,7 @@
/* only for customdata_data_transfer_interp_normal_normals */
#include "data_transfer_intern.h"
+using blender::float2;
using blender::IndexRange;
using blender::Set;
using blender::Span;
@@ -1012,110 +1013,9 @@ static void layerInterp_mloopcol(const void **sources,
/** \} */
/* -------------------------------------------------------------------- */
-/** \name Callbacks for (#MLoopUV, #CD_MLOOPUV)
+/** \name Callbacks for #OrigSpaceLoop
* \{ */
-static void layerCopyValue_mloopuv(const void *source,
- void *dest,
- const int mixmode,
- const float mixfactor)
-{
- const MLoopUV *luv1 = static_cast<const MLoopUV *>(source);
- MLoopUV *luv2 = static_cast<MLoopUV *>(dest);
-
- /* We only support a limited subset of advanced mixing here -
- * namely the mixfactor interpolation. */
-
- if (mixmode == CDT_MIX_NOMIX) {
- copy_v2_v2(luv2->uv, luv1->uv);
- }
- else {
- interp_v2_v2v2(luv2->uv, luv2->uv, luv1->uv, mixfactor);
- }
-}
-
-static bool layerEqual_mloopuv(const void *data1, const void *data2)
-{
- const MLoopUV *luv1 = static_cast<const MLoopUV *>(data1);
- const MLoopUV *luv2 = static_cast<const MLoopUV *>(data2);
-
- return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
-}
-
-static void layerMultiply_mloopuv(void *data, const float fac)
-{
- MLoopUV *luv = static_cast<MLoopUV *>(data);
-
- mul_v2_fl(luv->uv, fac);
-}
-
-static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
-{
- MLoopUV *min = static_cast<MLoopUV *>(vmin);
- MLoopUV *max = static_cast<MLoopUV *>(vmax);
-
- INIT_MINMAX2(min->uv, max->uv);
-}
-
-static void layerDoMinMax_mloopuv(const void *data, void *vmin, void *vmax)
-{
- const MLoopUV *luv = static_cast<const MLoopUV *>(data);
- MLoopUV *min = static_cast<MLoopUV *>(vmin);
- MLoopUV *max = static_cast<MLoopUV *>(vmax);
-
- minmax_v2v2_v2(min->uv, max->uv, luv->uv);
-}
-
-static void layerAdd_mloopuv(void *data1, const void *data2)
-{
- MLoopUV *l1 = static_cast<MLoopUV *>(data1);
- const MLoopUV *l2 = static_cast<const MLoopUV *>(data2);
-
- add_v2_v2(l1->uv, l2->uv);
-}
-
-static void layerInterp_mloopuv(const void **sources,
- const float *weights,
- const float * /*sub_weights*/,
- int count,
- void *dest)
-{
- float uv[2];
- int flag = 0;
-
- zero_v2(uv);
-
- for (int i = 0; i < count; i++) {
- const float interp_weight = weights[i];
- const MLoopUV *src = static_cast<const MLoopUV *>(sources[i]);
- madd_v2_v2fl(uv, src->uv, interp_weight);
- if (interp_weight > 0.0f) {
- flag |= src->flag;
- }
- }
-
- /* Delay writing to the destination in case dest is in sources. */
- copy_v2_v2(((MLoopUV *)dest)->uv, uv);
- ((MLoopUV *)dest)->flag = flag;
-}
-
-static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes)
-{
- MLoopUV *uv = static_cast<MLoopUV *>(data);
- bool has_errors = false;
-
- for (int i = 0; i < totitems; i++, uv++) {
- if (!is_finite_v2(uv->uv)) {
- if (do_fixes) {
- zero_v2(uv->uv);
- }
- has_errors = true;
- }
- }
-
- return has_errors;
-}
-
/* origspace is almost exact copy of mloopuv's, keep in sync */
static void layerCopyValue_mloop_origspace(const void *source,
void *dest,
@@ -1617,6 +1517,47 @@ static bool layerValidate_propfloat2(void *data, const uint totitems, const bool
return has_errors;
}
+static bool layerEqual_propfloat2(const void *data1, const void *data2)
+{
+ const float2 &a = *static_cast<const float2 *>(data1);
+ const float2 &b = *static_cast<const float2 *>(data2);
+
+ return blender::math::distance_squared(a, b) < 0.00001f;
+}
+
+static void layerInitMinMax_propfloat2(void *vmin, void *vmax)
+{
+ float2 &min = *static_cast<float2 *>(vmin);
+ float2 &max = *static_cast<float2 *>(vmax);
+ INIT_MINMAX2(min, max);
+}
+
+static void layerDoMinMax_propfloat2(const void *data, void *vmin, void *vmax)
+{
+ const float2 &value = *static_cast<const float2 *>(data);
+ float2 &a = *static_cast<float2 *>(vmin);
+ float2 &b = *static_cast<float2 *>(vmax);
+ blender::math::min_max(value, a, b);
+}
+
+static void layerCopyValue_propfloat2(const void *source,
+ void *dest,
+ const int mixmode,
+ const float mixfactor)
+{
+ const float2 &a = *static_cast<const float2 *>(source);
+ float2 &b = *static_cast<float2 *>(dest);
+
+ /* We only support a limited subset of advanced mixing here-
+ * namely the mixfactor interpolation. */
+ if (mixmode == CDT_MIX_NOMIX) {
+ b = a;
+ }
+ else {
+ b = blender::math::interpolate(b, a, mixfactor);
+ }
+}
+
/** \} */
/* -------------------------------------------------------------------- */
@@ -1758,28 +1699,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* NOTE: when we expose the UV Map / TexFace split to the user,
* change this back to face Texture. */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
- /* 16: CD_MLOOPUV */
- {sizeof(MLoopUV),
- "MLoopUV",
- 1,
- N_("UVMap"),
- nullptr,
- nullptr,
- layerInterp_mloopuv,
- nullptr,
- nullptr,
- nullptr,
- layerValidate_mloopuv,
- layerEqual_mloopuv,
- layerMultiply_mloopuv,
- layerInitMinMax_mloopuv,
- layerAdd_mloopuv,
- layerDoMinMax_mloopuv,
- layerCopyValue_mloopuv,
- nullptr,
- nullptr,
- nullptr,
- layerMaxNum_tface},
+ /* 16: CD_MLOOPUV */ /* DEPRECATED */
+ {sizeof(MLoopUV), "MLoopUV", 1, N_("UVMap")},
/* 17: CD_PROP_BYTE_COLOR */
{sizeof(MLoopCol),
"MLoopCol",
@@ -2026,10 +1947,12 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
nullptr,
nullptr,
layerValidate_propfloat2,
- nullptr,
+ layerEqual_propfloat2,
layerMultiply_propfloat2,
- nullptr,
- layerAdd_propfloat2},
+ layerInitMinMax_propfloat2,
+ layerAdd_propfloat2,
+ layerDoMinMax_propfloat2,
+ layerCopyValue_propfloat2},
/* 50: CD_PROP_BOOL */
{sizeof(bool),
"bool",
@@ -2129,8 +2052,8 @@ const CustomData_MeshMasks CD_MASK_MESH = {
/* pmask */
(CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/* lmask */
- (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL |
- CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
+ (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK |
+ CD_MASK_PROP_ALL),
};
const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
/* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN |
@@ -2143,8 +2066,8 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
/* pmask */
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
/* lmask */
- (CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL |
- CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */
+ (CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
+ CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */
};
const CustomData_MeshMasks CD_MASK_BMESH = {
/* vmask */ (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY |
@@ -2154,8 +2077,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
/* pmask */
(CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
/* lmask */
- (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK |
- CD_MASK_PROP_ALL),
+ (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
const CustomData_MeshMasks CD_MASK_EVERYTHING = {
/* vmask */ (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT |
@@ -2173,7 +2095,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
(CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP |
CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/* lmask */
- (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPUV |
+ (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL |
CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL |
CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index e6afca11b40..c57f8bb37bd 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -67,7 +67,7 @@ void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types,
r_data_masks->vmask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
}
else if (cddata_type == CD_FAKE_UV) {
- r_data_masks->lmask |= CD_MASK_MLOOPUV;
+ r_data_masks->lmask |= CD_MASK_PROP_FLOAT2;
}
else if (cddata_type == CD_FAKE_LNOR) {
r_data_masks->lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL;
@@ -984,7 +984,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
else if (elem_type == ME_LOOP) {
if (cddata_type == CD_FAKE_UV) {
- cddata_type = CD_MLOOPUV;
+ cddata_type = CD_PROP_FLOAT2;
}
else if (cddata_type == CD_FAKE_LNOR) {
/* Pre-process should have generated it,
@@ -1023,7 +1023,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
else if (elem_type == ME_POLY) {
if (cddata_type == CD_FAKE_UV) {
- cddata_type = CD_MLOOPUV;
+ cddata_type = CD_PROP_FLOAT2;
}
if (!(cddata_type & CD_FAKE)) {
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index e0ae3f42be6..11307c726d5 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -1468,7 +1468,7 @@ typedef struct DynamicPaintSetInitColorData {
const DynamicPaintSurface *surface;
const MLoop *mloop;
- const MLoopUV *mloopuv;
+ const float (*mloopuv)[2];
const MLoopTri *mlooptri;
const MLoopCol *mloopcol;
struct ImagePool *pool;
@@ -1486,7 +1486,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
const MLoop *mloop = data->mloop;
const MLoopTri *mlooptri = data->mlooptri;
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
struct ImagePool *pool = data->pool;
Tex *tex = data->surface->init_texture;
@@ -1499,8 +1499,8 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
const uint vert = mloop[mlooptri[i].tri[j]].v;
/* remap to [-1.0, 1.0] */
- uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f;
- uv[1] = mloopuv[mlooptri[i].tri[j]].uv[1] * 2.0f - 1.0f;
+ uv[0] = mloopuv[mlooptri[i].tri[j]][0] * 2.0f - 1.0f;
+ uv[1] = mloopuv[mlooptri[i].tri[j]][1] * 2.0f - 1.0f;
multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false);
@@ -1520,7 +1520,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb(
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
const MLoopTri *mlooptri = data->mlooptri;
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
Tex *tex = data->surface->init_texture;
ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
const int samples = (data->surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
@@ -1534,7 +1534,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb(
/* collect all uvs */
for (int j = 3; j--;) {
- copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]].uv);
+ copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]]);
}
/* interpolate final uv pos */
@@ -1615,8 +1615,9 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
}
/* get uv map */
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->init_layername, uvname);
- const MLoopUV *mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
+ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->init_layername, uvname);
+ const float(*mloopuv)[2] = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname);
+
if (!mloopuv) {
return;
}
@@ -2185,7 +2186,7 @@ typedef struct DynamicPaintCreateUVSurfaceData {
Vec3f *tempWeights;
const MLoopTri *mlooptri;
- const MLoopUV *mloopuv;
+ const float (*mloopuv)[2];
const MLoop *mloop;
const int tottri;
@@ -2203,7 +2204,7 @@ static void dynamic_paint_create_uv_surface_direct_cb(
Vec3f *tempWeights = data->tempWeights;
const MLoopTri *mlooptri = data->mlooptri;
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
const MLoop *mloop = data->mloop;
const int tottri = data->tottri;
@@ -2256,9 +2257,9 @@ static void dynamic_paint_create_uv_surface_direct_cb(
continue;
}
- const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv;
- const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv;
- const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv;
+ const float *uv1 = mloopuv[mlooptri[i].tri[0]];
+ const float *uv2 = mloopuv[mlooptri[i].tri[1]];
+ const float *uv3 = mloopuv[mlooptri[i].tri[2]];
/* If point is inside the face */
if (isect_point_tri_v2(point[sample], uv1, uv2, uv3) != 0) {
@@ -2298,7 +2299,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(
Vec3f *tempWeights = data->tempWeights;
const MLoopTri *mlooptri = data->mlooptri;
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
const MLoop *mloop = data->mloop;
uint32_t *active_points = data->active_points;
@@ -2339,9 +2340,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(
if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) {
float uv[2];
const int i = tempPoints[ind].tri_index;
- const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv;
- const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv;
- const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv;
+ const float *uv1 = mloopuv[mlooptri[i].tri[0]];
+ const float *uv2 = mloopuv[mlooptri[i].tri[1]];
+ const float *uv3 = mloopuv[mlooptri[i].tri[2]];
/* tri index */
/* There is a low possibility of actually having a neighbor point which tri is
@@ -2385,7 +2386,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(
#undef JITTER_SAMPLES
static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri,
- const MLoopUV *mloopuv,
+ const float (*mloopuv)[2],
int tri_index,
const float point[2])
{
@@ -2396,8 +2397,8 @@ static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri,
for (int i = 0; i < 3; i++) {
const float dist_squared = dist_squared_to_line_segment_v2(
point,
- mloopuv[mlooptri[tri_index].tri[(i + 0)]].uv,
- mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]].uv);
+ mloopuv[mlooptri[tri_index].tri[(i + 0)]],
+ mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]]);
if (dist_squared < min_distance) {
min_distance = dist_squared;
@@ -2510,7 +2511,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
{
const MLoop *mloop = data->mloop;
const MLoopTri *mlooptri = data->mlooptri;
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
const uint *loop_idx = mlooptri[tri_index].tri;
@@ -2523,9 +2524,9 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
float uv0[2], uv1[2], uv2[2];
- copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]].uv);
- copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]].uv);
- copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]].uv);
+ copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]]);
+ copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]]);
+ copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]]);
/* Verify the target point is on the opposite side of the edge from the third triangle
* vertex, to ensure that we always move closer to the goal point. */
@@ -2576,13 +2577,13 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
/* Allow for swapped vertex order */
if (overt0 == vert0 && overt1 == vert1) {
found_other = true;
- copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]].uv);
- copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]].uv);
+ copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]]);
+ copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]]);
}
else if (overt0 == vert1 && overt1 == vert0) {
found_other = true;
- copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 0)]].uv);
- copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 1) % 3]].uv);
+ copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 0)]]);
+ copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 1) % 3]]);
}
if (found_other) {
@@ -2805,7 +2806,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
PaintUVPoint *tempPoints = NULL;
Vec3f *tempWeights = NULL;
const MLoopTri *mlooptri = NULL;
- const MLoopUV *mloopuv = NULL;
+ const float(*mloopuv)[2] = NULL;
const MLoop *mloop = NULL;
Bounds2D *faceBB = NULL;
@@ -2826,9 +2827,9 @@ int dynamicPaint_createUVSurface(Scene *scene,
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
/* get uv map */
- if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->uvlayer_name, uvname);
- mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
+ if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
+ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname);
+ mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname);
}
/* Check for validity */
@@ -2887,11 +2888,11 @@ int dynamicPaint_createUVSurface(Scene *scene,
if (!error) {
for (int i = 0; i < tottri; i++) {
- copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]].uv);
- copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]].uv);
+ copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]]);
+ copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]]);
for (int j = 1; j < 3; j++) {
- minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]].uv);
+ minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]]);
}
}
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.cc b/source/blender/blenkernel/intern/editmesh_tangent.cc
index 12799afd2f7..6af839585f7 100644
--- a/source/blender/blenkernel/intern/editmesh_tangent.cc
+++ b/source/blender/blenkernel/intern/editmesh_tangent.cc
@@ -151,7 +151,7 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void *
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
const float (*poly_normals)[3],
const float (*loop_normals)[3],
@@ -254,7 +254,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
/* NOTE: we assume we do have tessellated loop normals at this point
* (in case it is object-enabled), have to check this is valid. */
mesh2tangent->precomputedLoopNormals = loop_normals;
- mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, n);
+ mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, n);
/* needed for indexing loop-tangents */
int htype_index = BM_LOOP;
@@ -270,8 +270,8 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
else {
/* Fill the resulting tangent_mask */
int uv_ind = CustomData_get_named_layer_index(
- &bm->ldata, CD_MLOOPUV, loopdata_out->layers[index].name);
- int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
+ &bm->ldata, CD_PROP_FLOAT2, loopdata_out->layers[index].name);
+ int uv_start = CustomData_get_layer_index(&bm->ldata, CD_PROP_FLOAT2);
BLI_assert(uv_ind != -1 && uv_start != -1);
BLI_assert(uv_ind - uv_start < MAX_MTFACE);
tangent_mask_curr |= 1 << (uv_ind - uv_start);
@@ -306,7 +306,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
*tangent_mask_curr_p = tangent_mask_curr;
- int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
+ int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_PROP_FLOAT2, act_uv_n);
if (act_uv_index >= 0) {
int tan_index = CustomData_get_named_layer_index(
loopdata_out, CD_TANGENT, bm->ldata.layers[act_uv_index].name);
@@ -314,7 +314,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
} /* else tangent has been built from orco */
/* Update render layer index */
- int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
+ int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_PROP_FLOAT2, ren_uv_n);
if (ren_uv_index >= 0) {
int tan_index = CustomData_get_named_layer_index(
loopdata_out, CD_TANGENT, bm->ldata.layers[ren_uv_index].name);
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index c72f498cd5a..7409435e54a 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -1788,7 +1788,7 @@ static void sample_mesh(FluidFlowSettings *ffs,
const float (*vert_normals)[3],
const MLoop *mloop,
const MLoopTri *mlooptri,
- const MLoopUV *mloopuv,
+ const float (*mloopuv)[2],
float *influence_map,
float *velocity_map,
int index,
@@ -1907,9 +1907,9 @@ static void sample_mesh(FluidFlowSettings *ffs,
}
else if (mloopuv) {
const float *uv[3];
- uv[0] = mloopuv[mlooptri[f_index].tri[0]].uv;
- uv[1] = mloopuv[mlooptri[f_index].tri[1]].uv;
- uv[2] = mloopuv[mlooptri[f_index].tri[2]].uv;
+ uv[0] = mloopuv[mlooptri[f_index].tri[0]];
+ uv[1] = mloopuv[mlooptri[f_index].tri[1]];
+ uv[2] = mloopuv[mlooptri[f_index].tri[2]];
interp_v2_v2v2v2(tex_co, UNPACK3(uv), weights);
@@ -1982,7 +1982,7 @@ typedef struct EmitFromDMData {
const float (*vert_normals)[3];
const MLoop *mloop;
const MLoopTri *mlooptri;
- const MLoopUV *mloopuv;
+ const float (*mloopuv)[2];
const MDeformVert *dvert;
int defgrp_index;
@@ -2068,7 +2068,8 @@ static void emit_from_mesh(
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
const int numverts = me->totvert;
const MDeformVert *dvert = BKE_mesh_deform_verts(me);
- const MLoopUV *mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ffs->uvlayer_name);
+ const float(*mloopuv)[2] = CustomData_get_layer_named(
+ &me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name);
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
vert_vel = MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_velocity");
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index d148d59a48b..805e583a5d0 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -930,16 +930,6 @@ static void set_shade_smooth(MPoly &mpoly, bool value)
SET_FLAG_FROM_TEST(mpoly.flag, value, ME_SMOOTH);
}
-static float2 get_loop_uv(const MLoopUV &uv)
-{
- return float2(uv.uv);
-}
-
-static void set_loop_uv(MLoopUV &uv, float2 co)
-{
- copy_v2_v2(uv.uv, co);
-}
-
static float get_crease(const float &crease)
{
return crease;
@@ -1301,14 +1291,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
make_derived_write_attribute<float, float, get_crease, set_crease>,
nullptr);
- static NamedLegacyCustomDataProvider uvs(
- ATTR_DOMAIN_CORNER,
- CD_PROP_FLOAT2,
- CD_MLOOPUV,
- corner_access,
- make_derived_read_attribute<MLoopUV, float2, get_loop_uv>,
- make_derived_write_attribute<MLoopUV, float2, get_loop_uv, set_loop_uv>);
-
static VertexGroupsAttributeProvider vertex_groups;
static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access);
static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access);
@@ -1317,8 +1299,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
return ComponentAttributeProviders(
{&position, &id, &material_index, &shade_smooth, &normal, &crease},
- {&uvs,
- &corner_custom_data,
+ {&corner_custom_data,
&vertex_groups,
&point_custom_data,
&edge_custom_data,
diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c
index 23067d1a4e3..11bd82601f8 100644
--- a/source/blender/blenkernel/intern/layer_utils.c
+++ b/source/blender/blenkernel/intern/layer_utils.c
@@ -248,7 +248,7 @@ bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void *UNUSED(user
const Mesh *me = ob->data;
const BMEditMesh *em = me->edit_mesh;
if (em != NULL) {
- if (CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV) != -1) {
+ if (CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) {
return true;
}
}
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index 2d613f24a0a..53c61a1a5e7 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -231,6 +231,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
Vector<CustomDataLayer, 16> edge_layers;
Vector<CustomDataLayer, 16> loop_layers;
Vector<CustomDataLayer, 16> poly_layers;
+ blender::ResourceScope temp_arrays_for_legacy_format;
/* cache only - don't write */
mesh->mface = nullptr;
@@ -282,6 +283,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip);
CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip);
CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip);
+
+ if (!BLO_write_is_undo(writer)) {
+ BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers);
+ }
}
BLO_write_id_struct(writer, Mesh, id_address, &mesh->id);
@@ -475,12 +480,10 @@ static const char *cmpcode_to_str(int code)
static int customdata_compare(
CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh)
{
- const float thresh_sq = thresh * thresh;
CustomDataLayer *l1, *l2;
int layer_count1 = 0, layer_count2 = 0, j;
const uint64_t cd_mask_non_generic = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MPOLY |
- CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR |
- CD_MASK_MDEFORMVERT;
+ CD_MASK_PROP_BYTE_COLOR | CD_MASK_MDEFORMVERT;
const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic;
const Span<MLoop> loops_1 = m1->loops();
const Span<MLoop> loops_2 = m2->loops();
@@ -488,19 +491,28 @@ static int customdata_compare(
for (int i = 0; i < c1->totlayer; i++) {
l1 = &c1->layers[i];
if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr) {
- layer_count1++;
+ /* TODO(@Baardaap): This if statement is only added to be able to use the old test files
+ * in the tests. It should be removed once the test file is updated. */
+ if (l1->name[0] != '.') {
+ layer_count1++;
+ }
}
}
for (int i = 0; i < c2->totlayer; i++) {
l2 = &c2->layers[i];
if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr) {
- layer_count2++;
+ /* TODO(@Baardaap): This if statement is only added to be able to use the old test files
+ * in the tests. It should be removed once the test file is updated. */
+ if (l2->name[0] != '.') {
+ layer_count2++;
+ }
}
}
if (layer_count1 != layer_count2) {
- /* TODO(@HooglyBoogly): Re-enable after tests are updated for material index refactor. */
+ /* TODO(@HooglyBoogly): Re-enable after tests are updated for material index refactor and UV as
+ * generic attribute refactor. */
// return MESHCMP_CDLAYERS_MISMATCH;
}
@@ -588,18 +600,6 @@ static int customdata_compare(
}
break;
}
- case CD_MLOOPUV: {
- MLoopUV *lp1 = (MLoopUV *)l1->data;
- MLoopUV *lp2 = (MLoopUV *)l2->data;
- int ltot = m1->totloop;
-
- for (j = 0; j < ltot; j++, lp1++, lp2++) {
- if (len_squared_v2v2(lp1->uv, lp2->uv) > thresh_sq) {
- return MESHCMP_LOOPUVMISMATCH;
- }
- }
- break;
- }
case CD_PROP_BYTE_COLOR: {
MLoopCol *lp1 = (MLoopCol *)l1->data;
MLoopCol *lp2 = (MLoopCol *)l2->data;
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 2255038a991..a1ab10c8ef8 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -198,8 +198,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
MutableAttributeAccessor attributes = mesh->attributes_for_write();
SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>(
"material_index", ATTR_DOMAIN_FACE);
- MLoopUV *mloopuv = static_cast<MLoopUV *>(CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, "UVMap"));
+ blender::float2 *mloopuv = static_cast<blender::float2 *>(CustomData_add_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, "UVMap"));
/* verts and faces */
vertcount = 0;
@@ -280,8 +280,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
if (mloopuv) {
for (int i = 0; i < 3; i++, mloopuv++) {
- mloopuv->uv[0] = (mloop[i].v - startvert) / float(dl->nr - 1);
- mloopuv->uv[1] = 0.0f;
+ (*mloopuv)[0] = (mloop[i].v - startvert) / float(dl->nr - 1);
+ (*mloopuv)[1] = 0.0f;
}
}
@@ -357,15 +357,15 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
/* find uv based on vertex index into grid array */
int v = mloop[i].v - startvert;
- mloopuv->uv[0] = (v / dl->nr) / float(orco_sizev);
- mloopuv->uv[1] = (v % dl->nr) / float(orco_sizeu);
+ (*mloopuv)[0] = (v / dl->nr) / float(orco_sizev);
+ (*mloopuv)[1] = (v % dl->nr) / float(orco_sizeu);
/* cyclic correction */
- if (ELEM(i, 1, 2) && mloopuv->uv[0] == 0.0f) {
- mloopuv->uv[0] = 1.0f;
+ if ((ELEM(i, 1, 2)) && (*mloopuv)[0] == 0.0f) {
+ (*mloopuv)[0] = 1.0f;
}
- if (ELEM(i, 0, 1) && mloopuv->uv[1] == 0.0f) {
- mloopuv->uv[1] = 1.0f;
+ if ((ELEM(i, 0, 1)) && (*mloopuv)[1] == 0.0f) {
+ (*mloopuv)[1] = 1.0f;
}
}
}
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index 9a199c9c768..e67733668cd 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -216,24 +216,6 @@ float BKE_mesh_calc_area(const Mesh *me)
return total_area;
}
-float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array)
-{
-
- int i, l_iter = mpoly->loopstart;
- float area;
- float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, size_t(mpoly->totloop));
-
- /* pack vertex cos into an array for area_poly_v2 */
- for (i = 0; i < mpoly->totloop; i++, l_iter++) {
- copy_v2_v2(vertexcos[i], uv_array[l_iter].uv);
- }
-
- /* finally calculate the area */
- area = area_poly_v2(vertexcos, uint(mpoly->totloop));
-
- return area;
-}
-
static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly,
const MLoop *loopstart,
const MVert *mvarray,
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index 23426f8c087..c1419f2aaae 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -17,6 +17,7 @@
#include "BLI_edgehash.h"
#include "BLI_math.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_memarena.h"
#include "BLI_polyfill_2d.h"
#include "BLI_task.hh"
@@ -300,17 +301,18 @@ static void bm_corners_to_loops_ex(ID *id,
for (int i = 0; i < numTex; i++) {
const MTFace *texface = (const MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i);
- MLoopUV *mloopuv = (MLoopUV *)CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
- copy_v2_v2(mloopuv->uv, texface->uv[0]);
- mloopuv++;
- copy_v2_v2(mloopuv->uv, texface->uv[1]);
- mloopuv++;
- copy_v2_v2(mloopuv->uv, texface->uv[2]);
- mloopuv++;
+ blender::float2 *uv = static_cast<blender::float2 *>(
+ CustomData_get_n(ldata, CD_PROP_FLOAT2, loopstart, i));
+ copy_v2_v2(*uv, texface->uv[0]);
+ uv++;
+ copy_v2_v2(*uv, texface->uv[1]);
+ uv++;
+ copy_v2_v2(*uv, texface->uv[2]);
+ uv++;
if (mf->v4) {
- copy_v2_v2(mloopuv->uv, texface->uv[3]);
- mloopuv++;
+ copy_v2_v2(*uv, texface->uv[3]);
+ uv++;
}
}
@@ -391,7 +393,7 @@ static void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int to
for (int i = 0; i < fdata->totlayer; i++) {
if (fdata->layers[i].type == CD_MTFACE) {
CustomData_add_layer_named(
- ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, totloop, fdata->layers[i].name);
+ ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, totloop, fdata->layers[i].name);
}
else if (fdata->layers[i].type == CD_MCOL) {
CustomData_add_layer_named(
@@ -534,17 +536,17 @@ static void update_active_fdata_layers(CustomData *fdata, CustomData *ldata)
{
int act;
- if (CustomData_has_layer(ldata, CD_MLOOPUV)) {
- act = CustomData_get_active_layer(ldata, CD_MLOOPUV);
+ if (CustomData_has_layer(ldata, CD_PROP_FLOAT2)) {
+ act = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_active(fdata, CD_MTFACE, act);
- act = CustomData_get_render_layer(ldata, CD_MLOOPUV);
+ act = CustomData_get_render_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_render(fdata, CD_MTFACE, act);
- act = CustomData_get_clone_layer(ldata, CD_MLOOPUV);
+ act = CustomData_get_clone_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_clone(fdata, CD_MTFACE, act);
- act = CustomData_get_stencil_layer(ldata, CD_MLOOPUV);
+ act = CustomData_get_stencil_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_stencil(fdata, CD_MTFACE, act);
}
@@ -577,7 +579,7 @@ static bool check_matching_legacy_layer_counts(CustomData *fdata, CustomData *ld
((a_num += CustomData_number_of_layers(l_a, t_a)) == \
(b_num += CustomData_number_of_layers(l_b, t_b)))
- if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) {
+ if (!LAYER_CMP(ldata, CD_PROP_FLOAT2, fdata, CD_MTFACE)) {
return false;
}
if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) {
@@ -610,7 +612,7 @@ static void add_mface_layers(CustomData *fdata, CustomData *ldata, int total)
BLI_assert(!check_matching_legacy_layer_counts(fdata, ldata, false));
for (int i = 0; i < ldata->totlayer; i++) {
- if (ldata->layers[i].type == CD_MLOOPUV) {
+ if (ldata->layers[i].type == CD_PROP_FLOAT2) {
CustomData_add_layer_named(
fdata, CD_MTFACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name);
}
@@ -648,7 +650,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
* Callers could also check but safer to do here - campbell */
}
else {
- const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
@@ -667,7 +669,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
* some info to help troubleshoot what's going on. */
printf(
"%s: warning! Tessellation uvs or vcol data got out of sync, "
- "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
+ "had to reset!\n CD_MTFACE: %d != CD_PROP_FLOAT2: %d || CD_MCOL: %d != "
"CD_PROP_BYTE_COLOR: "
"%d\n",
__func__,
@@ -710,16 +712,16 @@ static void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata,
if (CustomData_has_layer(fdata, CD_MTFACE)) {
act = CustomData_get_active_layer(fdata, CD_MTFACE);
- CustomData_set_layer_active(ldata, CD_MLOOPUV, act);
+ CustomData_set_layer_active(ldata, CD_PROP_FLOAT2, act);
act = CustomData_get_render_layer(fdata, CD_MTFACE);
- CustomData_set_layer_render(ldata, CD_MLOOPUV, act);
+ CustomData_set_layer_render(ldata, CD_PROP_FLOAT2, act);
act = CustomData_get_clone_layer(fdata, CD_MTFACE);
- CustomData_set_layer_clone(ldata, CD_MLOOPUV, act);
+ CustomData_set_layer_clone(ldata, CD_PROP_FLOAT2, act);
act = CustomData_get_stencil_layer(fdata, CD_MTFACE);
- CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act);
+ CustomData_set_layer_stencil(ldata, CD_PROP_FLOAT2, act);
}
if (CustomData_has_layer(fdata, CD_MCOL)) {
@@ -785,7 +787,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata,
* we could be ~25% quicker with dedicated code.
* The issue is, unless having two different functions with nearly the same code,
* there's not much ways to solve this. Better IMHO to live with it for now (sigh). */
- const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV);
+ const int numUV = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2);
const int numCol = CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR);
const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL);
const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP);
@@ -797,12 +799,13 @@ static void mesh_loops_to_tessdata(CustomData *fdata,
for (i = 0; i < numUV; i++) {
MTFace *texface = (MTFace *)CustomData_get_layer_n(fdata, CD_MTFACE, i);
- const MLoopUV *mloopuv = (const MLoopUV *)CustomData_get_layer_n(ldata, CD_MLOOPUV, i);
+ const blender::float2 *uv = static_cast<const blender::float2 *>(
+ CustomData_get_layer_n(ldata, CD_PROP_FLOAT2, i));
for (findex = 0, pidx = polyindices, lidx = loopindices; findex < num_faces;
pidx++, lidx++, findex++, texface++) {
for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) {
- copy_v2_v2(texface->uv[j], mloopuv[(*lidx)[j]].uv);
+ copy_v2_v2(texface->uv[j], uv[(*lidx)[j]]);
}
}
}
@@ -1460,6 +1463,179 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Generic UV Map Conversion
+ * \{ */
+
+void BKE_mesh_legacy_convert_uvs_to_struct(
+ Mesh *mesh,
+ blender::ResourceScope &temp_mloopuv_for_convert,
+ blender::Vector<CustomDataLayer, 16> &face_corner_layers_to_write)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ const AttributeAccessor attributes = mesh->attributes();
+ Vector<CustomDataLayer, 16> new_layer_to_write;
+
+ /* Don't write the boolean UV map sublayers which will be written in the legacy #MLoopUV type. */
+ Set<std::string> uv_sublayers_to_skip;
+ char vert_name[MAX_CUSTOMDATA_LAYER_NAME];
+ char edge_name[MAX_CUSTOMDATA_LAYER_NAME];
+ char pin_name[MAX_CUSTOMDATA_LAYER_NAME];
+ for (const CustomDataLayer &layer : face_corner_layers_to_write) {
+ uv_sublayers_to_skip.add_multiple_new({get_uv_map_vert_selection_name(layer.name, vert_name),
+ get_uv_map_edge_selection_name(layer.name, edge_name),
+ get_uv_map_pin_name(layer.name, pin_name)});
+ }
+
+ for (const CustomDataLayer &layer : face_corner_layers_to_write) {
+ if (uv_sublayers_to_skip.contains_as(layer.name)) {
+ continue;
+ }
+ if (layer.type != CD_PROP_FLOAT2) {
+ new_layer_to_write.append(layer);
+ continue;
+ }
+ const Span<float2> coords{static_cast<const float2 *>(layer.data), mesh->totloop};
+ CustomDataLayer mloopuv_layer = layer;
+ mloopuv_layer.type = CD_MLOOPUV;
+ MutableSpan<MLoopUV> mloopuv = temp_mloopuv_for_convert.construct<Array<MLoopUV>>(
+ mesh->totloop);
+ mloopuv_layer.data = mloopuv.data();
+
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const VArray<bool> vert_selection = attributes.lookup_or_default<bool>(
+ get_uv_map_vert_selection_name(layer.name, buffer), ATTR_DOMAIN_CORNER, false);
+ const VArray<bool> edge_selection = attributes.lookup_or_default<bool>(
+ get_uv_map_edge_selection_name(layer.name, buffer), ATTR_DOMAIN_CORNER, false);
+ const VArray<bool> pin = attributes.lookup_or_default<bool>(
+ get_uv_map_pin_name(layer.name, buffer), ATTR_DOMAIN_CORNER, false);
+
+ threading::parallel_for(mloopuv.index_range(), 2048, [&](IndexRange range) {
+ for (const int i : range) {
+ copy_v2_v2(mloopuv[i].uv, coords[i]);
+ SET_FLAG_FROM_TEST(mloopuv[i].flag, vert_selection[i], MLOOPUV_VERTSEL);
+ SET_FLAG_FROM_TEST(mloopuv[i].flag, edge_selection[i], MLOOPUV_EDGESEL);
+ SET_FLAG_FROM_TEST(mloopuv[i].flag, pin[i], MLOOPUV_PINNED);
+ }
+ });
+ new_layer_to_write.append(mloopuv_layer);
+ }
+
+ face_corner_layers_to_write = new_layer_to_write;
+ mesh->ldata.totlayer = new_layer_to_write.size();
+ mesh->ldata.maxlayer = mesh->ldata.totlayer;
+}
+
+void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh)
+{
+ using namespace blender;
+ using namespace blender::bke;
+
+ /* Store layer names since they will be removed, used to set the active status of new layers.
+ * Use intermediate #StringRef because the names can be null. */
+ const std::string active_uv = StringRef(
+ CustomData_get_active_layer_name(&mesh->ldata, CD_MLOOPUV));
+ const std::string default_uv = StringRef(
+ CustomData_get_render_layer_name(&mesh->ldata, CD_MLOOPUV));
+
+ Set<std::string> uv_layers_to_convert;
+ for (const int uv_layer_i : IndexRange(CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV))) {
+ uv_layers_to_convert.add_as(CustomData_get_layer_name(&mesh->ldata, CD_MLOOPUV, uv_layer_i));
+ }
+
+ for (const StringRefNull name : uv_layers_to_convert) {
+ const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
+ CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, name.c_str()));
+ const uint32_t needed_boolean_attributes = threading::parallel_reduce(
+ IndexRange(mesh->totloop),
+ 4096,
+ 0,
+ [&](const IndexRange range, uint32_t init) {
+ for (const int i : range) {
+ init |= mloopuv[i].flag;
+ }
+ return init;
+ },
+ [](const uint32_t a, const uint32_t b) { return a | b; });
+
+ float2 *coords = static_cast<float2 *>(
+ MEM_malloc_arrayN(mesh->totloop, sizeof(float2), __func__));
+ bool *vert_selection = nullptr;
+ bool *edge_selection = nullptr;
+ bool *pin = nullptr;
+ if (needed_boolean_attributes & MLOOPUV_VERTSEL) {
+ vert_selection = static_cast<bool *>(
+ MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__));
+ }
+ if (needed_boolean_attributes & MLOOPUV_EDGESEL) {
+ edge_selection = static_cast<bool *>(
+ MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__));
+ }
+ if (needed_boolean_attributes & MLOOPUV_PINNED) {
+ pin = static_cast<bool *>(MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__));
+ }
+
+ threading::parallel_for(IndexRange(mesh->totloop), 4096, [&](IndexRange range) {
+ for (const int i : range) {
+ coords[i] = mloopuv[i].uv;
+ }
+ if (vert_selection) {
+ for (const int i : range) {
+ vert_selection[i] = mloopuv[i].flag & MLOOPUV_VERTSEL;
+ }
+ }
+ if (edge_selection) {
+ for (const int i : range) {
+ edge_selection[i] = mloopuv[i].flag & MLOOPUV_EDGESEL;
+ }
+ }
+ if (pin) {
+ for (const int i : range) {
+ pin[i] = mloopuv[i].flag & MLOOPUV_PINNED;
+ }
+ }
+ });
+
+ CustomData_free_layer_named(&mesh->ldata, name.c_str(), mesh->totloop);
+ CustomData_add_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, CD_ASSIGN, coords, mesh->totloop, name.c_str());
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ if (vert_selection) {
+ CustomData_add_layer_named(&mesh->ldata,
+ CD_PROP_BOOL,
+ CD_ASSIGN,
+ vert_selection,
+ mesh->totloop,
+ get_uv_map_vert_selection_name(name.c_str(), buffer));
+ }
+ if (edge_selection) {
+ CustomData_add_layer_named(&mesh->ldata,
+ CD_PROP_BOOL,
+ CD_ASSIGN,
+ edge_selection,
+ mesh->totloop,
+ get_uv_map_edge_selection_name(name.c_str(), buffer));
+ }
+ if (pin) {
+ CustomData_add_layer_named(&mesh->ldata,
+ CD_PROP_BOOL,
+ CD_ASSIGN,
+ pin,
+ mesh->totloop,
+ get_uv_map_pin_name(name.c_str(), buffer));
+ }
+ }
+
+ CustomData_set_layer_active_index(
+ &mesh->ldata,
+ CD_PROP_FLOAT2,
+ CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, active_uv.c_str()));
+ CustomData_set_layer_render_index(
+ &mesh->ldata,
+ CD_PROP_FLOAT2,
+ CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, default_uv.c_str()));
+}
+
/** \name Selection Attribute and Legacy Flag Conversion
* \{ */
diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc
index ed4ae94da7f..676d733c9a2 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.cc
+++ b/source/blender/blenkernel/intern/mesh_mapping.cc
@@ -34,7 +34,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
const bool *hide_poly,
const bool *select_poly,
const MLoop *mloop,
- const MLoopUV *mloopuv,
+ const float (*mloopuv)[2],
uint totpoly,
uint totvert,
const float limit[2],
@@ -95,7 +95,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
vmap->vert[mloop[mp->loopstart + i].v] = buf;
if (use_winding) {
- copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i].uv);
+ copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i]);
}
buf++;
@@ -120,14 +120,14 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly,
v->next = newvlist;
newvlist = v;
- uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index].uv;
+ uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index];
lastv = nullptr;
iterv = vlist;
while (iterv) {
next = iterv->next;
- uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index].uv;
+ uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index];
sub_v2_v2v2(uvdiff, uv2, uv);
if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] &&
@@ -973,7 +973,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
*/
struct MeshCheckIslandBoundaryUv {
const MLoop *loops;
- const MLoopUV *luvs;
+ const float (*luvs)[2];
const MeshElemMap *edge_loop_map;
};
@@ -989,27 +989,27 @@ static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/,
const MeshCheckIslandBoundaryUv *data = static_cast<const MeshCheckIslandBoundaryUv *>(
user_data);
const MLoop *loops = data->loops;
- const MLoopUV *luvs = data->luvs;
+ const float(*luvs)[2] = data->luvs;
const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e];
BLI_assert(edge_to_loops->count >= 2 && (edge_to_loops->count % 2) == 0);
const uint v1 = loops[edge_to_loops->indices[0]].v;
const uint v2 = loops[edge_to_loops->indices[1]].v;
- const float *uvco_v1 = luvs[edge_to_loops->indices[0]].uv;
- const float *uvco_v2 = luvs[edge_to_loops->indices[1]].uv;
+ const float *uvco_v1 = luvs[edge_to_loops->indices[0]];
+ const float *uvco_v2 = luvs[edge_to_loops->indices[1]];
for (int i = 2; i < edge_to_loops->count; i += 2) {
if (loops[edge_to_loops->indices[i]].v == v1) {
- if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]].uv) ||
- !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]].uv)) {
+ if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]]) ||
+ !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]])) {
return true;
}
}
else {
BLI_assert(loops[edge_to_loops->indices[i]].v == v2);
UNUSED_VARS_NDEBUG(v2);
- if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]].uv) ||
- !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]].uv)) {
+ if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]]) ||
+ !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]])) {
return true;
}
}
@@ -1029,7 +1029,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/,
const int totpoly,
const MLoop *loops,
const int totloop,
- const MLoopUV *luvs,
+ const float (*luvs)[2],
MeshIslandStore *r_island_store)
{
int *poly_groups = nullptr;
@@ -1193,7 +1193,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts,
const int totpoly,
MLoop *loops,
const int totloop,
- const MLoopUV *luvs,
+ const float (*luvs)[2],
MeshIslandStore *r_island_store)
{
BLI_assert(luvs != nullptr);
diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
index 2c500f4d972..b78de0da295 100644
--- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc
+++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
@@ -16,6 +16,7 @@
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_memarena.h"
#include "BLI_strict_flags.h"
@@ -57,7 +58,7 @@ static int compare_v2_classify(const float uv_a[2], const float uv_b[2])
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) {
return;
@@ -65,14 +66,14 @@ static void merge_uvs_for_vertex(const Span<int> loops_for_vert, Span<MLoopUV *>
/* Manipulate a copy of the loop indices, de-duplicating UV's per layer. */
Vector<int, 32> loops_merge;
loops_merge.reserve(loops_for_vert.size());
- for (MLoopUV *mloopuv : mloopuv_layers) {
+ for (float2 *mloopuv : mloopuv_layers) {
BLI_assert(loops_merge.is_empty());
loops_merge.extend_unchecked(loops_for_vert);
while (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;) {
- float *uv_dst = mloopuv[loops_merge[i]].uv;
+ float *uv_dst = mloopuv[loops_merge[i]];
switch (compare_v2_classify(uv_src, uv_dst)) {
case CMP_CLOSE: {
uv_dst[0] = uv_src[0];
@@ -106,7 +107,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
if (me->totloop == 0) {
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) {
return;
}
@@ -121,14 +122,15 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
me->totpoly,
me->totloop);
- Vector<MLoopUV *> mloopuv_layers;
+ Vector<float2 *> mloopuv_layers;
mloopuv_layers.reserve(mloopuv_layers_num);
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);
}
- Span<MLoopUV *> mloopuv_layers_as_span = mloopuv_layers.as_span();
+ Span<float2 *> mloopuv_layers_as_span = mloopuv_layers.as_span();
+
threading::parallel_for(IndexRange(me->totvert), 1024, [&](IndexRange range) {
for (const int64_t v_index : range) {
MeshElemMap &loops_for_vert = vert_to_loop[v_index];
diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c
index ce3fc5d99c8..ee5bca276c4 100644
--- a/source/blender/blenkernel/intern/mesh_mirror.c
+++ b/source/blender/blenkernel/intern/mesh_mirror.c
@@ -356,33 +356,33 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* If set, flip around center of each tile. */
const bool do_mirr_udim = (mmd->flag & MOD_MIR_MIRROR_UDIM) != 0;
- const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
+ const int totuv = CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2);
for (a = 0; a < totuv; a++) {
- MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, a);
+ float(*dmloopuv)[2] = CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, a);
int j = maxLoops;
dmloopuv += j; /* second set of loops only */
for (; j-- > 0; dmloopuv++) {
if (do_mirr_u) {
- float u = dmloopuv->uv[0];
+ float u = (*dmloopuv)[0];
if (do_mirr_udim) {
- dmloopuv->uv[0] = ceilf(u) - fmodf(u, 1.0f) + mmd->uv_offset[0];
+ (*dmloopuv)[0] = ceilf(u) - fmodf(u, 1.0f) + mmd->uv_offset[0];
}
else {
- dmloopuv->uv[0] = 1.0f - u + mmd->uv_offset[0];
+ (*dmloopuv)[0] = 1.0f - u + mmd->uv_offset[0];
}
}
if (do_mirr_v) {
- float v = dmloopuv->uv[1];
+ float v = (*dmloopuv)[1];
if (do_mirr_udim) {
- dmloopuv->uv[1] = ceilf(v) - fmodf(v, 1.0f) + mmd->uv_offset[1];
+ (*dmloopuv)[1] = ceilf(v) - fmodf(v, 1.0f) + mmd->uv_offset[1];
}
else {
- dmloopuv->uv[1] = 1.0f - v + mmd->uv_offset[1];
+ (*dmloopuv)[1] = 1.0f - v + mmd->uv_offset[1];
}
}
- dmloopuv->uv[0] += mmd->uv_offset_copy[0];
- dmloopuv->uv[1] += mmd->uv_offset_copy[1];
+ (*dmloopuv)[0] += mmd->uv_offset_copy[0];
+ (*dmloopuv)[1] += mmd->uv_offset_copy[1];
}
}
}
diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc
index 49ea23a1552..3e24cc9e39b 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.cc
+++ b/source/blender/blenkernel/intern/mesh_tangent.cc
@@ -18,6 +18,7 @@
#include "BLI_task.h"
#include "BLI_utildefines.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
@@ -29,6 +30,8 @@
#include "atomic_ops.h"
#include "mikktspace.hh"
+using blender::float2;
+
/* -------------------------------------------------------------------- */
/** \name Mesh Tangent Calculations (Single Layer)
* \{ */
@@ -52,7 +55,7 @@ struct BKEMeshToTangent {
mikk::float3 GetTexCoord(const uint face_num, const uint vert_num)
{
- const float *uv = luvs[uint(mpolys[face_num].loopstart) + vert_num].uv;
+ const float *uv = luvs[uint(mpolys[face_num].loopstart) + vert_num];
return mikk::float3(uv[0], uv[1], 1.0f);
}
@@ -70,7 +73,7 @@ struct BKEMeshToTangent {
const MPoly *mpolys; /* faces */
const MLoop *mloops; /* faces vertices */
const MVert *mverts; /* vertices */
- const MLoopUV *luvs; /* texture coordinates */
+ const float2 *luvs; /* texture coordinates */
const float (*lnors)[3]; /* loops' normals */
float (*tangents)[4]; /* output tangents */
int num_polys; /* number of polygons */
@@ -81,8 +84,8 @@ void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
const MLoop *mloops,
float (*r_looptangent)[4],
const float (*loopnors)[3],
- const MLoopUV *loopuvs,
- const int /*numLoops*/,
+ const float (*loopuvs)[2],
+ const int UNUSED(numLoops),
const MPoly *mpolys,
const int numPolys,
ReportList *reports)
@@ -92,7 +95,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts,
mesh_to_tangent.mpolys = mpolys;
mesh_to_tangent.mloops = mloops;
mesh_to_tangent.mverts = mverts;
- mesh_to_tangent.luvs = loopuvs;
+ mesh_to_tangent.luvs = reinterpret_cast<const float2 *>(loopuvs);
mesh_to_tangent.lnors = loopnors;
mesh_to_tangent.tangents = r_looptangent;
mesh_to_tangent.num_polys = numPolys;
@@ -116,16 +119,16 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
float (*r_looptangents)[4],
ReportList *reports)
{
- const MLoopUV *loopuvs;
+ using namespace blender;
+ using namespace blender::bke;
- /* Check we have valid texture coordinates first! */
- if (uvmap) {
- loopuvs = static_cast<MLoopUV *>(CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap));
- }
- else {
- loopuvs = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
+ if (!uvmap) {
+ uvmap = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
}
- if (!loopuvs) {
+
+ const AttributeAccessor attributes = mesh->attributes();
+ const VArraySpan<float2> uv_map = attributes.lookup<float2>(uvmap, ATTR_DOMAIN_CORNER);
+ if (uv_map.is_empty()) {
BKE_reportf(reports,
RPT_ERROR,
"Tangent space computation needs a UV Map, \"%s\" not found, aborting",
@@ -146,7 +149,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
BKE_mesh_loops(mesh),
r_looptangents,
loopnors,
- loopuvs,
+ reinterpret_cast<const float(*)[2]>(uv_map.data()),
mesh->totloop,
BKE_mesh_polys(mesh),
mesh->totpoly,
@@ -221,7 +224,7 @@ struct SGLSLMeshToTangent {
const MLoopTri *lt;
uint loop_index = GetLoop(face_num, vert_num, lt);
if (mloopuv != nullptr) {
- const float *uv = mloopuv[loop_index].uv;
+ const float2 &uv = mloopuv[loop_index];
return mikk::float3(uv[0], uv[1], 1.0f);
}
const float *l_orco = orco[mloop[loop_index].v];
@@ -275,10 +278,10 @@ struct SGLSLMeshToTangent {
const float (*precomputedFaceNormals)[3];
const float (*precomputedLoopNormals)[3];
const MLoopTri *looptri;
- const MLoopUV *mloopuv; /* texture coordinates */
- const MPoly *mpoly; /* indices */
- const MLoop *mloop; /* indices */
- const MVert *mvert; /* vertex coordinates */
+ const float2 *mloopuv; /* texture coordinates */
+ const MPoly *mpoly; /* indices */
+ const MLoop *mloop; /* indices */
+ const MVert *mvert; /* vertex coordinates */
const float (*vert_normals)[3];
const float (*orco)[3];
float (*tangent)[4]; /* destination */
@@ -306,7 +309,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
const char *layer_name)
{
if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 &&
- CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1) {
+ CustomData_get_named_layer_index(uv_data, CD_PROP_FLOAT2, layer_name) != -1) {
CustomData_add_layer_named(
tan_data, CD_TANGENT, CD_SET_DEFAULT, nullptr, numLoopData, layer_name);
}
@@ -314,7 +317,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_count,
bool *rcalc_act,
bool *rcalc_ren,
@@ -325,15 +328,15 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
short *rtangent_mask)
{
/* Active uv in viewport */
- int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV);
- *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV);
+ int layer_index = CustomData_get_layer_index(loopData, CD_PROP_FLOAT2);
+ *ract_uv_n = CustomData_get_active_layer(loopData, CD_PROP_FLOAT2);
ract_uv_name[0] = 0;
if (*ract_uv_n != -1) {
strcpy(ract_uv_name, loopData->layers[*ract_uv_n + layer_index].name);
}
/* Active tangent in render */
- *rren_uv_n = CustomData_get_render_layer(loopData, CD_MLOOPUV);
+ *rren_uv_n = CustomData_get_render_layer(loopData, CD_PROP_FLOAT2);
rren_uv_name[0] = 0;
if (*rren_uv_n != -1) {
strcpy(rren_uv_name, loopData->layers[*rren_uv_n + layer_index].name);
@@ -361,9 +364,9 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
}
*rtangent_mask = 0;
- const int uv_layer_num = CustomData_number_of_layers(loopData, CD_MLOOPUV);
+ const int uv_layer_num = CustomData_number_of_layers(loopData, CD_PROP_FLOAT2);
for (int n = 0; n < uv_layer_num; n++) {
- const char *name = CustomData_get_layer_name(loopData, CD_MLOOPUV, n);
+ const char *name = CustomData_get_layer_name(loopData, CD_PROP_FLOAT2, n);
bool add = false;
for (int i = 0; i < tangent_names_count; i++) {
if (tangent_names[i][0] && STREQ(tangent_names[i], name)) {
@@ -394,7 +397,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
CustomData *loopdata,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
const float (*vert_normals)[3],
const float (*poly_normals)[3],
@@ -409,8 +412,8 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
int ren_uv_n = -1;
bool calc_act = false;
bool calc_ren = false;
- char act_uv_name[MAX_NAME];
- char ren_uv_name[MAX_NAME];
+ char act_uv_name[MAX_CUSTOMDATA_LAYER_NAME];
+ char ren_uv_name[MAX_CUSTOMDATA_LAYER_NAME];
short tangent_mask = 0;
short tangent_mask_curr = *tangent_mask_curr_p;
@@ -501,8 +504,8 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
mesh2tangent->precomputedFaceNormals = poly_normals;
mesh2tangent->orco = nullptr;
- mesh2tangent->mloopuv = static_cast<const MLoopUV *>(
- CustomData_get_layer_named(loopdata, CD_MLOOPUV, loopdata_out->layers[index].name));
+ mesh2tangent->mloopuv = static_cast<const float2 *>(CustomData_get_layer_named(
+ loopdata, CD_PROP_FLOAT2, loopdata_out->layers[index].name));
/* Fill the resulting tangent_mask */
if (!mesh2tangent->mloopuv) {
@@ -515,8 +518,8 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
}
else {
int uv_ind = CustomData_get_named_layer_index(
- loopdata, CD_MLOOPUV, loopdata_out->layers[index].name);
- int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV);
+ loopdata, CD_PROP_FLOAT2, loopdata_out->layers[index].name);
+ int uv_start = CustomData_get_layer_index(loopdata, CD_PROP_FLOAT2);
BLI_assert(uv_ind != -1 && uv_start != -1);
BLI_assert(uv_ind - uv_start < MAX_MTFACE);
tangent_mask_curr |= short(1 << (uv_ind - uv_start));
@@ -545,7 +548,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
/* Update active layer index */
int act_uv_index = (act_uv_n != -1) ?
- CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, act_uv_n) :
+ CustomData_get_layer_index_n(loopdata, CD_PROP_FLOAT2, act_uv_n) :
-1;
if (act_uv_index != -1) {
int tan_index = CustomData_get_named_layer_index(
@@ -555,7 +558,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
/* Update render layer index */
int ren_uv_index = (ren_uv_n != -1) ?
- CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, ren_uv_n) :
+ CustomData_get_layer_index_n(loopdata, CD_PROP_FLOAT2, ren_uv_n) :
-1;
if (ren_uv_index != -1) {
int tan_index = CustomData_get_named_layer_index(
@@ -567,7 +570,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert,
void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
bool calc_active_tangent,
- const char (*tangent_names)[MAX_NAME],
+ const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len)
{
/* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 9cd3b6e9e9e..8a148de4e82 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -1023,7 +1023,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata,
is_valid &= mesh_validate_customdata(
pdata, mask.pmask, totpoly, do_verbose, do_fixes, &is_change_p);
- const int tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV);
+ const int tot_uvloop = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2);
if (tot_uvloop > MAX_MTFACE) {
PRINT_ERR(
"\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, "
@@ -1033,12 +1033,12 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata,
}
/* check indices of clone/stencil */
- if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
- CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0);
+ if (do_fixes && CustomData_get_clone_layer(ldata, CD_PROP_FLOAT2) >= tot_uvloop) {
+ CustomData_set_layer_clone(ldata, CD_PROP_FLOAT2, 0);
is_change_l = true;
}
- if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) {
- CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0);
+ if (do_fixes && CustomData_get_stencil_layer(ldata, CD_PROP_FLOAT2) >= tot_uvloop) {
+ CustomData_set_layer_stencil(ldata, CD_PROP_FLOAT2, 0);
is_change_l = true;
}
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 54a26a897d8..2979a3cf1ff 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -67,6 +67,7 @@
#include "RNA_types.h"
using blender::Array;
+using blender::float2;
using blender::float3;
using blender::float4x4;
using blender::Span;
@@ -1043,7 +1044,7 @@ struct FaceDupliData_Mesh {
const MLoop *mloop;
const MVert *mvert;
const float (*orco)[3];
- const MLoopUV *mloopuv;
+ const float2 *mloopuv;
};
struct FaceDupliData_EditMesh {
@@ -1193,7 +1194,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
const MLoop *mloop = fdd->mloop;
const MVert *mvert = fdd->mvert;
const float(*orco)[3] = fdd->orco;
- const MLoopUV *mloopuv = fdd->mloopuv;
+ const float2 *mloopuv = fdd->mloopuv;
const int totface = fdd->totface;
const bool use_scale = fdd->params.use_scale;
int a;
@@ -1218,7 +1219,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx,
}
if (mloopuv) {
for (int j = 0; j < mp->totloop; j++) {
- madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j].uv, w);
+ madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j], w);
}
}
}
@@ -1278,7 +1279,7 @@ static void make_duplis_faces(const DupliContext *ctx)
FaceDupliData_Params fdd_params = {ctx, (parent->transflag & OB_DUPLIFACES_SCALE) != 0};
if (em != nullptr) {
- const int uv_idx = CustomData_get_render_layer(&em->bm->ldata, CD_MLOOPUV);
+ const int uv_idx = CustomData_get_render_layer(&em->bm->ldata, CD_PROP_FLOAT2);
FaceDupliData_EditMesh fdd{};
fdd.params = fdd_params;
fdd.em = em;
@@ -1286,20 +1287,20 @@ static void make_duplis_faces(const DupliContext *ctx)
fdd.has_orco = (vert_coords != nullptr);
fdd.has_uvs = (uv_idx != -1);
fdd.cd_loop_uv_offset = (uv_idx != -1) ?
- CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, uv_idx) :
+ CustomData_get_n_offset(&em->bm->ldata, CD_PROP_FLOAT2, uv_idx) :
-1;
make_child_duplis(ctx, &fdd, make_child_duplis_faces_from_editmesh);
}
else {
- const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_MLOOPUV);
+ const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_PROP_FLOAT2);
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;
fdd.mpoly = me_eval->polys().data();
fdd.mloop = me_eval->loops().data();
fdd.mvert = me_eval->verts().data();
- fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n(
- &me_eval->ldata, CD_MLOOPUV, uv_idx) :
+ fdd.mloopuv = (uv_idx != -1) ? (const float2 *)CustomData_get_layer_n(
+ &me_eval->ldata, CD_PROP_FLOAT2, uv_idx) :
nullptr;
fdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc
index 106c9594718..32d332cf07e 100644
--- a/source/blender/blenkernel/intern/object_update.cc
+++ b/source/blender/blenkernel/intern/object_update.cc
@@ -158,7 +158,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
#endif
if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
/* Always compute UVs, vertex colors as orcos for render. */
- cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR;
+ cddata_masks.lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR;
cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
}
makeDerivedMesh(depsgraph, scene, ob, &cddata_masks); /* was CD_MASK_BAREMESH */
diff --git a/source/blender/blenkernel/intern/paint_canvas.cc b/source/blender/blenkernel/intern/paint_canvas.cc
index b72418d88c0..5eed6e15467 100644
--- a/source/blender/blenkernel/intern/paint_canvas.cc
+++ b/source/blender/blenkernel/intern/paint_canvas.cc
@@ -80,7 +80,7 @@ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *setti
}
const Mesh *mesh = static_cast<Mesh *>(ob->data);
- return CustomData_get_active_layer_index(&mesh->ldata, CD_MLOOPUV);
+ return CustomData_get_active_layer_index(&mesh->ldata, CD_PROP_FLOAT2);
}
case PAINT_CANVAS_SOURCE_MATERIAL: {
/* Use uv map of the canvas. */
@@ -98,7 +98,7 @@ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *setti
}
const Mesh *mesh = static_cast<Mesh *>(ob->data);
- return CustomData_get_named_layer_index(&mesh->ldata, CD_MLOOPUV, slot->uvname);
+ return CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, slot->uvname);
}
}
return -1;
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index df616d4e087..0f50d7ba437 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -109,7 +109,7 @@ struct EncodePixelsUserData {
ImageUser *image_user;
PBVH *pbvh;
Vector<PBVHNode *> *nodes;
- const MLoopUV *ldata_uv;
+ const float2 *ldata_uv;
};
static void do_encode_pixels(void *__restrict userdata,
@@ -137,9 +137,9 @@ static void do_encode_pixels(void *__restrict userdata,
for (int triangle_index = 0; triangle_index < triangles.size(); triangle_index++) {
const MLoopTri *lt = &pbvh->looptri[node->prim_indices[triangle_index]];
float2 uvs[3] = {
- float2(data->ldata_uv[lt->tri[0]].uv) - tile_offset,
- float2(data->ldata_uv[lt->tri[1]].uv) - tile_offset,
- float2(data->ldata_uv[lt->tri[2]].uv) - tile_offset,
+ data->ldata_uv[lt->tri[0]] - tile_offset,
+ data->ldata_uv[lt->tri[1]] - tile_offset,
+ data->ldata_uv[lt->tri[2]] - tile_offset,
};
const float minv = clamp_f(min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f);
@@ -284,8 +284,9 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
return;
}
- const MLoopUV *ldata_uv = static_cast<const MLoopUV *>(
- CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
+ const float2 *ldata_uv = static_cast<const float2 *>(
+ CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2));
+
if (ldata_uv == nullptr) {
return;
}
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index aabed2cea28..9f74be30029 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -193,14 +193,14 @@ static int get_num_uv_layers(const OpenSubdiv_Converter *converter)
{
ConverterStorage *storage = converter->user_data;
const Mesh *mesh = storage->mesh;
- return CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
+ return CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2);
}
static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int layer_index)
{
ConverterStorage *storage = converter->user_data;
const Mesh *mesh = storage->mesh;
- const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
+ const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index);
const int num_poly = mesh->totpoly;
const int num_vert = mesh->totvert;
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index e6f24aa6ff8..aac0dfeea15 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -127,7 +127,7 @@ typedef struct FaceVaryingDataFromUVContext {
OpenSubdiv_TopologyRefiner *topology_refiner;
const Mesh *mesh;
const MPoly *polys;
- const MLoopUV *mloopuv;
+ const float (*mloopuv)[2];
float (*buffer)[2];
int layer_index;
} FaceVaryingDataFromUVContext;
@@ -140,7 +140,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata,
OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner;
const int layer_index = ctx->layer_index;
const MPoly *mpoly = &ctx->polys[face_index];
- const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart];
+ const float(*mluv)[2] = &ctx->mloopuv[mpoly->loopstart];
/* TODO(sergey): OpenSubdiv's C-API converter can change winding of
* loops of a face, need to watch for that, to prevent wrong UVs assigned.
@@ -149,19 +149,19 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata,
const int *uv_indices = topology_refiner->getFaceFVarValueIndices(
topology_refiner, face_index, layer_index);
for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) {
- copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], mluv->uv);
+ copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv);
}
}
static void set_face_varying_data_from_uv(Subdiv *subdiv,
const Mesh *mesh,
- const MLoopUV *mloopuv,
+ const float (*mloopuv)[2],
const int layer_index)
{
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
OpenSubdiv_Evaluator *evaluator = subdiv->evaluator;
const int num_faces = topology_refiner->getNumFaces(topology_refiner);
- const MLoopUV *mluv = mloopuv;
+ const float(*mluv)[2] = mloopuv;
const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index);
/* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */
@@ -250,9 +250,9 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv,
/* Set coordinates of base mesh vertices. */
set_coarse_positions(subdiv, mesh, coarse_vertex_cos);
/* Set face-varying data to UV maps. */
- const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
+ const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2);
for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) {
- const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
+ const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index);
set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index);
}
/* Set vertex data to orco. */
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc
index e1c434f2b2e..6832d0b5703 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.cc
+++ b/source/blender/blenkernel/intern/subdiv_mesh.cc
@@ -15,6 +15,7 @@
#include "BLI_array.hh"
#include "BLI_bitmap.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
#include "BKE_customdata.h"
@@ -28,6 +29,8 @@
#include "MEM_guardedalloc.h"
+using blender::float2;
+
using blender::Span;
/* -------------------------------------------------------------------- */
@@ -56,7 +59,8 @@ struct SubdivMeshContext {
int *poly_origindex;
/* UV layers interpolation. */
int num_uv_layers;
- MLoopUV *uv_layers[MAX_MTFACE];
+ float2 *uv_layers[MAX_MTFACE];
+
/* Original coordinates (ORCO) interpolation. */
float (*orco)[3];
float (*cloth_orco)[3];
@@ -73,10 +77,10 @@ struct SubdivMeshContext {
static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
- ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV);
+ ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2);
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
- ctx->uv_layers[layer_index] = static_cast<MLoopUV *>(
- CustomData_get_layer_n(&subdiv_mesh->ldata, CD_MLOOPUV, layer_index));
+ ctx->uv_layers[layer_index] = static_cast<float2 *>(
+ CustomData_get_layer_n(&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index));
}
}
@@ -864,8 +868,8 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
Subdiv *subdiv = ctx->subdiv;
const int mloop_index = subdiv_loop - ctx->subdiv_loops;
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
- MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
- BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv);
+ BKE_subdiv_eval_face_varying(
+ subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][mloop_index]);
}
}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 80fb637b76e..f864fc223fe 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -262,7 +262,7 @@ static void get_face_uv_map_vert(
static int ss_sync_from_uv(CCGSubSurf *ss,
CCGSubSurf *origss,
DerivedMesh *dm,
- const MLoopUV *mloopuv)
+ const float (*mloopuv)[2])
{
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
@@ -312,7 +312,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss,
int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index;
CCGVertHDL vhdl = POINTER_FROM_INT(loopid);
- copy_v2_v2(uv, mloopuv[loopid].uv);
+ copy_v2_v2(uv, mloopuv[loopid]);
ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv);
}
@@ -387,11 +387,11 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
{
CCGFaceIterator fi;
int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S;
- const MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n);
- /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with
+ const float(*dmloopuv)[2] = CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n);
+ /* need to update both CD_MTFACE & CD_PROP_FLOAT2, hrmf, we could get away with
* just tface except applying the modifier then looses subsurf UV */
MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
- MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n);
+ float(*mloopuv)[2] = CustomData_get_layer_n(&result->loopData, CD_PROP_FLOAT2, n);
if (!dmloopuv || (!tface && !mloopuv)) {
return;
@@ -421,7 +421,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
/* load coordinates from uvss into tface */
MTFace *tf = tface;
- MLoopUV *mluv = mloopuv;
+ float(*mluv)[2] = mloopuv;
for (index = 0; index < totface; index++) {
CCGFace *f = faceMap[index];
@@ -446,10 +446,10 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *
}
if (mluv) {
- copy_v2_v2(mluv[0].uv, a);
- copy_v2_v2(mluv[1].uv, d);
- copy_v2_v2(mluv[2].uv, c);
- copy_v2_v2(mluv[3].uv, b);
+ copy_v2_v2(mluv[0], a);
+ copy_v2_v2(mluv[1], d);
+ copy_v2_v2(mluv[2], c);
+ copy_v2_v2(mluv[3], b);
mluv += 4;
}
}
@@ -1807,8 +1807,8 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
if (useSubsurfUv) {
CustomData *ldata = &ccgdm->dm.loopData;
CustomData *dmldata = &dm->loopData;
- int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV);
- int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV);
+ int numlayer = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2);
+ int dmnumlayer = CustomData_number_of_layers(dmldata, CD_PROP_FLOAT2);
for (i = 0; i < numlayer && i < dmnumlayer; i++) {
set_subsurf_uv(ss, dm, &ccgdm->dm, i);
diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc
index 2616bb890a3..3302aa890d9 100644
--- a/source/blender/blenloader/intern/versioning_400.cc
+++ b/source/blender/blenloader/intern/versioning_400.cc
@@ -23,6 +23,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh)
{
BKE_mesh_legacy_convert_flags_to_selection_layers(&mesh);
BKE_mesh_legacy_convert_flags_to_hide_layers(&mesh);
+ BKE_mesh_legacy_convert_uvs_to_generic(&mesh);
BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh);
BKE_mesh_legacy_bevel_weight_to_layers(&mesh);
BKE_mesh_legacy_face_set_to_generic(&mesh);
diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc
index da23e9cb49f..cfc56250bcd 100644
--- a/source/blender/blenloader/intern/versioning_defaults.cc
+++ b/source/blender/blenloader/intern/versioning_defaults.cc
@@ -351,16 +351,14 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
/* Correct default startup UV's. */
Mesh *me = static_cast<Mesh *>(BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2));
if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
- MLoopUV *mloopuv = static_cast<MLoopUV *>(CustomData_get_layer(&me->ldata, CD_MLOOPUV));
const float uv_values[24][2] = {
{0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75},
{0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25},
{0.125, 0.50}, {0.375, 0.50}, {0.375, 0.75}, {0.125, 0.75}, {0.375, 0.50}, {0.625, 0.50},
{0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50},
};
- for (int i = 0; i < ARRAY_SIZE(uv_values); i++) {
- copy_v2_v2(mloopuv[i].uv, uv_values[i]);
- }
+ float(*mloopuv)[2] = static_cast<float (*)[2]>(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2));
+ memcpy(mloopuv, uv_values, sizeof(float[2]) * me->totloop);
}
/* Make sure that the curve profile is initialized */
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 3956db0288a..931643b093d 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -173,6 +173,7 @@
* - Use two different iterator types for BMO map/buffer types.
*/
+#include "BKE_customdata.h"
#include "DNA_customdata_types.h" /* BMesh struct in bmesh_class.h uses */
#include "DNA_listBase.h" /* selection history uses */
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 9d5737a5b71..5139cbec692 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -529,6 +529,37 @@ typedef bool (*BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_
#define BM_ELEM_CD_GET_BOOL(ele, offset) \
(BLI_assert(offset != -1), *((bool *)((char *)(ele)->head.data + (offset))))
+#define BM_ELEM_CD_GET_OPT_BOOL(ele, offset) \
+ (offset == -1 ? false : *((bool *)((char *)(ele)->head.data + (offset))))
+
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+# define BM_ELEM_CD_GET_BOOL_P(ele, offset) \
+ (BLI_assert(offset != -1), \
+ _Generic(ele, \
+ GENERIC_TYPE_ANY((bool *)POINTER_OFFSET((ele)->head.data, offset), \
+ _BM_GENERIC_TYPE_ELEM_NONCONST), \
+ GENERIC_TYPE_ANY((const bool *)POINTER_OFFSET((ele)->head.data, offset), \
+ _BM_GENERIC_TYPE_ELEM_CONST)))
+#else
+# define BM_ELEM_CD_GET_BOOL_P(ele, offset) \
+ (BLI_assert(offset != -1), (bool *)((char *)(ele)->head.data + (offset)))
+#endif
+
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+# define BM_ELEM_CD_GET_OPT_BOOL_P(ele, offset) \
+ ((offset != -1) ? \
+ _Generic(ele, \
+ GENERIC_TYPE_ANY((bool *)POINTER_OFFSET((ele)->head.data, offset), \
+ _BM_GENERIC_TYPE_ELEM_NONCONST), \
+ GENERIC_TYPE_ANY((const bool *)POINTER_OFFSET((ele)->head.data, offset), \
+ _BM_GENERIC_TYPE_ELEM_CONST)) : NULL)
+#else
+# define BM_ELEM_CD_GET_OPT_BOOL_P(ele, offset) \
+ ((offset != -1) ? (bool *)((char *)(ele)->head.data + (offset)) : NULL)
+#endif
+
+
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
# define BM_ELEM_CD_GET_VOID_P(ele, offset) \
(BLI_assert(offset != -1), \
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index b7028dee5e1..0198cb6818f 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -15,8 +15,10 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "BLI_string.h"
#include "BLI_task.h"
+#include "BKE_attribute.h"
#include "BKE_customdata.h"
#include "BKE_multires.h"
@@ -872,6 +874,34 @@ void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *
}
}
+void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name)
+{
+ if (CustomData_get_named_layer_index(data, type, name) == -1) {
+ BM_data_layer_add_named(bm, data, type, name);
+ }
+}
+
+void BM_uv_map_ensure_vert_selection_attribute(BMesh *bm, const char *uv_map_name)
+{
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+ BM_data_layer_ensure_named(
+ bm, &bm->ldata, CD_PROP_BOOL, get_uv_map_vert_selection_name(uv_map_name, name));
+}
+
+void BM_uv_map_ensure_edge_selection_attribute(BMesh *bm, const char *uv_map_name)
+{
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+ BM_data_layer_ensure_named(
+ bm, &bm->ldata, CD_PROP_BOOL, get_uv_map_edge_selection_name(uv_map_name, name));
+}
+
+void BM_uv_map_ensure_pin_attribute(BMesh *bm, const char *uv_map_name)
+{
+ char name[MAX_CUSTOMDATA_LAYER_NAME];
+ BM_data_layer_ensure_named(
+ bm, &bm->ldata, CD_PROP_BOOL, get_uv_map_pin_name(uv_map_name, name));
+}
+
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
{
CustomData olddata;
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index 2cf9dffceec..6f1a29dce98 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -58,7 +58,13 @@ void BM_data_interp_face_vert_edge(
BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v, BMEdge *e, float fac);
void BM_data_layer_add(BMesh *bm, CustomData *data, int type);
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
+void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name);
void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
+
+void BM_uv_map_ensure_vert_selection_attribute(BMesh *bm, const char *uv_map_name);
+void BM_uv_map_ensure_edge_selection_attribute(BMesh *bm, const char *uv_map_name);
+void BM_uv_map_ensure_pin_attribute(BMesh *bm, const char *uv_map_name);
+
/**
* Remove a named custom data layer, if it existed. Return true if the layer was removed.
*/
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 6df446a377c..a2aecf80456 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -234,9 +234,9 @@ float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset)
/* The Trapezium Area Rule */
float cross = 0.0f;
do {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset);
- cross += (luv_next->uv[0] - luv->uv[0]) * (luv_next->uv[1] + luv->uv[1]);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l_iter->next, cd_loop_uv_offset);
+ cross += (luv_next[0] - luv[0]) * (luv_next[1] + luv[1]);
} while ((l_iter = l_iter->next) != l_first);
return fabsf(cross * 0.5f);
}
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc
index 0e2385ff4e2..2bc24078bad 100644
--- a/source/blender/bmesh/intern/bmesh_query_uv.cc
+++ b/source/blender/bmesh/intern/bmesh_query_uv.cc
@@ -12,6 +12,7 @@
#include "BLI_math_vec_types.hh"
#include "BLI_utildefines_stack.h"
+#include "BKE_attribute.hh"
#include "BKE_customdata.h"
#include "DNA_meshdata_types.h"
@@ -19,12 +20,36 @@
#include "bmesh.h"
#include "intern/bmesh_private.h"
+BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm)
+{
+ using namespace blender;
+ using namespace blender::bke;
+ const int layer_index = CustomData_get_layer_index(&bm->ldata, CD_PROP_FLOAT2);
+ if (layer_index == -1) {
+ return {-1, -1, -1, -1};
+ }
+
+ char const *name = bm->ldata.layers[layer_index].name;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+
+ BMUVOffsets offsets;
+ offsets.uv = bm->ldata.layers[layer_index].offset;
+ offsets.select_vert = CustomData_get_offset_named(
+ &bm->ldata, CD_PROP_BOOL, get_uv_map_vert_selection_name(name, buffer));
+ offsets.select_edge = CustomData_get_offset_named(
+ &bm->ldata, CD_PROP_BOOL, get_uv_map_edge_selection_name(name, buffer));
+ offsets.pin = CustomData_get_offset_named(
+ &bm->ldata, CD_PROP_BOOL, get_uv_map_pin_name(name, buffer));
+
+ return offsets;
+}
+
static void uv_aspect(const BMLoop *l,
const float aspect[2],
const int cd_loop_uv_offset,
float r_uv[2])
{
- const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv;
+ const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
r_uv[0] = uv[0] * aspect[0];
r_uv[1] = uv[1] * aspect[1];
}
@@ -81,8 +106,8 @@ void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset,
zero_v2(r_cent);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- add_v2_v2(r_cent, luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ add_v2_v2(r_cent, luv);
} while ((l_iter = l_iter->next) != l_first);
mul_v2_fl(r_cent, 1.0f / float(f->len));
@@ -96,8 +121,7 @@ float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset)
int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- uvs[i++] = luv->uv;
+ uvs[i++] = BM_ELEM_CD_GET_FLOAT2_P(l_iter, cd_loop_uv_offset);
} while ((l_iter = l_iter->next) != l_first);
return cross_poly_v2(reinterpret_cast<const float(*)[2]>(uvs.data()), f->len);
}
@@ -108,31 +132,30 @@ void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd
const BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- minmax_v2v2_v2(min, max, luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ minmax_v2v2_v2(min, max, luv);
} while ((l_iter = l_iter->next) != l_first);
}
bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
{
BLI_assert(l_a->e == l_b->e);
- MLoopUV *luv_a_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
- MLoopUV *luv_a_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a->next, cd_loop_uv_offset);
- MLoopUV *luv_b_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
- MLoopUV *luv_b_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b->next, cd_loop_uv_offset);
+ float *luv_a_curr = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset);
+ float *luv_a_next = BM_ELEM_CD_GET_FLOAT_P(l_a->next, cd_loop_uv_offset);
+ float *luv_b_curr = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset);
+ float *luv_b_next = BM_ELEM_CD_GET_FLOAT_P(l_b->next, cd_loop_uv_offset);
if (l_a->v != l_b->v) {
std::swap(luv_b_curr, luv_b_next);
}
- return (equals_v2v2(luv_a_curr->uv, luv_b_curr->uv) &&
- equals_v2v2(luv_a_next->uv, luv_b_next->uv));
+ return (equals_v2v2(luv_a_curr, luv_b_curr) && equals_v2v2(luv_a_next, luv_b_next));
}
bool BM_loop_uv_share_vert_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset)
{
BLI_assert(l_a->v == l_b->v);
- const MLoopUV *luv_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
- const MLoopUV *luv_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
- if (!equals_v2v2(luv_a->uv, luv_b->uv)) {
+ const float *luv_a = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset);
+ const float *luv_b = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset);
+ if (!equals_v2v2(luv_a, luv_b)) {
return false;
}
return true;
@@ -150,11 +173,9 @@ bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int
const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e);
{
- const MLoopUV *luv_other_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_a,
- cd_loop_uv_offset);
- const MLoopUV *luv_other_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_b,
- cd_loop_uv_offset);
- if (!equals_v2v2(luv_other_a->uv, luv_other_b->uv)) {
+ const float *luv_other_a = BM_ELEM_CD_GET_FLOAT_P(l_other_a, cd_loop_uv_offset);
+ const float *luv_other_b = BM_ELEM_CD_GET_FLOAT_P(l_other_b, cd_loop_uv_offset);
+ if (!equals_v2v2(luv_other_a, luv_other_b)) {
return false;
}
}
@@ -172,7 +193,7 @@ bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int
BLI_assert(BM_face_is_normal_valid(f));
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
- projverts[i] = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv;
+ projverts[i] = BM_ELEM_CD_GET_FLOAT2_P(l_iter, cd_loop_uv_offset);
}
return isect_point_poly_v2(
diff --git a/source/blender/bmesh/intern/bmesh_query_uv.h b/source/blender/bmesh/intern/bmesh_query_uv.h
index 6aa82653535..1bd3ce6ebc7 100644
--- a/source/blender/bmesh/intern/bmesh_query_uv.h
+++ b/source/blender/bmesh/intern/bmesh_query_uv.h
@@ -6,6 +6,11 @@
* \ingroup bmesh
*/
+/**
+ * Retrieve the custom data offsets for layers used for user interaction with the active UV map.
+ */
+BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm);
+
float BM_loop_uv_calc_edge_length_squared(const BMLoop *l,
int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index df749b591dc..3a2216d78a0 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -277,7 +277,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
}
if (BMO_slot_bool_get(op->slots_in, "cmp_uvs") &&
- bm_edge_delimit_cdata(&bm->ldata, CD_MLOOPUV, &delimit_data.cdata[delimit_data.cdata_len])) {
+ bm_edge_delimit_cdata(
+ &bm->ldata, CD_PROP_FLOAT2, &delimit_data.cdata[delimit_data.cdata_len])) {
delimit_data.cdata_len += 1;
}
diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c
index 72507cbab6d..434c1524ca9 100644
--- a/source/blender/bmesh/operators/bmo_mirror.c
+++ b/source/blender/bmesh/operators/bmo_mirror.c
@@ -67,30 +67,30 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op)
if (mirror_u || mirror_v) {
BMFace *f;
BMLoop *l;
- MLoopUV *luv;
- const int totlayer = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ float *luv;
+ const int totlayer = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2);
BMIter liter;
BMO_ITER (f, &siter, dupeop.slots_out, "geom.out", BM_FACE) {
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
for (i = 0; i < totlayer; i++) {
- luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
+ luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_PROP_FLOAT2, i);
if (mirror_u) {
- float uv_u = luv->uv[0];
+ float uv_u = luv[0];
if (mirror_udim) {
- luv->uv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f);
+ luv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f);
}
else {
- luv->uv[0] = 1.0f - uv_u;
+ luv[0] = 1.0f - uv_u;
}
}
if (mirror_v) {
- float uv_v = luv->uv[1];
+ float uv_v = luv[1];
if (mirror_udim) {
- luv->uv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f);
+ luv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f);
}
else {
- luv->uv[1] = 1.0f - uv_v;
+ luv[1] = 1.0f - uv_v;
}
}
}
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index c60ffbedb94..70984ba10bd 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -719,7 +719,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
const float xtot_inv2 = 2.0f / (xtot);
const float ytot_inv2 = 2.0f / (ytot);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert **varr;
@@ -799,7 +799,7 @@ void BM_mesh_calc_uvs_grid(BMesh *bm,
}
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
switch (loop_index) {
case 0:
@@ -818,8 +818,8 @@ void BM_mesh_calc_uvs_grid(BMesh *bm,
break;
}
- luv->uv[0] = x;
- luv->uv[1] = y;
+ luv[0] = x;
+ luv[1] = y;
}
x += dx;
@@ -836,7 +836,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
const int seg = BMO_slot_int_get(op->slots_in, "u_segments");
const int tot = BMO_slot_int_get(op->slots_in, "v_segments");
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMOperator bmop, prevop;
@@ -955,7 +955,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
const float rad_div = rad / 200.0f;
const int subdiv = BMO_slot_int_get(op->slots_in, "subdivisions");
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert *eva[12];
@@ -1000,9 +1000,9 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
if (calc_uvs) {
int loop_index;
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->uv[0] = icouvs[uvi][0];
- luv->uv[1] = icouvs[uvi][1];
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ luv[0] = icouvs[uvi][0];
+ luv[1] = icouvs[uvi][1];
uvi++;
}
}
@@ -1063,7 +1063,7 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset)
avgy /= 3.0f;
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
float x = l->v->co[0];
float y = l->v->co[1];
float z = l->v->co[2];
@@ -1084,10 +1084,10 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset)
}
float phi = saacos(z / len);
- luv->uv[0] = 0.5f + theta / ((float)M_PI * 2);
- luv->uv[1] = 1.0f - phi / (float)M_PI;
+ luv[0] = 0.5f + theta / ((float)M_PI * 2);
+ luv[1] = 1.0f - phi / (float)M_PI;
- uvs[loop_index] = luv->uv;
+ uvs[loop_index] = luv;
}
/* Fix awkwardly-wrapping UVs */
@@ -1133,9 +1133,9 @@ void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag, const int cd_loop_uv_
continue;
}
BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->uv[0] < minx) {
- minx = luv->uv[0];
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (luv[0] < minx) {
+ minx = luv[0];
}
}
}
@@ -1145,8 +1145,8 @@ void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag, const int cd_loop_uv_
continue;
}
BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->uv[0] -= minx;
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ luv[0] -= minx;
}
}
}
@@ -1159,7 +1159,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
for (i = 0; i < monkeynv; i++) {
@@ -1213,15 +1213,15 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, f_new_a, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->uv[0] = monkeyuvs[uvi * 2 + 0];
- luv->uv[1] = monkeyuvs[uvi * 2 + 1];
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ luv[0] = monkeyuvs[uvi * 2 + 0];
+ luv[1] = monkeyuvs[uvi * 2 + 1];
uvi++;
}
BM_ITER_ELEM (l, &liter, f_new_b, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->uv[0] = monkeyuvs[uvi * 2 + 0];
- luv->uv[1] = monkeyuvs[uvi * 2 + 1];
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ luv[0] = monkeyuvs[uvi * 2 + 0];
+ luv[1] = monkeyuvs[uvi * 2 + 1];
uvi++;
}
}
@@ -1239,7 +1239,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
@@ -1335,7 +1335,7 @@ void BM_mesh_calc_uvs_circle(
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
float uv_vco[3];
copy_v3_v3(uv_vco, l->v->co);
@@ -1343,8 +1343,8 @@ void BM_mesh_calc_uvs_circle(
mul_m4_v3(inv_mat, uv_vco);
/* then just take those coords for UVs */
- luv->uv[0] = uv_center + uv_scale * uv_vco[0];
- luv->uv[1] = uv_center + uv_scale * uv_vco[1];
+ luv[0] = uv_center + uv_scale * uv_vco[0];
+ luv[1] = uv_center + uv_scale * uv_vco[1];
}
}
}
@@ -1361,7 +1361,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
if (!segs) {
@@ -1556,7 +1556,7 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
if (f->len == 4 && radius_top && radius_bottom) {
/* side face - so unwrap it in a rectangle */
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
switch (loop_index) {
case 0:
@@ -1575,8 +1575,8 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
break;
}
- luv->uv[0] = x;
- luv->uv[1] = y;
+ luv[0] = x;
+ luv[1] = y;
}
}
else {
@@ -1585,18 +1585,18 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
BM_face_normal_update(f);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
float uv_vco[3];
mul_v3_m4v3(uv_vco, inv_mat, l->v->co);
if (dot_v3v3(f->no, local_up) > 0.0f) { /* if this is a top face of the cone */
- luv->uv[0] = uv_center_x_top + uv_vco[0] * uv_scale_top;
- luv->uv[1] = uv_center_y + uv_vco[1] * uv_scale_top;
+ luv[0] = uv_center_x_top + uv_vco[0] * uv_scale_top;
+ luv[1] = uv_center_y + uv_vco[1] * uv_scale_top;
}
else {
- luv->uv[0] = uv_center_x_bottom + uv_vco[0] * uv_scale_bottom;
- luv->uv[1] = uv_center_y + uv_vco[1] * uv_scale_bottom;
+ luv[0] = uv_center_x_bottom + uv_vco[0] * uv_scale_bottom;
+ luv[1] = uv_center_y + uv_vco[1] * uv_scale_bottom;
}
}
}
@@ -1609,7 +1609,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
float mat[4][4];
float off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
/* rotation order set to match 'BM_mesh_calc_uvs_cube' */
@@ -1670,7 +1670,7 @@ void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag)
BMIter fiter, liter;
const float width = 0.25f;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
float x = 0.375f;
float y = 0.0f;
@@ -1685,10 +1685,10 @@ void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag)
}
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
- luv->uv[0] = x;
- luv->uv[1] = y;
+ luv[0] = x;
+ luv[1] = y;
switch (loop_index) {
case 0:
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index d88f3112a71..a821fa2b744 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -462,56 +462,56 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op)
BMIter l_iter; /* iteration loop */
const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
if (cd_loop_uv_offset != -1) {
BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
if (use_ccw == false) { /* same loops direction */
BMLoop *lf; /* current face loops */
- MLoopUV *f_luv; /* first face loop uv */
+ float *f_luv; /* first face loop uv */
float p_uv[2]; /* previous uvs */
float t_uv[2]; /* temp uvs */
int n = 0;
BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
/* current loop uv is the previous loop uv */
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset);
if (n == 0) {
f_luv = luv;
- copy_v2_v2(p_uv, luv->uv);
+ copy_v2_v2(p_uv, luv);
}
else {
- copy_v2_v2(t_uv, luv->uv);
- copy_v2_v2(luv->uv, p_uv);
+ copy_v2_v2(t_uv, luv);
+ copy_v2_v2(luv, p_uv);
copy_v2_v2(p_uv, t_uv);
}
n++;
}
- copy_v2_v2(f_luv->uv, p_uv);
+ copy_v2_v2(f_luv, p_uv);
}
- else { /* counter loop direction */
- BMLoop *lf; /* current face loops */
- MLoopUV *p_luv; /* previous loop uv */
- MLoopUV *luv;
+ else { /* counter loop direction */
+ BMLoop *lf; /* current face loops */
+ float *p_luv; /* previous loop uv */
+ float *luv;
float t_uv[2]; /* current uvs */
int n = 0;
BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
/* previous loop uv is the current loop uv */
- luv = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_uv_offset);
+ luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset);
if (n == 0) {
p_luv = luv;
- copy_v2_v2(t_uv, luv->uv);
+ copy_v2_v2(t_uv, luv);
}
else {
- copy_v2_v2(p_luv->uv, luv->uv);
+ copy_v2_v2(p_luv, luv);
p_luv = luv;
}
n++;
}
- copy_v2_v2(luv->uv, t_uv);
+ copy_v2_v2(luv, t_uv);
}
}
}
@@ -530,22 +530,22 @@ static void bm_face_reverse_uvs(BMFace *f, const int cd_loop_uv_offset)
float(*uvs)[2] = BLI_array_alloca(uvs, f->len);
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(uvs[i], luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ copy_v2_v2(uvs[i], luv);
}
/* now that we have the uvs in the array, reverse! */
BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
/* current loop uv is the previous loop uv */
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uvs[(f->len - i - 1)]);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ copy_v2_v2(luv, uvs[(f->len - i - 1)]);
}
}
void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op)
{
BMOIter iter;
BMFace *f;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
if (cd_loop_uv_offset != -1) {
BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index c45f9dbe49c..17a176da152 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -811,7 +811,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm)
bp->math_layer_info.has_math_layers = false;
bp->math_layer_info.face_component = NULL;
for (int i = 0; i < bm->ldata.totlayer; i++) {
- if (CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) {
+ if (CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2)) {
bp->math_layer_info.has_math_layers = true;
break;
}
@@ -1009,10 +1009,10 @@ static BMFace *choose_rep_face(BevelParams *bp, BMFace **face, int nfaces)
* Caller should ensure that no seams are violated by doing this. */
static void bev_merge_uvs(BMesh *bm, BMVert *v)
{
- int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2);
for (int i = 0; i < num_of_uv_layers; i++) {
- int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i);
+ int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, i);
if (cd_loop_uv_offset == -1) {
return;
@@ -1023,15 +1023,15 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v)
BMIter iter;
BMLoop *l;
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ add_v2_v2(uv, luv);
n++;
}
if (n > 1) {
mul_v2_fl(uv, 1.0f / (float)n);
BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ copy_v2_v2(luv, uv);
}
}
}
@@ -1041,7 +1041,7 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v)
* and part of faces that share edge bme. */
static void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, BMVert *v)
{
- int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2);
BMLoop *l1 = NULL;
BMLoop *l2 = NULL;
@@ -1060,22 +1060,22 @@ static void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, BMVert *v)
}
for (int i = 0; i < num_of_uv_layers; i++) {
- int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i);
+ int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, i);
if (cd_loop_uv_offset == -1) {
return;
}
float uv[2] = {0.0f, 0.0f};
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l1, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
- luv = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l1, cd_loop_uv_offset);
+ add_v2_v2(uv, luv);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l2, cd_loop_uv_offset);
+ add_v2_v2(uv, luv);
mul_v2_fl(uv, 0.5f);
- luv = BM_ELEM_CD_GET_VOID_P(l1, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uv);
- luv = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, uv);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l1, cd_loop_uv_offset);
+ copy_v2_v2(luv, uv);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l2, cd_loop_uv_offset);
+ copy_v2_v2(luv, uv);
}
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 8a11815bd4c..11adeaf5c10 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -289,14 +289,14 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm,
int i;
if (delimit & BMO_DELIM_UV) {
- const int layer_len = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
+ const int layer_len = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2);
if (layer_len == 0) {
delimit &= ~BMO_DELIM_UV;
}
else {
- delimit_data.cd_loop_type = CD_MLOOPUV;
+ delimit_data.cd_loop_type = CD_PROP_FLOAT2;
delimit_data.cd_loop_size = CustomData_sizeof(delimit_data.cd_loop_type);
- delimit_data.cd_loop_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, 0);
+ delimit_data.cd_loop_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, 0);
delimit_data.cd_loop_offset_end = delimit_data.cd_loop_size * layer_len;
}
}
diff --git a/source/blender/bmesh/tools/bmesh_path_uv.c b/source/blender/bmesh/tools/bmesh_path_uv.c
index ecc92fd09a4..26726fe4bac 100644
--- a/source/blender/bmesh/tools/bmesh_path_uv.c
+++ b/source/blender/bmesh/tools/bmesh_path_uv.c
@@ -67,23 +67,23 @@ static void verttag_add_adjacent_uv(HeapSimple *heap,
BLI_assert(params->aspect_y != 0.0f);
const int cd_loop_uv_offset = params->cd_loop_uv_offset;
const int l_a_index = BM_elem_index_get(l_a);
- const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset);
- const float uv_a[2] = {luv_a->uv[0], luv_a->uv[1] / params->aspect_y};
+ const float *luv_a = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset);
+ const float uv_a[2] = {luv_a[0], luv_a[1] / params->aspect_y};
{
BMIter liter;
BMLoop *l;
/* Loop over faces of face, but do so by first looping over loops. */
BM_ITER_ELEM (l, &liter, l_a->v, BM_LOOPS_OF_VERT) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(luv_a->uv, luv->uv)) {
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_a, luv)) {
/* 'l_a' is already tagged, tag all adjacent. */
BM_elem_flag_enable(l, BM_ELEM_TAG);
BMLoop *l_b = l->next;
do {
if (!BM_elem_flag_test(l_b, BM_ELEM_TAG)) {
- const MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset);
- const float uv_b[2] = {luv_b->uv[0], luv_b->uv[1] / params->aspect_y};
+ const float *luv_b = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset);
+ const float uv_b[2] = {luv_b[0], luv_b[1] / params->aspect_y};
/* We know 'l_b' is not visited, check it out! */
const int l_b_index = BM_elem_index_get(l_b);
const float cost_cut = params->use_topology_distance ? 1.0f : len_v2v2(uv_a, uv_b);
@@ -189,13 +189,13 @@ static float edgetag_cut_cost_vert_uv(
BMLoop *l_v1 = (l_v->v == l_e_a->v) ? l_e_a->next : l_e_a;
BMLoop *l_v2 = (l_v->v == l_e_b->v) ? l_e_b->next : l_e_b;
- MLoopUV *luv_v1 = BM_ELEM_CD_GET_VOID_P(l_v1, cd_loop_uv_offset);
- MLoopUV *luv_v2 = BM_ELEM_CD_GET_VOID_P(l_v2, cd_loop_uv_offset);
- MLoopUV *luv_v = BM_ELEM_CD_GET_VOID_P(l_v, cd_loop_uv_offset);
+ float *luv_v1 = BM_ELEM_CD_GET_FLOAT_P(l_v1, cd_loop_uv_offset);
+ float *luv_v2 = BM_ELEM_CD_GET_FLOAT_P(l_v2, cd_loop_uv_offset);
+ float *luv_v = BM_ELEM_CD_GET_FLOAT_P(l_v, cd_loop_uv_offset);
- float uv_v1[2] = {luv_v1->uv[0], luv_v1->uv[1] / aspect_y};
- float uv_v2[2] = {luv_v2->uv[0], luv_v2->uv[1] / aspect_y};
- float uv_v[2] = {luv_v->uv[0], luv_v->uv[1] / aspect_y};
+ float uv_v1[2] = {luv_v1[0], luv_v1[1] / aspect_y};
+ float uv_v2[2] = {luv_v2[0], luv_v2[1] / aspect_y};
+ float uv_v[2] = {luv_v[0], luv_v[1] / aspect_y};
return step_cost_3_v2(uv_v1, uv_v, uv_v2);
}
@@ -204,11 +204,11 @@ static float edgetag_cut_cost_face_uv(
BMLoop *l_e_a, BMLoop *l_e_b, BMFace *f, const float aspect_v2[2], const int cd_loop_uv_offset)
{
float l_e_a_cent[2], l_e_b_cent[2], f_cent[2];
- MLoopUV *luv_e_a = BM_ELEM_CD_GET_VOID_P(l_e_a, cd_loop_uv_offset);
- MLoopUV *luv_e_b = BM_ELEM_CD_GET_VOID_P(l_e_b, cd_loop_uv_offset);
+ float *luv_e_a = BM_ELEM_CD_GET_FLOAT_P(l_e_a, cd_loop_uv_offset);
+ float *luv_e_b = BM_ELEM_CD_GET_FLOAT_P(l_e_b, cd_loop_uv_offset);
- mid_v2_v2v2(l_e_a_cent, luv_e_a->uv, luv_e_a->uv);
- mid_v2_v2v2(l_e_b_cent, luv_e_b->uv, luv_e_b->uv);
+ mid_v2_v2v2(l_e_a_cent, luv_e_a, luv_e_a);
+ mid_v2_v2v2(l_e_b_cent, luv_e_b, luv_e_b);
mul_v2_v2(l_e_a_cent, aspect_v2);
mul_v2_v2(l_e_b_cent, aspect_v2);
@@ -397,9 +397,8 @@ static float facetag_cut_cost_edge_uv(BMFace *f_a,
BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent);
BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent);
- const float *co_v1 = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge, cd_loop_uv_offset))->uv;
- const float *co_v2 =
- ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge->next, cd_loop_uv_offset))->uv;
+ const float *co_v1 = BM_ELEM_CD_GET_FLOAT_P(l_edge, cd_loop_uv_offset);
+ const float *co_v2 = BM_ELEM_CD_GET_FLOAT_P(l_edge->next, cd_loop_uv_offset);
#if 0
mid_v2_v2v2(e_cent, co_v1, co_v2);
@@ -444,7 +443,7 @@ static float facetag_cut_cost_vert_uv(BMFace *f_a,
BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent);
BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent);
- copy_v2_v2(v_cent, ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_vert, cd_loop_uv_offset))->uv);
+ copy_v2_v2(v_cent, BM_ELEM_CD_GET_FLOAT_P(l_vert, cd_loop_uv_offset));
mul_v2_v2(f_a_cent, aspect_v2);
mul_v2_v2(f_b_cent, aspect_v2);
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.cc b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
index 0fcbe5ab07d..83aa2aac3e8 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.cc
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc
@@ -439,10 +439,11 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
const DRWContextState *draw_ctx = DRW_context_state_get();
const bool is_edit_object = DRW_object_is_in_edit_mode(ob);
Mesh *me = (Mesh *)ob->data;
- const bool has_active_object_uvmap = CustomData_get_active_layer(&me->ldata, CD_MLOOPUV) != -1;
+ const bool has_active_object_uvmap = CustomData_get_active_layer(&me->ldata, CD_PROP_FLOAT2) !=
+ -1;
const bool has_active_edit_uvmap = is_edit_object &&
(CustomData_get_active_layer(&me->edit_mesh->bm->ldata,
- CD_MLOOPUV) != -1);
+ CD_PROP_FLOAT2) != -1);
const bool draw_shadows = (draw_ctx->object_mode != OB_MODE_OBJECT) &&
(ob->mode == draw_ctx->object_mode);
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 15a16539a26..830a9213f5a 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -297,7 +297,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
if (ob->dt < OB_TEXTURE) {
color_type = V3D_SHADING_MATERIAL_COLOR;
}
- else if ((me == NULL) || !CustomData_has_layer(ldata, CD_MLOOPUV)) {
+ else if ((me == NULL) || !CustomData_has_layer(ldata, CD_PROP_FLOAT2)) {
/* Disable color mode if data layer is unavailable. */
color_type = V3D_SHADING_MATERIAL_COLOR;
}
@@ -322,7 +322,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd,
if (!is_sculpt_pbvh && !is_render) {
/* Force texture or vertex mode if object is in paint mode. */
- if (is_texpaint_mode && me && CustomData_has_layer(ldata, CD_MLOOPUV)) {
+ if (is_texpaint_mode && me && CustomData_has_layer(ldata, CD_PROP_FLOAT2)) {
color_type = V3D_SHADING_TEXTURE_COLOR;
if (r_texpaint_mode) {
*r_texpaint_mode = true;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc
index 031de3e4ef2..0f1abf52e6f 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.cc
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc
@@ -252,7 +252,7 @@ static void mesh_cd_calc_active_uv_layer(const Object *object,
{
const Mesh *me_final = editmesh_final_or_this(object, me);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
- int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+ int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
if (layer != -1) {
cd_used->uv |= (1 << layer);
}
@@ -264,7 +264,7 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object *object,
{
const Mesh *me_final = editmesh_final_or_this(object, me);
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
- int layer = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV);
+ int layer = CustomData_get_stencil_layer(cd_ldata, CD_PROP_FLOAT2);
if (layer != -1) {
cd_used->uv |= (1 << layer);
}
@@ -318,7 +318,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
* We do it based on the specified name.
*/
if (name[0] != '\0') {
- layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name);
+ layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name);
type = CD_MTFACE;
#if 0 /* Tangents are always from UV's - this will never happen. */
@@ -360,8 +360,9 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
switch (type) {
case CD_MTFACE: {
if (layer == -1) {
- layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
- CustomData_get_render_layer(cd_ldata, CD_MLOOPUV);
+ layer = (name[0] != '\0') ?
+ CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) :
+ CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
}
if (layer != -1) {
cd_used.uv |= (1 << layer);
@@ -370,12 +371,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
}
case CD_TANGENT: {
if (layer == -1) {
- layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) :
- CustomData_get_render_layer(cd_ldata, CD_MLOOPUV);
+ layer = (name[0] != '\0') ?
+ CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) :
+ CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
/* Only fallback to orco (below) when we have no UV layers, see: T56545 */
if (layer == -1 && name[0] != '\0') {
- layer = CustomData_get_render_layer(cd_ldata, CD_MLOOPUV);
+ layer = CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
}
}
if (layer != -1) {
diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c
index cddab74c46f..6f3ad687441 100644
--- a/source/blender/draw/intern/draw_cache_impl_particles.c
+++ b/source/blender/draw/intern/draw_cache_impl_particles.c
@@ -833,10 +833,10 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
if (psmd != NULL && psmd->mesh_final != NULL) {
- if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) {
- cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV);
- active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV);
- render_uv = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_MLOOPUV);
+ if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2)) {
+ cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_FLOAT2);
+ active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2);
+ render_uv = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2);
}
if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) {
cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata,
@@ -889,7 +889,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]);
char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
+ const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_PROP_FLOAT2, i);
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
int n = 0;
@@ -1162,9 +1162,9 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
MCol **parent_mcol = NULL;
if (psmd != NULL) {
- if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) {
- num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV);
- active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV);
+ if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2)) {
+ num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_FLOAT2);
+ active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2);
}
if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) {
num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR);
@@ -1186,7 +1186,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
for (int i = 0; i < num_uv_layers; i++) {
char uuid[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
+ const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_PROP_FLOAT2, i);
GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
BLI_snprintf(uuid, sizeof(uuid), "a%s", attr_safe_name);
diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc
index 6c504e63511..3ae673f556a 100644
--- a/source/blender/draw/intern/draw_pbvh.cc
+++ b/source/blender/draw/intern/draw_pbvh.cc
@@ -605,15 +605,6 @@ struct PBVHBatches {
break;
}
- case CD_MLOOPUV: {
- MLoopUV *mloopuv = static_cast<MLoopUV *>(
- CustomData_get_layer_named(args->ldata, CD_MLOOPUV, vbo.name.c_str()));
-
- foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) {
- *static_cast<float2 *>(GPU_vertbuf_raw_step(&access)) = mloopuv[tri->tri[tri_i]].uv;
- });
- break;
- }
case CD_PROP_COLOR:
if (vbo.domain == ATTR_DOMAIN_POINT) {
MPropCol *mpropcol = static_cast<MPropCol *>(
@@ -835,10 +826,6 @@ struct PBVHBatches {
GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
need_aliases = true;
break;
- case CD_MLOOPUV:
- GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- need_aliases = true;
- break;
case CD_PBVH_FSET_TYPE:
GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
break;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc
index ec7d3a933b4..42336f7b416 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc
@@ -91,7 +91,7 @@ const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor,
void mesh_render_data_face_flag(const MeshRenderData *mr,
const BMFace *efa,
- const int cd_ofs,
+ const BMUVOffsets offsets,
EditLoopData *eattr)
{
if (efa == mr->efa_act) {
@@ -104,7 +104,7 @@ void mesh_render_data_face_flag(const MeshRenderData *mr,
if (efa == mr->efa_act_uv) {
eattr->v_flag |= VFLAG_FACE_UV_ACTIVE;
}
- if ((cd_ofs != -1) && uvedit_face_select_test_ex(mr->toolsettings, (BMFace *)efa, cd_ofs)) {
+ if ((offsets.uv != -1) && uvedit_face_select_test_ex(mr->toolsettings, (BMFace *)efa, offsets)) {
eattr->v_flag |= VFLAG_FACE_UV_SELECT;
}
@@ -121,30 +121,30 @@ void mesh_render_data_face_flag(const MeshRenderData *mr,
void mesh_render_data_loop_flag(const MeshRenderData *mr,
BMLoop *l,
- const int cd_ofs,
+ const BMUVOffsets offsets,
EditLoopData *eattr)
{
- if (cd_ofs == -1) {
+ if (offsets.uv == -1) {
return;
}
- MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_ofs);
- if (luv != nullptr && (luv->flag & MLOOPUV_PINNED)) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.pin)) {
eattr->v_flag |= VFLAG_VERT_UV_PINNED;
}
- if (uvedit_uv_select_test_ex(mr->toolsettings, l, cd_ofs)) {
+ if (uvedit_uv_select_test_ex(mr->toolsettings, l, offsets)) {
eattr->v_flag |= VFLAG_VERT_UV_SELECT;
}
}
void mesh_render_data_loop_edge_flag(const MeshRenderData *mr,
BMLoop *l,
- const int cd_ofs,
+ const BMUVOffsets offsets,
EditLoopData *eattr)
{
- if (cd_ofs == -1) {
+ if (offsets.uv == -1) {
return;
}
- if (uvedit_edge_select_test_ex(mr->toolsettings, l, cd_ofs)) {
+
+ if (uvedit_edge_select_test_ex(mr->toolsettings, l, offsets)) {
eattr->v_flag |= VFLAG_EDGE_UV_SELECT;
eattr->v_flag |= VFLAG_VERT_UV_SELECT;
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
index c6230e2695e..3693bd6a13e 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh
@@ -390,15 +390,15 @@ const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor,
bool do_single_mat);
void mesh_render_data_face_flag(const MeshRenderData *mr,
const BMFace *efa,
- int cd_ofs,
+ BMUVOffsets offsets,
EditLoopData *eattr);
void mesh_render_data_loop_flag(const MeshRenderData *mr,
BMLoop *l,
- int cd_ofs,
+ BMUVOffsets offsets,
EditLoopData *eattr);
void mesh_render_data_loop_edge_flag(const MeshRenderData *mr,
BMLoop *l,
- int cd_ofs,
+ BMUVOffsets offsets,
EditLoopData *eattr);
extern const MeshExtract extract_tris;
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
index 31dc2fdff6a..b730281e087 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
@@ -138,7 +138,7 @@ static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr,
EditLoopData *data = vbo_data + l_index;
memset(data, 0x0, sizeof(*data));
- mesh_render_data_face_flag(mr, f, -1, data);
+ mesh_render_data_face_flag(mr, f, {-1, -1, -1, -1}, data);
mesh_render_data_edge_flag(mr, l_iter->e, data);
mesh_render_data_vert_flag(mr, l_iter->v, data);
} while ((l_iter = l_iter->next) != l_first);
@@ -161,7 +161,7 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr,
BMEdge *eed = bm_original_edge_get(mr, ml->e);
BMVert *eve = bm_original_vert_get(mr, ml->v);
if (efa) {
- mesh_render_data_face_flag(mr, efa, -1, data);
+ mesh_render_data_face_flag(mr, efa, {-1, -1, -1, -1}, data);
}
if (eed) {
mesh_render_data_edge_flag(mr, eed, data);
@@ -289,7 +289,7 @@ static void extract_edit_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
/* coarse_quad can be null when called by the mesh iteration below. */
if (coarse_quad) {
/* The -1 parameter is for edit_uvs, which we don't do here. */
- mesh_render_data_face_flag(mr, coarse_quad, -1, edit_loop_data);
+ mesh_render_data_face_flag(mr, coarse_quad, {-1, -1, -1, -1}, edit_loop_data);
}
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
index 3ebf2daf1e9..6e55cca37d2 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
@@ -19,7 +19,7 @@ namespace blender::draw {
struct MeshExtract_EditUVData_Data {
EditLoopData *vbo_data;
- int cd_ofs;
+ BMUVOffsets offsets;
};
static void extract_edituv_data_init_common(const MeshRenderData *mr,
@@ -37,9 +37,8 @@ static void extract_edituv_data_init_common(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, loop_len);
- CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo);
- data->cd_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV);
+ data->offsets = BM_uv_map_get_offsets(mr->bm);
}
static void extract_edituv_data_init(const MeshRenderData *mr,
@@ -64,9 +63,9 @@ static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr,
MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data);
EditLoopData *eldata = &data->vbo_data[l_index];
memset(eldata, 0x0, sizeof(*eldata));
- mesh_render_data_loop_flag(mr, l_iter, data->cd_ofs, eldata);
- mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata);
- mesh_render_data_loop_edge_flag(mr, l_iter, data->cd_ofs, eldata);
+ mesh_render_data_loop_flag(mr, l_iter, data->offsets, eldata);
+ mesh_render_data_face_flag(mr, f, data->offsets, eldata);
+ mesh_render_data_loop_edge_flag(mr, l_iter, data->offsets, eldata);
} while ((l_iter = l_iter->next) != l_first);
}
@@ -90,8 +89,8 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
if (eed && eve) {
/* Loop on an edge endpoint. */
BMLoop *l = BM_face_edge_share_loop(efa, eed);
- mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata);
- mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata);
+ mesh_render_data_loop_flag(mr, l, data->offsets, eldata);
+ mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata);
}
else {
if (eed == nullptr) {
@@ -105,7 +104,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
if (eed) {
/* Mapped points on an edge between two edit verts. */
BMLoop *l = BM_face_edge_share_loop(efa, eed);
- mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata);
+ mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata);
}
}
}
@@ -146,8 +145,8 @@ static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cach
BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex);
/* Loop on an edge endpoint. */
BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
- mesh_render_data_loop_flag(mr, l, data->cd_ofs, edit_loop_data);
- mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data);
+ mesh_render_data_loop_flag(mr, l, data->offsets, edit_loop_data);
+ mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data);
}
else {
if (edge_origindex == -1) {
@@ -160,11 +159,11 @@ static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cach
/* Mapped points on an edge between two edit verts. */
BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex);
BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
- mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data);
+ mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data);
}
}
- mesh_render_data_face_flag(mr, coarse_quad, data->cd_ofs, edit_loop_data);
+ mesh_render_data_face_flag(mr, coarse_quad, data->offsets, edit_loop_data);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
index 492756f30bb..6d9e70d8f00 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
@@ -9,6 +9,8 @@
#include "BKE_mesh.h"
+#include "BLI_math_vec_types.hh"
+
#include "extract_mesh.hh"
#include "draw_subdivision.h"
@@ -26,7 +28,7 @@ struct UVStretchAngle {
struct MeshExtract_StretchAngle_Data {
UVStretchAngle *vbo_data;
- const MLoopUV *luv;
+ const float2 *uv;
float auv[2][2], last_auv[2];
float av[2][3], last_av[3];
int cd_ofs;
@@ -94,11 +96,11 @@ static void extract_edituv_stretch_angle_init(const MeshRenderData *mr,
/* Special iterator needed to save about half of the computing cost. */
if (mr->extract_type == MR_EXTRACT_BMESH) {
- data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV);
+ data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_PROP_FLOAT2);
}
else {
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
- data->luv = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
+ data->uv = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2);
}
}
@@ -115,18 +117,18 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
do {
const int l_index = BM_elem_index_get(l_iter);
- const MLoopUV *luv, *luv_next;
+ const float(*luv)[2], (*luv_next)[2];
BMLoop *l_next = l_iter->next;
if (l_iter == BM_FACE_FIRST_LOOP(f)) {
/* First loop in face. */
BMLoop *l_tmp = l_iter->prev;
BMLoop *l_next_tmp = l_iter;
- luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_tmp, data->cd_ofs);
- luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next_tmp, data->cd_ofs);
+ luv = BM_ELEM_CD_GET_FLOAT2_P(l_tmp, data->cd_ofs);
+ luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next_tmp, data->cd_ofs);
compute_normalize_edge_vectors(auv,
av,
- luv->uv,
- luv_next->uv,
+ *luv,
+ *luv_next,
bm_vert_co_get(mr, l_tmp->v),
bm_vert_co_get(mr, l_next_tmp->v));
/* Save last edge. */
@@ -142,14 +144,10 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr,
copy_v3_v3(av[1], last_av);
}
else {
- luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs);
- luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next, data->cd_ofs);
- compute_normalize_edge_vectors(auv,
- av,
- luv->uv,
- luv_next->uv,
- bm_vert_co_get(mr, l_iter->v),
- bm_vert_co_get(mr, l_next->v));
+ luv = BM_ELEM_CD_GET_FLOAT2_P(l_iter, data->cd_ofs);
+ luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next, data->cd_ofs);
+ compute_normalize_edge_vectors(
+ auv, av, *luv, *luv_next, bm_vert_co_get(mr, l_iter->v), bm_vert_co_get(mr, l_next->v));
}
edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[l_index]);
} while ((l_iter = l_iter->next) != l_first);
@@ -175,7 +173,7 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
v = &mr->mvert[mr->mloop[ml_index_last].v];
v_next = &mr->mvert[mr->mloop[l_next_tmp].v];
compute_normalize_edge_vectors(
- auv, av, data->luv[ml_index_last].uv, data->luv[l_next_tmp].uv, v->co, v_next->co);
+ auv, av, data->uv[ml_index_last], data->uv[l_next_tmp], v->co, v_next->co);
/* Save last edge. */
copy_v2_v2(last_auv, auv[1]);
copy_v3_v3(last_av, av[1]);
@@ -193,7 +191,7 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr
v = &mr->mvert[mr->mloop[ml_index].v];
v_next = &mr->mvert[mr->mloop[l_next].v];
compute_normalize_edge_vectors(
- auv, av, data->luv[ml_index].uv, data->luv[l_next].uv, v->co, v_next->co);
+ auv, av, data->uv[ml_index], data->uv[l_next], v->co, v_next->co);
}
edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]);
}
@@ -246,7 +244,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
uint32_t uv_layers = cache->cd_used.uv;
/* HACK to fix T68857 */
if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) {
- int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+ int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
if (layer != -1) {
uv_layers |= (1 << layer);
}
@@ -255,7 +253,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
int uvs_offset = 0;
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
- if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
break;
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
index 7c96fbd6a99..88bad80ea7d 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
@@ -5,6 +5,8 @@
* \ingroup draw
*/
+#include "BLI_math_vec_types.hh"
+
#include "MEM_guardedalloc.h"
#include "BKE_mesh.h"
@@ -57,7 +59,7 @@ static void compute_area_ratio(const MeshRenderData *mr,
if (mr->extract_type == MR_EXTRACT_BMESH) {
CustomData *cd_ldata = &mr->bm->ldata;
- int uv_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV);
+ int uv_ofs = CustomData_get_offset(cd_ldata, CD_PROP_FLOAT2);
BMFace *efa;
BMIter f_iter;
@@ -72,11 +74,12 @@ static void compute_area_ratio(const MeshRenderData *mr,
}
else {
BLI_assert(mr->extract_type == MR_EXTRACT_MESH);
- const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
+ const float2 *uv_data = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2);
const MPoly *mp = mr->mpoly;
for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) {
float area = BKE_mesh_calc_poly_area(mp, &mr->mloop[mp->loopstart], mr->mvert);
- float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data);
+ float uvarea = area_poly_v2(reinterpret_cast<const float(*)[2]>(&uv_data[mp->loopstart]),
+ mp->totloop);
tot_area += area;
tot_uv_area += uvarea;
r_area_ratio[mp_index] = area_ratio_get(area, uvarea);
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
index 55ad2e67487..1ac4512bab0 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
@@ -17,7 +17,7 @@ namespace blender::draw {
struct MeshExtract_EditUVFdotData_Data {
EditLoopData *vbo_data;
- int cd_ofs;
+ BMUVOffsets offsets;
};
static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
@@ -36,7 +36,7 @@ static void extract_fdots_edituv_data_init(const MeshRenderData *mr,
MeshExtract_EditUVFdotData_Data *data = static_cast<MeshExtract_EditUVFdotData_Data *>(tls_data);
data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo);
- data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV);
+ data->offsets = BM_uv_map_get_offsets(mr->bm);
}
static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
@@ -47,7 +47,7 @@ static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr,
MeshExtract_EditUVFdotData_Data *data = static_cast<MeshExtract_EditUVFdotData_Data *>(_data);
EditLoopData *eldata = &data->vbo_data[BM_elem_index_get(f)];
memset(eldata, 0x0, sizeof(*eldata));
- mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata);
+ mesh_render_data_face_flag(mr, f, data->offsets, eldata);
}
static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
@@ -60,7 +60,7 @@ static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
memset(eldata, 0x0, sizeof(*eldata));
BMFace *efa = bm_original_face_get(mr, mp_index);
if (efa) {
- mesh_render_data_face_flag(mr, efa, data->cd_ofs, eldata);
+ mesh_render_data_face_flag(mr, efa, data->offsets, eldata);
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
index 802f000cb43..c8d4144f38c 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
@@ -17,7 +17,7 @@ namespace blender::draw {
struct MeshExtract_FdotUV_Data {
float (*vbo_data)[2];
- const MLoopUV *uv_data;
+ const float (*uv_data)[2];
int cd_ofs;
};
@@ -46,10 +46,10 @@ static void extract_fdots_uv_init(const MeshRenderData *mr,
data->vbo_data = (float(*)[2])GPU_vertbuf_get_data(vbo);
if (mr->extract_type == MR_EXTRACT_BMESH) {
- data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV);
+ data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_PROP_FLOAT2);
}
else {
- data->uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV);
+ data->uv_data = (const float(*)[2])CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2);
}
}
@@ -63,8 +63,8 @@ static void extract_fdots_uv_iter_poly_bm(const MeshRenderData * /*mr*/,
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
float w = 1.0f / float(f->len);
- const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs);
- madd_v2_v2fl(data->vbo_data[BM_elem_index_get(f)], luv->uv, w);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, data->cd_ofs);
+ madd_v2_v2fl(data->vbo_data[BM_elem_index_get(f)], luv, w);
} while ((l_iter = l_iter->next) != l_first);
}
@@ -82,12 +82,12 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
const MLoop *ml = &mloop[ml_index];
if (mr->use_subsurf_fdots) {
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
- copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index].uv);
+ copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index]);
}
}
else {
float w = 1.0f / float(mp->totloop);
- madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index].uv, w);
+ madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index], w);
}
}
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
index 6f0c98c684b..578ef48ecc3 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
@@ -48,7 +48,8 @@ static void extract_tan_init_common(const MeshRenderData *mr,
/* FIXME(T91838): This is to avoid a crash when orco tangent was requested but there are valid
* uv layers. It would be better to fix the root cause. */
- if (tan_layers == 0 && use_orco_tan && CustomData_get_layer_index(cd_ldata, CD_MLOOPUV) != -1) {
+ if (tan_layers == 0 && use_orco_tan &&
+ CustomData_get_layer_index(cd_ldata, CD_PROP_FLOAT2) != -1) {
tan_layers = 1;
use_orco_tan = false;
}
@@ -56,17 +57,17 @@ static void extract_tan_init_common(const MeshRenderData *mr,
for (int i = 0; i < MAX_MTFACE; i++) {
if (tan_layers & (1 << i)) {
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
+ const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_PROP_FLOAT2, i);
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
/* Tangent layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name);
GPU_vertformat_attr_add(format, attr_name, comp_type, 4, fetch_mode);
/* Active render layer name. */
- if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2)) {
GPU_vertformat_alias_add(format, "t");
}
/* Active display layer name. */
- if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
GPU_vertformat_alias_add(format, "at");
}
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
index fe6e31af3c2..025de5463e1 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
@@ -5,6 +5,7 @@
* \ingroup draw
*/
+#include "BLI_math_vec_types.hh"
#include "BLI_string.h"
#include "draw_subdivision.h"
@@ -29,7 +30,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
uint32_t uv_layers = cache->cd_used.uv;
/* HACK to fix T68857 */
if (extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) {
- int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+ int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
if (layer != -1) {
uv_layers |= (1 << layer);
}
@@ -40,24 +41,24 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
- const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i);
+ const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_PROP_FLOAT2, i);
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
/* UV layer name. */
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
GPU_vertformat_attr_add(format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
/* Active render layer name. */
- if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2)) {
GPU_vertformat_alias_add(format, "a");
}
/* Active display layer name. */
- if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
GPU_vertformat_alias_add(format, "au");
/* Alias to `pos` for edit uvs. */
GPU_vertformat_alias_add(format, "pos");
}
/* Stencil mask uv layer name. */
- if (i == CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV)) {
+ if (i == CustomData_get_stencil_layer(cd_ldata, CD_PROP_FLOAT2)) {
GPU_vertformat_alias_add(format, "mu");
}
}
@@ -90,28 +91,28 @@ static void extract_uv_init(const MeshRenderData *mr,
GPU_vertbuf_init_with_format(vbo, &format);
GPU_vertbuf_data_alloc(vbo, v_len);
- float(*uv_data)[2] = (float(*)[2])GPU_vertbuf_get_data(vbo);
+ float2 *uv_data = static_cast<float2 *>(GPU_vertbuf_get_data(vbo));
for (int i = 0; i < MAX_MTFACE; i++) {
if (uv_layers & (1 << i)) {
if (mr->extract_type == MR_EXTRACT_BMESH) {
- int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_MLOOPUV, i);
+ int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_PROP_FLOAT2, i);
BMIter f_iter;
BMFace *efa;
BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) {
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
do {
- MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_ofs);
- memcpy(uv_data, luv->uv, sizeof(*uv_data));
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_ofs);
+ memcpy(uv_data, luv, sizeof(*uv_data));
uv_data++;
} while ((l_iter = l_iter->next) != l_first);
}
}
else {
- const MLoopUV *layer_data = (const MLoopUV *)CustomData_get_layer_n(
- cd_ldata, CD_MLOOPUV, i);
+ const float2 *layer_data = static_cast<float2 *>(
+ CustomData_get_layer_n(cd_ldata, CD_PROP_FLOAT2, i));
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, uv_data++, layer_data++) {
- memcpy(uv_data, layer_data->uv, sizeof(*uv_data));
+ memcpy(uv_data, layer_data, sizeof(*uv_data));
}
}
}
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index 1d2b1264477..364bd15ca5c 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -965,7 +965,7 @@ static int surface_set_exec(bContext *C, wmOperator *op)
Mesh &new_surface_mesh = *static_cast<Mesh *>(new_surface_ob.data);
const char *new_uv_map_name = CustomData_get_active_layer_name(&new_surface_mesh.ldata,
- CD_MLOOPUV);
+ CD_PROP_FLOAT2);
CTX_DATA_BEGIN (C, Object *, selected_ob, selected_objects) {
if (selected_ob->type != OB_CURVES) {
diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc
index 7f163da493b..5b0202dcbe1 100644
--- a/source/blender/editors/geometry/geometry_attributes.cc
+++ b/source/blender/editors/geometry/geometry_attributes.cc
@@ -246,7 +246,6 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op)
enum class ConvertAttributeMode {
Generic,
- UVMap,
VertexGroup,
};
@@ -299,23 +298,6 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
}
break;
}
- case ConvertAttributeMode::UVMap: {
- MLoopUV *dst_uvs = static_cast<MLoopUV *>(
- MEM_calloc_arrayN(mesh->totloop, sizeof(MLoopUV), __func__));
- VArray<float2> src_varray = attributes.lookup_or_default<float2>(
- name, ATTR_DOMAIN_CORNER, {0.0f, 0.0f});
- for (const int i : IndexRange(mesh->totloop)) {
- copy_v2_v2(dst_uvs[i].uv, src_varray[i]);
- }
- attributes.remove(name);
- CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_ASSIGN, dst_uvs, mesh->totloop, name.c_str());
- int *active_index = BKE_id_attributes_active_index_p(&mesh->id);
- if (*active_index > 0) {
- *active_index -= 1;
- }
- break;
- }
case ConvertAttributeMode::VertexGroup: {
Array<float> src_weights(mesh->totvert);
VArray<float> src_varray = attributes.lookup_or_default<float>(
@@ -671,7 +653,6 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot)
static EnumPropertyItem mode_items[] = {
{int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""},
- {int(ConvertAttributeMode::UVMap), "UV_MAP", 0, "UV Map", ""},
{int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""},
{0, nullptr, 0, nullptr, nullptr},
};
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 52527f6c1b8..76f7e3b2c3e 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -552,12 +552,17 @@ void ED_mesh_geometry_clear(struct Mesh *mesh);
void ED_mesh_update(struct Mesh *mesh, struct bContext *C, bool calc_edges, bool calc_edges_loose);
+bool *ED_mesh_uv_map_ensure_vert_selection(struct Mesh *mesh, int uv_index);
+bool *ED_mesh_uv_map_ensure_edge_selection(struct Mesh *mesh, int uv_index);
+bool *ED_mesh_uv_map_ensure_pin(struct Mesh *mesh, int uv_index);
+const bool *ED_mesh_uv_map_get_vert_selection(const struct Mesh *mesh, int uv_index);
+const bool *ED_mesh_uv_map_get_edge_selection(const struct Mesh *mesh, int uv_index);
+const bool *ED_mesh_uv_map_get_pin(const struct Mesh *mesh, int uv_index);
+
void ED_mesh_uv_ensure(struct Mesh *me, const char *name);
int ED_mesh_uv_add(
struct Mesh *me, const char *name, bool active_set, bool do_init, struct ReportList *reports);
-bool ED_mesh_uv_remove_index(struct Mesh *me, int n);
-bool ED_mesh_uv_remove_active(struct Mesh *me);
-bool ED_mesh_uv_remove_named(struct Mesh *me, const char *name);
+
void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me);
/**
* Without a #bContext, called when UV-editing.
diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h
index 5fea8711a84..c8c7ac96b32 100644
--- a/source/blender/editors/include/ED_uvedit.h
+++ b/source/blender/editors/include/ED_uvedit.h
@@ -7,6 +7,8 @@
#pragma once
+#include "BKE_customdata.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -30,6 +32,7 @@ struct bContext;
struct bNode;
struct bNodeTree;
struct wmKeyConfig;
+struct BMUVOffsets;
/* uvedit_ops.c */
@@ -87,17 +90,19 @@ bool ED_uvedit_test(struct Object *obedit);
bool uvedit_face_visible_test_ex(const struct ToolSettings *ts, struct BMFace *efa);
bool uvedit_face_select_test_ex(const struct ToolSettings *ts,
struct BMFace *efa,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
+
bool uvedit_edge_select_test_ex(const struct ToolSettings *ts,
struct BMLoop *l,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
bool uvedit_uv_select_test_ex(const struct ToolSettings *ts,
struct BMLoop *l,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
+
bool uvedit_face_visible_test(const struct Scene *scene, struct BMFace *efa);
-bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, int cd_loop_uv_offset);
-bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset);
-bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset);
+bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, BMUVOffsets offsets);
+bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, BMUVOffsets offsets);
+bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, BMUVOffsets offsets);
/* Individual UV element selection functions. */
@@ -111,7 +116,7 @@ void uvedit_face_select_set(const struct Scene *scene,
struct BMFace *efa,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/**
* \brief Select UV Edge
*
@@ -122,7 +127,7 @@ void uvedit_edge_select_set(const struct Scene *scene,
struct BMLoop *l,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/**
* \brief Select UV Vertex
*
@@ -133,7 +138,7 @@ void uvedit_uv_select_set(const struct Scene *scene,
struct BMLoop *l,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/* Low level functions for (de)selecting individual UV elements. Ensure UV face visibility before
* use. */
@@ -142,29 +147,31 @@ void uvedit_face_select_enable(const struct Scene *scene,
struct BMesh *bm,
struct BMFace *efa,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_face_select_disable(const struct Scene *scene,
struct BMesh *bm,
struct BMFace *efa,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
+
void uvedit_edge_select_enable(const struct Scene *scene,
struct BMesh *bm,
struct BMLoop *l,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_edge_select_disable(const struct Scene *scene,
struct BMesh *bm,
struct BMLoop *l,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
+
void uvedit_uv_select_enable(const struct Scene *scene,
struct BMesh *bm,
struct BMLoop *l,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_uv_select_disable(const struct Scene *scene,
struct BMesh *bm,
struct BMLoop *l,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/* Sticky mode UV element selection functions. */
@@ -173,19 +180,20 @@ void uvedit_face_select_set_with_sticky(const struct Scene *scene,
struct BMFace *efa,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_edge_select_set_with_sticky(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
+
void uvedit_uv_select_set_with_sticky(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
bool select,
bool do_history,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/* Low level functions for sticky element selection (sticky mode independent). Type of sticky
* selection is specified explicitly (using sticky_flag, except for face selection). */
@@ -195,28 +203,28 @@ void uvedit_face_select_shared_vert(const struct Scene *scene,
struct BMFace *efa,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_edge_select_shared_vert(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
const bool select,
const int sticky_flag,
const bool do_history,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void uvedit_uv_select_shared_vert(const struct Scene *scene,
struct BMEditMesh *em,
struct BMLoop *l,
const bool select,
const int sticky_flag,
const bool do_history,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/* Sets required UV edge flags as specified by the sticky_flag. */
void uvedit_edge_select_set_noflush(const struct Scene *scene,
struct BMLoop *l,
const bool select,
const int sticky_flag,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/**
* \brief UV Select Mode set
@@ -315,7 +323,7 @@ struct FaceIsland {
* \note While this is duplicate information,
* it allows islands from multiple meshes to be stored in the same list.
*/
- int cd_loop_uv_offset;
+ BMUVOffsets offsets;
float aspect_y;
};
@@ -326,7 +334,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
const bool only_selected_uvs,
const bool use_seams,
const float aspect_y,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
struct UVMapUDIM_Params {
const struct Image *image;
diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc
index 2ef2772d404..fdf39701384 100644
--- a/source/blender/editors/mesh/editmesh_select.cc
+++ b/source/blender/editors/mesh/editmesh_select.cc
@@ -3211,7 +3211,7 @@ static int select_linked_delimit_default_from_op(wmOperator *op, const int selec
static void select_linked_delimit_validate(BMesh *bm, int *delimit)
{
if ((*delimit) & BMO_DELIM_UV) {
- if (!CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2)) {
(*delimit) &= ~BMO_DELIM_UV;
}
}
@@ -3222,7 +3222,7 @@ static void select_linked_delimit_begin(BMesh *bm, int delimit)
DelimitData delimit_data = {0};
if (delimit & BMO_DELIM_UV) {
- delimit_data.cd_loop_type = CD_MLOOPUV;
+ delimit_data.cd_loop_type = CD_PROP_FLOAT2;
delimit_data.cd_loop_offset = CustomData_get_offset(&bm->ldata, delimit_data.cd_loop_type);
if (delimit_data.cd_loop_offset == -1) {
delimit &= ~BMO_DELIM_UV;
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index bbc092d0a99..3f1981b1e75 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -459,10 +459,10 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
/* vars from original func */
UvVertMap *vmap;
UvMapVert *buf;
- const MLoopUV *luv;
+ const float(*luv)[2];
uint a;
int totverts, i, totuv, totfaces;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
bool *winding = NULL;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
@@ -516,8 +516,8 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
buf++;
if (use_winding) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(tf_uv[i], luv->uv);
+ luv = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset);
+ copy_v2_v2(tf_uv[i], *luv);
}
}
@@ -542,8 +542,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
efa = BM_face_at_index(bm, v->poly_index);
l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->loop_of_poly_index);
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- uv = luv->uv;
+ uv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
lastv = NULL;
iterv = vlist;
@@ -552,8 +551,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us
next = iterv->next;
efa = BM_face_at_index(bm, iterv->poly_index);
l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index);
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- uv2 = luv->uv;
+ uv2 = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT) &&
(!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) {
@@ -682,7 +680,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
UvElement *islandbuf,
uint *map,
bool uv_selected,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BM_uv_element_map_ensure_head_table(element_map);
@@ -723,7 +721,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
while (element) {
/* Scan forwards around the BMFace that contains element->l. */
- if (!uv_selected || uvedit_edge_select_test(scene, element->l, cd_loop_uv_offset)) {
+ if (!uv_selected || uvedit_edge_select_test(scene, element->l, offsets)) {
UvElement *next = BM_uv_element_get(element_map, element->l->next->f, element->l->next);
if (next->island == INVALID_ISLAND) {
UvElement *tail = element_map->head_table[next - element_map->storage];
@@ -739,7 +737,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map,
}
/* Scan backwards around the BMFace that contains element->l. */
- if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, cd_loop_uv_offset)) {
+ if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, offsets)) {
UvElement *prev = BM_uv_element_get(element_map, element->l->prev->f, element->l->prev);
if (prev->island == INVALID_ISLAND) {
UvElement *tail = element_map->head_table[prev - element_map->storage];
@@ -788,14 +786,14 @@ static void bm_uv_build_islands(UvElementMap *element_map,
int *island_number = MEM_callocN(sizeof(*island_number) * bm->totface, "uv_island_number_face");
copy_vn_i(island_number, bm->totface, INVALID_ISLAND);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets uv_offsets = BM_uv_map_get_offsets(bm);
const bool use_uv_edge_connectivity = scene->toolsettings->uv_flag & UV_SYNC_SELECTION ?
scene->toolsettings->selectmode & SCE_SELECT_EDGE :
scene->toolsettings->uv_selectmode & UV_SELECT_EDGE;
if (use_uv_edge_connectivity) {
nislands = bm_uv_edge_select_build_islands(
- element_map, scene, islandbuf, map, uv_selected, cd_loop_uv_offset);
+ element_map, scene, islandbuf, map, uv_selected, uv_offsets);
islandbufsize = totuv;
}
@@ -813,7 +811,7 @@ static void bm_uv_build_islands(UvElementMap *element_map,
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uv_selected && !uvedit_uv_select_test(scene, l, uv_offsets)) {
continue;
}
@@ -890,20 +888,23 @@ static void bm_uv_build_islands(UvElementMap *element_map,
}
/* return true if `loop` has UV co-ordinates which match `luv_a` and `luv_b` */
-static bool loop_uv_match(BMLoop *loop, MLoopUV *luv_a, MLoopUV *luv_b, int cd_loop_uv_offset)
+static bool loop_uv_match(BMLoop *loop,
+ const float luv_a[2],
+ const float luv_b[2],
+ int cd_loop_uv_offset)
{
- MLoopUV *luv_c = BM_ELEM_CD_GET_VOID_P(loop, cd_loop_uv_offset);
- MLoopUV *luv_d = BM_ELEM_CD_GET_VOID_P(loop->next, cd_loop_uv_offset);
- return compare_v2v2(luv_a->uv, luv_c->uv, STD_UV_CONNECT_LIMIT) &&
- compare_v2v2(luv_b->uv, luv_d->uv, STD_UV_CONNECT_LIMIT);
+ const float *luv_c = BM_ELEM_CD_GET_FLOAT_P(loop, cd_loop_uv_offset);
+ const float *luv_d = BM_ELEM_CD_GET_FLOAT_P(loop->next, cd_loop_uv_offset);
+ return compare_v2v2(luv_a, luv_c, STD_UV_CONNECT_LIMIT) &&
+ compare_v2v2(luv_b, luv_d, STD_UV_CONNECT_LIMIT);
}
/* Given `anchor` and `edge`, return true if there are edges that fan between them that are
* seam-free. */
static bool seam_connected_recursive(BMVert *anchor,
BMEdge *edge,
- MLoopUV *luv_anchor,
- MLoopUV *luv_fan,
+ float luv_anchor[2],
+ float luv_fan[2],
BMLoop *needle,
GSet *visited,
int cd_loop_uv_offset)
@@ -931,7 +932,7 @@ static bool seam_connected_recursive(BMVert *anchor,
return true; /* Success. */
}
- MLoopUV *luv_far = BM_ELEM_CD_GET_VOID_P(loop->prev, cd_loop_uv_offset);
+ float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset);
if (seam_connected_recursive(
anchor, loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
return true;
@@ -947,7 +948,7 @@ static bool seam_connected_recursive(BMVert *anchor,
return true; /* Success. */
}
- MLoopUV *luv_far = BM_ELEM_CD_GET_VOID_P(loop->next->next, cd_loop_uv_offset);
+ float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset);
if (seam_connected_recursive(
anchor, loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) {
return true;
@@ -970,8 +971,8 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd
BLI_gset_clear(visited, NULL);
- MLoopUV *luv_anchor = BM_ELEM_CD_GET_VOID_P(loop_a, cd_loop_uv_offset);
- MLoopUV *luv_fan = BM_ELEM_CD_GET_VOID_P(loop_a->next, cd_loop_uv_offset);
+ float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset);
+ float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset);
const bool result = seam_connected_recursive(
loop_a->v, loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset);
return result;
@@ -991,9 +992,9 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
BMFace *efa;
BMIter iter, liter;
BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
- MLoopUV *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- if (cd_loop_uv_offset < 0) {
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+ if (offsets.uv < 0) {
return NULL;
}
@@ -1016,7 +1017,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
else {
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
totuv++;
}
}
@@ -1057,7 +1058,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
int i;
BMLoop *l;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uv_selected && !uvedit_uv_select_test(scene, l, offsets)) {
continue;
}
@@ -1070,8 +1071,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
element_map->vertex[BM_elem_index_get(l->v)] = buf;
if (use_winding) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(tf_uv[i], luv->uv);
+ const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ copy_v2_v2(tf_uv[i], uv);
}
buf++;
@@ -1098,9 +1099,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
v->next = newvlist;
newvlist = v;
- luv = BM_ELEM_CD_GET_VOID_P(v->l, cd_loop_uv_offset);
- const float *uv = luv->uv;
- bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, cd_loop_uv_offset);
+ const float *uv = BM_ELEM_CD_GET_VOID_P(v->l, offsets.uv);
+ bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, offsets);
UvElement *lastv = NULL;
UvElement *iterv = vlist;
@@ -1108,20 +1108,19 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
/* Scan through unsorted list, finding UvElements which are connected to `v`. */
while (iterv) {
UvElement *next = iterv->next;
- luv = BM_ELEM_CD_GET_VOID_P(iterv->l, cd_loop_uv_offset);
bool connected = true; /* Assume connected unless we can prove otherwise. */
if (connected) {
/* Are the two UVs close together? */
- const float *uv2 = luv->uv;
+ const float *uv2 = BM_ELEM_CD_GET_FLOAT_P(iterv->l, offsets.uv);
connected = compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT);
}
if (connected) {
/* Check if the uv loops share the same selection state (if not, they are not connected
* as they have been ripped or other edit commands have separated them). */
- const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, cd_loop_uv_offset);
+ const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, offsets);
connected = (uv_vert_sel == uv2_vert_sel);
}
@@ -1131,7 +1130,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm,
}
if (connected && use_seams) {
- connected = seam_connected(iterv->l, v->l, seam_visited_gset, cd_loop_uv_offset);
+ connected = seam_connected(iterv->l, v->l, seam_visited_gset, offsets.uv);
}
if (connected) {
@@ -1257,7 +1256,7 @@ BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool se
bool EDBM_uv_check(BMEditMesh *em)
{
/* some of these checks could be a touch overkill */
- return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV);
+ return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2);
}
bool EDBM_vert_color_check(BMEditMesh *em)
diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc
index 9901f4e1836..f6d16acdb2d 100644
--- a/source/blender/editors/mesh/mesh_data.cc
+++ b/source/blender/editors/mesh/mesh_data.cc
@@ -17,7 +17,6 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
-#include "BKE_attribute.h"
#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
@@ -35,6 +34,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "BLT_translation.h"
+
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_paint.h"
@@ -45,6 +46,7 @@
#include "mesh_intern.h" /* own include */
using blender::Array;
+using blender::float2;
using blender::MutableSpan;
using blender::Span;
@@ -107,32 +109,6 @@ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_t
}
#define GET_CD_DATA(me, data) ((me)->edit_mesh ? &(me)->edit_mesh->bm->data : &(me)->data)
-static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
-{
- const int type = layer->type;
- CustomData *data;
- int layer_index, tot, n;
-
- char htype = BM_FACE;
- if (ELEM(type, CD_PROP_BYTE_COLOR, CD_MLOOPUV)) {
- htype = BM_LOOP;
- }
- else if (ELEM(type, CD_PROP_COLOR)) {
- htype = BM_VERT;
- }
-
- data = mesh_customdata_get_type(me, htype, &tot);
- layer_index = CustomData_get_layer_index(data, type);
- n = (layer - &data->layers[layer_index]);
- BLI_assert(n >= 0 && (n + layer_index) < data->totlayer);
-
- if (me->edit_mesh) {
- BM_data_layer_free_n(me->edit_mesh->bm, data, type, n);
- }
- else {
- CustomData_free_layer(data, type, tot, layer_index + n);
- }
-}
static void mesh_uv_reset_array(float **fuv, const int len)
{
@@ -182,18 +158,18 @@ static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset)
int i;
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, i) {
- fuv[i] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv;
+ fuv[i] = ((float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset));
}
mesh_uv_reset_array(fuv.data(), f->len);
}
-static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv)
+static void mesh_uv_reset_mface(const MPoly *mp, float2 *mloopuv)
{
Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop);
for (int i = 0; i < mp->totloop; i++) {
- fuv[i] = mloopuv[mp->loopstart + i].uv;
+ fuv[i] = mloopuv[mp->loopstart + i];
}
mesh_uv_reset_array(fuv.data(), mp->totloop);
@@ -205,7 +181,8 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
if (em) {
/* Collect BMesh UVs */
- const int cd_loop_uv_offset = CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, layernum);
+ const int cd_loop_uv_offset = CustomData_get_n_offset(
+ &em->bm->ldata, CD_PROP_FLOAT2, layernum);
BMFace *efa;
BMIter iter;
@@ -222,8 +199,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
}
else {
/* Collect Mesh UVs */
- BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
- MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum);
+ BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2));
+ float2 *mloopuv = static_cast<float2 *>(
+ CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, layernum));
const MPoly *polys = BKE_mesh_polys(me);
for (int i = 0; i < me->totpoly; i++) {
@@ -238,7 +216,7 @@ void ED_mesh_uv_loop_reset(bContext *C, Mesh *me)
{
/* could be ldata or pdata */
CustomData *ldata = GET_CD_DATA(me, ldata);
- const int layernum = CustomData_get_active_layer(ldata, CD_MLOOPUV);
+ const int layernum = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2);
ED_mesh_uv_loop_reset_ex(me, layernum);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
@@ -252,40 +230,43 @@ int ED_mesh_uv_add(
BMEditMesh *em;
int layernum_dst;
+ if (!name) {
+ name = DATA_("UVMap");
+ }
+
bool is_init = false;
if (me->edit_mesh) {
em = me->edit_mesh;
- layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV);
+ layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2);
if (layernum_dst >= MAX_MTFACE) {
BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE);
return -1;
}
- /* CD_MLOOPUV */
- BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name);
+ BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, name);
/* copy data from active UV */
if (layernum_dst && do_init) {
- const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV);
- BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum_src, layernum_dst);
+ const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_data_layer_copy(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, layernum_src, layernum_dst);
is_init = true;
}
if (active_set || layernum_dst == 0) {
- CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum_dst);
+ CustomData_set_layer_active(&em->bm->ldata, CD_PROP_FLOAT2, layernum_dst);
}
}
else {
- layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (layernum_dst >= MAX_MTFACE) {
BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE);
return -1;
}
- if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) {
+ if (CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2) && do_init) {
CustomData_add_layer_named(&me->ldata,
- CD_MLOOPUV,
+ CD_PROP_FLOAT2,
CD_DUPLICATE,
CustomData_get_layer(&me->ldata, CD_MLOOPUV),
me->totloop,
@@ -294,11 +275,11 @@ int ED_mesh_uv_add(
}
else {
CustomData_add_layer_named(
- &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, name);
+ &me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, me->totloop, name);
}
if (active_set || layernum_dst == 0) {
- CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
+ CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, layernum_dst);
}
}
@@ -313,6 +294,68 @@ int ED_mesh_uv_add(
return layernum_dst;
}
+static const bool *get_corner_boolean_attribute(const Mesh &mesh,
+ const blender::StringRefNull name)
+{
+ return static_cast<const bool *>(
+ CustomData_get_layer_named(&mesh.ldata, CD_PROP_BOOL, name.c_str()));
+}
+
+const bool *ED_mesh_uv_map_get_vert_selection(const Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return get_corner_boolean_attribute(*mesh, get_uv_map_vert_selection_name(uv_name, buffer));
+}
+const bool *ED_mesh_uv_map_get_edge_selection(const Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return get_corner_boolean_attribute(*mesh, get_uv_map_edge_selection_name(uv_name, buffer));
+}
+const bool *ED_mesh_uv_map_get_pin(const Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return get_corner_boolean_attribute(*mesh, get_uv_map_pin_name(uv_name, buffer));
+}
+
+static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name)
+{
+ bool *data = static_cast<bool *>(CustomData_duplicate_referenced_layer_named(
+ &mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop));
+ if (!data) {
+ data = static_cast<bool *>(CustomData_add_layer_named(
+ &mesh.ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh.totpoly, name.c_str()));
+ }
+ return data;
+}
+
+bool *ED_mesh_uv_map_ensure_vert_selection(Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return ensure_corner_boolean_attribute(*mesh, get_uv_map_vert_selection_name(uv_name, buffer));
+}
+bool *ED_mesh_uv_map_ensure_edge_selection(Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return ensure_corner_boolean_attribute(*mesh, get_uv_map_edge_selection_name(uv_name, buffer));
+}
+bool *ED_mesh_uv_map_ensure_pin(Mesh *mesh, const int uv_index)
+{
+ using namespace blender::bke;
+ char buffer[MAX_CUSTOMDATA_LAYER_NAME];
+ const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index);
+ return ensure_corner_boolean_attribute(*mesh, get_uv_map_pin_name(uv_name, buffer));
+}
+
void ED_mesh_uv_ensure(Mesh *me, const char *name)
{
BMEditMesh *em;
@@ -321,59 +364,19 @@ void ED_mesh_uv_ensure(Mesh *me, const char *name)
if (me->edit_mesh) {
em = me->edit_mesh;
- layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV);
+ layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2);
if (layernum_dst == 0) {
ED_mesh_uv_add(me, name, true, true, nullptr);
}
}
else {
- layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (layernum_dst == 0) {
ED_mesh_uv_add(me, name, true, true, nullptr);
}
}
}
-bool ED_mesh_uv_remove_index(Mesh *me, const int n)
-{
- CustomData *ldata = GET_CD_DATA(me, ldata);
- CustomDataLayer *cdlu;
- int index;
-
- index = CustomData_get_layer_index_n(ldata, CD_MLOOPUV, n);
- cdlu = (index == -1) ? nullptr : &ldata->layers[index];
-
- if (!cdlu) {
- return false;
- }
-
- delete_customdata_layer(me, cdlu);
-
- DEG_id_tag_update(&me->id, 0);
- WM_main_add_notifier(NC_GEOM | ND_DATA, me);
-
- return true;
-}
-bool ED_mesh_uv_remove_active(Mesh *me)
-{
- CustomData *ldata = GET_CD_DATA(me, ldata);
- const int n = CustomData_get_active_layer(ldata, CD_MLOOPUV);
-
- if (n != -1) {
- return ED_mesh_uv_remove_index(me, n);
- }
- return false;
-}
-bool ED_mesh_uv_remove_named(Mesh *me, const char *name)
-{
- CustomData *ldata = GET_CD_DATA(me, ldata);
- const int n = CustomData_get_named_layer(ldata, CD_MLOOPUV, name);
- if (n != -1) {
- return ED_mesh_uv_remove_index(me, n);
- }
- return false;
-}
-
int ED_mesh_color_add(Mesh *me,
const char *name,
const bool active_set,
@@ -525,7 +528,7 @@ static bool uv_texture_remove_poll(bContext *C)
Object *ob = ED_object_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
CustomData *ldata = GET_CD_DATA(me, ldata);
- const int active = CustomData_get_active_layer(ldata, CD_MLOOPUV);
+ const int active = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2);
if (active != -1) {
return true;
}
@@ -566,12 +569,14 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int mesh_uv_texture_remove_exec(bContext *C, wmOperator * /*op*/)
+static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
- if (!ED_mesh_uv_remove_active(me)) {
+ CustomData *ldata = GET_CD_DATA(me, ldata);
+ const char *name = CustomData_get_active_layer_name(ldata, CD_PROP_FLOAT2);
+ if (!BKE_id_attribute_remove(&me->id, name, op->reports)) {
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index 147c26e521f..3294f9bbb23 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -1053,9 +1053,9 @@ static float *editmesh_get_mirror_uv(
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- if ((fabsf(luv->uv[0] - vec[0]) < 0.001f) && (fabsf(luv->uv[1] - vec[1]) < 0.001f)) {
- return luv->uv;
+ float *luv2 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ if ((fabsf(luv[0] - vec[0]) < 0.001f) && (fabsf(luv[1] - vec[1]) < 0.001f)) {
+ return luv;
}
}
}
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index 6075e4250eb..d8ebc183991 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -2096,7 +2096,7 @@ static int object_curves_empty_hair_add_exec(bContext *C, wmOperator *op)
/* Decide which UV map to use for attachment. */
Mesh *surface_mesh = static_cast<Mesh *>(surface_ob->data);
- const char *uv_name = CustomData_get_active_layer_name(&surface_mesh->ldata, CD_MLOOPUV);
+ const char *uv_name = CustomData_get_active_layer_name(&surface_mesh->ldata, CD_PROP_FLOAT2);
if (uv_name != nullptr) {
curves_id->surface_uv_map = BLI_strdup(uv_name);
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index e69ccf5a50d..e05ca63059f 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -460,7 +460,7 @@ static bool bake_object_check(const Scene *scene,
}
}
else if (target == R_BAKE_TARGET_IMAGE_TEXTURES) {
- if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) {
+ if (CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2) == -1) {
BKE_reportf(
reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2);
return false;
@@ -1378,7 +1378,7 @@ static int bake(const BakeAPIRender *bkr,
if (bkr->uv_layer[0] != '\0') {
Mesh *me = (Mesh *)ob_low->data;
- if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, bkr->uv_layer) == -1) {
+ if (CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, bkr->uv_layer) == -1) {
BKE_reportf(reports,
RPT_ERROR,
"No UV layer named \"%s\" found in the object \"%s\"",
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 78b059d5514..5f1af79c446 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -176,16 +176,16 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
- cddata_masks.lmask |= CD_MASK_MLOOPUV;
+ cddata_masks.lmask |= CD_MASK_PROP_FLOAT2;
Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
- int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
+ int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_PROP_FLOAT2);
RNA_enum_item_add_separator(&item, &totitem);
for (int i = 0; i < num_data; i++) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
- &me_eval->ldata, CD_MLOOPUV, i);
+ &me_eval->ldata, CD_PROP_FLOAT2, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index c85044bf915..7cb117ab6bc 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -421,16 +421,16 @@ typedef struct ProjPaintState {
const MLoop *mloop_eval;
const MLoopTri *mlooptri_eval;
- const MLoopUV *mloopuv_stencil_eval;
+ const float (*mloopuv_stencil_eval)[2];
/**
* \note These UV layers are aligned to \a mpoly_eval
* but each pointer references the start of the layer,
* so a loop indirection is needed as well.
*/
- const MLoopUV **poly_to_loop_uv;
+ const float (**poly_to_loop_uv)[2];
/** other UV map, use for cloning between layers. */
- const MLoopUV **poly_to_loop_uv_clone;
+ const float (**poly_to_loop_uv_clone)[2];
/* Actual material for each index, either from object or Mesh datablock... */
Material **mat_array;
@@ -517,14 +517,13 @@ BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_
ps->mloop_eval[lt->tri[0]].v, ps->mloop_eval[lt->tri[1]].v, ps->mloop_eval[lt->tri[2]].v,
#define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \
- uvlayer[lt->poly][lt->tri[0]].uv, uvlayer[lt->poly][lt->tri[1]].uv, \
- uvlayer[lt->poly][lt->tri[2]].uv,
+ uvlayer[lt->poly][lt->tri[0]], uvlayer[lt->poly][lt->tri[1]], uvlayer[lt->poly][lt->tri[2]],
#define PS_LOOPTRI_ASSIGN_UV_3(uv_tri, uvlayer, lt) \
{ \
- (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]].uv; \
- (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]].uv; \
- (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]].uv; \
+ (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]]; \
+ (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]]; \
+ (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]]; \
} \
((void)0)
@@ -1661,9 +1660,9 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps,
if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index];
- const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]].uv,
- ps->mloopuv_stencil_eval[lt_other->tri[1]].uv,
- ps->mloopuv_stencil_eval[lt_other->tri[2]].uv};
+ const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]],
+ ps->mloopuv_stencil_eval[lt_other->tri[1]],
+ ps->mloopuv_stencil_eval[lt_other->tri[2]]};
/* #BKE_image_acquire_ibuf - TODO: this may be slow. */
uchar rgba_ub[4];
@@ -4032,7 +4031,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask;
cddata_masks.fmask |= CD_MASK_MTFACE;
- cddata_masks.lmask |= CD_MASK_MLOOPUV;
+ cddata_masks.lmask |= CD_MASK_PROP_FLOAT2;
if (ps->do_face_sel) {
cddata_masks.vmask |= CD_MASK_ORIGINDEX;
cddata_masks.emask |= CD_MASK_ORIGINDEX;
@@ -4040,7 +4039,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
}
ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks);
- if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)) {
ps->me_eval = NULL;
return false;
}
@@ -4077,35 +4076,36 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval);
ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval);
- ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces");
+ ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces");
return true;
}
typedef struct {
- const MLoopUV *mloopuv_clone_base;
+ const float (*mloopuv_clone_base)[2];
const TexPaintSlot *slot_last_clone;
const TexPaintSlot *slot_clone;
} ProjPaintLayerClone;
static void proj_paint_layer_clone_init(ProjPaintState *ps, ProjPaintLayerClone *layer_clone)
{
- const MLoopUV *mloopuv_clone_base = NULL;
+ const float(*mloopuv_clone_base)[2] = NULL;
/* use clone mtface? */
if (ps->do_layer_clone) {
- const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
+ const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata,
+ CD_PROP_FLOAT2);
- ps->poly_to_loop_uv_clone = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *),
+ ps->poly_to_loop_uv_clone = MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]),
"proj_paint_mtfaces");
if (layer_num != -1) {
- mloopuv_clone_base = CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num);
+ mloopuv_clone_base = CustomData_get_layer_n(&ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num);
}
if (mloopuv_clone_base == NULL) {
/* get active instead */
- mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV);
+ mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
}
}
@@ -4135,8 +4135,8 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps,
if (lc->slot_clone != lc->slot_last_clone) {
if (!lc->slot_clone->uvname ||
!(lc->mloopuv_clone_base = CustomData_get_layer_named(
- &ps->me_eval->ldata, CD_MLOOPUV, lc->slot_clone->uvname))) {
- lc->mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV);
+ &ps->me_eval->ldata, CD_PROP_FLOAT2, lc->slot_clone->uvname))) {
+ lc->mloopuv_clone_base = CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
}
lc->slot_last_clone = lc->slot_clone;
}
@@ -4275,7 +4275,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
MemArena *arena,
const ProjPaintFaceLookup *face_lookup,
ProjPaintLayerClone *layer_clone,
- const MLoopUV *mloopuv_base,
+ const float (*mloopuv_base)[2],
const bool is_multi_view)
{
/* Image Vars - keep track of images we have used */
@@ -4301,14 +4301,14 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
slot = project_paint_face_paint_slot(ps, tri_index);
/* all faces should have a valid slot, reassert here */
if (slot == NULL) {
- mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV);
+ mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
tpage = ps->canvas_ima;
}
else {
if (slot != slot_last) {
if (!slot->uvname || !(mloopuv_base = CustomData_get_layer_named(
- &ps->me_eval->ldata, CD_MLOOPUV, slot->uvname))) {
- mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV);
+ &ps->me_eval->ldata, CD_PROP_FLOAT2, slot->uvname))) {
+ mloopuv_base = CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
}
slot_last = slot;
}
@@ -4333,7 +4333,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps,
ps->poly_to_loop_uv[lt->poly] = mloopuv_base;
- tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]].uv);
+ tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]]);
#ifndef PROJ_DEBUG_NOSEAMBLEED
project_paint_bleed_add_face_user(ps, arena, lt, tri_index);
@@ -4450,7 +4450,7 @@ static void project_paint_begin(const bContext *C,
{
ProjPaintLayerClone layer_clone;
ProjPaintFaceLookup face_lookup;
- const MLoopUV *mloopuv_base = NULL;
+ const float(*mloopuv_base)[2] = NULL;
/* At the moment this is just ps->arena_mt[0], but use this to show were not multi-threading. */
MemArena *arena;
@@ -4480,16 +4480,16 @@ static void project_paint_begin(const bContext *C,
proj_paint_layer_clone_init(ps, &layer_clone);
if (ps->do_layer_stencil || ps->do_stencil_brush) {
- // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_MLOOPUV);
- int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV);
+ // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
+ int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_PROP_FLOAT2);
if (layer_num != -1) {
ps->mloopuv_stencil_eval = CustomData_get_layer_n(
- &ps->me_eval->ldata, CD_MLOOPUV, layer_num);
+ &ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num);
}
if (ps->mloopuv_stencil_eval == NULL) {
/* get active instead */
- ps->mloopuv_stencil_eval = CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV);
+ ps->mloopuv_stencil_eval = CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2);
}
if (ps->do_stencil_brush) {
@@ -6378,7 +6378,7 @@ bool ED_paint_proj_mesh_data_check(
}
me = BKE_mesh_from_object(ob);
- layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (layernum == 0) {
hasuvs = false;
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f87ca073c82..8b0e96303f0 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -312,8 +312,8 @@ static void imapaint_pick_uv(
findex = index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly;
if (findex == faceindex) {
- const MLoopUV *mloopuv;
- const MLoopUV *tri_uv[3];
+ const float(*mloopuv)[2];
+ const float *tri_uv[3];
float tri_co[3][3];
for (int j = 3; j--;) {
@@ -329,17 +329,18 @@ static void imapaint_pick_uv(
slot = &ma->texpaintslot[ma->paint_active_slot];
if (!(slot && slot->uvname &&
- (mloopuv = CustomData_get_layer_named(&me_eval->ldata, CD_MLOOPUV, slot->uvname)))) {
- mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV);
+ (mloopuv = CustomData_get_layer_named(
+ &me_eval->ldata, CD_PROP_FLOAT2, slot->uvname)))) {
+ mloopuv = CustomData_get_layer(&me_eval->ldata, CD_PROP_FLOAT2);
}
}
else {
- mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV);
+ mloopuv = CustomData_get_layer(&me_eval->ldata, CD_PROP_FLOAT2);
}
- tri_uv[0] = &mloopuv[lt->tri[0]];
- tri_uv[1] = &mloopuv[lt->tri[1]];
- tri_uv[2] = &mloopuv[lt->tri[2]];
+ tri_uv[0] = mloopuv[lt->tri[0]];
+ tri_uv[1] = mloopuv[lt->tri[1]];
+ tri_uv[2] = mloopuv[lt->tri[2]];
p[0] = xy[0];
p[1] = xy[1];
@@ -347,8 +348,8 @@ static void imapaint_pick_uv(
imapaint_tri_weights(matrix, view, UNPACK3(tri_co), p, w);
absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]);
if (absw < minabsw) {
- uv[0] = tri_uv[0]->uv[0] * w[0] + tri_uv[1]->uv[0] * w[1] + tri_uv[2]->uv[0] * w[2];
- uv[1] = tri_uv[0]->uv[1] * w[0] + tri_uv[1]->uv[1] * w[1] + tri_uv[2]->uv[1] * w[2];
+ uv[0] = tri_uv[0][0] * w[0] + tri_uv[1][0] * w[1] + tri_uv[2][0] * w[2];
+ uv[1] = tri_uv[0][1] * w[0] + tri_uv[1][1] * w[1] + tri_uv[2][1] * w[2];
minabsw = absw;
}
}
@@ -423,7 +424,7 @@ void paint_sample_color(
uint faceindex;
uint totpoly = me->totpoly;
- if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) {
+ if (CustomData_has_layer(&me_eval->ldata, CD_PROP_FLOAT2)) {
ED_view3d_viewcontext_init(C, &vc, depsgraph);
view3d_operator_needs_opengl(C);
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 4739fa52674..81c499c923a 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -219,7 +219,7 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em,
apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv);
for (element = sculptdata->uv[i].element; element; element = element->next) {
- MLoopUV *luv;
+ float(*luv)[2];
BMLoop *l;
if (element->separate && element != sculptdata->uv[i].element) {
@@ -227,8 +227,8 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em,
}
l = element->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
+ luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(*luv, sculptdata->uv[i].uv);
}
}
}
@@ -302,7 +302,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em,
apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv);
for (element = sculptdata->uv[i].element; element; element = element->next) {
- MLoopUV *luv;
+ float(*luv)[2];
BMLoop *l;
if (element->separate && element != sculptdata->uv[i].element) {
@@ -310,8 +310,8 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em,
}
l = element->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
+ luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(*luv, sculptdata->uv[i].uv);
}
}
}
@@ -323,12 +323,12 @@ static void add_weighted_edge(float (*delta_buf)[3],
const UvElement *storage,
const UvElement *ele_next,
const UvElement *ele_prev,
- const MLoopUV *luv_next,
- const MLoopUV *luv_prev,
+ const float luv_next[2],
+ const float luv_prev[2],
const float weight)
{
float delta[2];
- sub_v2_v2v2(delta, luv_next->uv, luv_prev->uv);
+ sub_v2_v2v2(delta, luv_next, luv_prev);
bool code1 = (ele_prev->flag & MARK_BOUNDARY);
bool code2 = (ele_next->flag & MARK_BOUNDARY);
@@ -380,7 +380,7 @@ static void relaxation_iteration_uv(BMEditMesh *em,
struct UvElement **head_table = BM_uv_element_map_ensure_head_table(sculptdata->elementMap);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BLI_assert(cd_loop_uv_offset >= 0);
const int total_uvs = sculptdata->elementMap->total_uvs;
@@ -397,9 +397,9 @@ static void relaxation_iteration_uv(BMEditMesh *em,
const float *v_prev_co = ele_prev->l->v->co;
const float *v_next_co = ele_next->l->v->co;
- const MLoopUV *luv_curr = BM_ELEM_CD_GET_VOID_P(ele_curr->l, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(ele_next->l, cd_loop_uv_offset);
- const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(ele_prev->l, cd_loop_uv_offset);
+ const float(*luv_curr)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_curr->l, cd_loop_uv_offset);
+ const float(*luv_next)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_next->l, cd_loop_uv_offset);
+ const float(*luv_prev)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_prev->l, cd_loop_uv_offset);
const UvElement *head_curr = head_table[ele_curr - sculptdata->elementMap->storage];
const UvElement *head_next = head_table[ele_next - sculptdata->elementMap->storage];
@@ -407,11 +407,11 @@ static void relaxation_iteration_uv(BMEditMesh *em,
/* If the mesh is triangulated with no boundaries, only one edge is required. */
const float weight_curr = tri_weight_v3(method, v_curr_co, v_prev_co, v_next_co);
- add_weighted_edge(delta_buf, storage, head_next, head_prev, luv_next, luv_prev, weight_curr);
+ add_weighted_edge(delta_buf, storage, head_next, head_prev, *luv_next, *luv_prev, weight_curr);
/* Triangulated with a boundary? We need the incoming edges to solve the boundary. */
const float weight_prev = tri_weight_v3(method, v_prev_co, v_curr_co, v_next_co);
- add_weighted_edge(delta_buf, storage, head_next, head_curr, luv_next, luv_curr, weight_prev);
+ add_weighted_edge(delta_buf, storage, head_next, head_curr, *luv_next, *luv_curr, weight_prev);
if (method == UV_SCULPT_TOOL_RELAX_LAPLACIAN) {
/* Laplacian method has zero weights on virtual edges. */
@@ -420,7 +420,7 @@ static void relaxation_iteration_uv(BMEditMesh *em,
/* Meshes with quads (or other n-gons) need "virtual" edges too. */
const float weight_next = tri_weight_v3(method, v_next_co, v_curr_co, v_prev_co);
- add_weighted_edge(delta_buf, storage, head_prev, head_curr, luv_prev, luv_curr, weight_next);
+ add_weighted_edge(delta_buf, storage, head_prev, head_curr, *luv_prev, *luv_curr, weight_next);
}
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
@@ -444,18 +444,18 @@ static void relaxation_iteration_uv(BMEditMesh *em,
const float *delta_sum = delta_buf[adj_el->element - storage];
{
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(adj_el->element->l, cd_loop_uv_offset);
- BLI_assert(adj_el->uv == luv->uv); /* Only true for head. */
- adj_el->uv[0] = luv->uv[0] + strength * safe_divide(delta_sum[0], delta_sum[2]);
- adj_el->uv[1] = luv->uv[1] + strength * safe_divide(delta_sum[1], delta_sum[2]);
+ const float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(adj_el->element->l, cd_loop_uv_offset);
+ BLI_assert(adj_el->uv == (float *)luv); /* Only true for head. */
+ adj_el->uv[0] = (*luv)[0] + strength * safe_divide(delta_sum[0], delta_sum[2]);
+ adj_el->uv[1] = (*luv)[1] + strength * safe_divide(delta_sum[1], delta_sum[2]);
apply_sculpt_data_constraints(sculptdata, adj_el->uv);
}
/* Copy UV co-ordinates to all UvElements. */
UvElement *tail = adj_el->element;
while (tail) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(tail->l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, adj_el->uv);
+ float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(tail->l, cd_loop_uv_offset);
+ copy_v2_v2(*luv, adj_el->uv);
tail = tail->next;
if (tail && tail->separate) {
break;
@@ -527,7 +527,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv);
for (element = sculptdata->uv[i].element; element; element = element->next) {
- MLoopUV *luv;
+ float(*luv)[2];
BMLoop *l;
if (element->separate && element != sculptdata->uv[i].element) {
@@ -535,8 +535,8 @@ static void uv_sculpt_stroke_apply(bContext *C,
}
l = element->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(luv->uv, sculptdata->uv[i].uv);
+ luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(*luv, sculptdata->uv[i].uv);
}
}
}
@@ -570,7 +570,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
apply_sculpt_data_constraints(sculptdata, sculptdata->uv[uvindex].uv);
for (element = sculptdata->uv[uvindex].element; element; element = element->next) {
- MLoopUV *luv;
+ float(*luv)[2];
BMLoop *l;
if (element->separate && element != sculptdata->uv[uvindex].element) {
@@ -578,8 +578,8 @@ static void uv_sculpt_stroke_apply(bContext *C,
}
l = element->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(luv->uv, sculptdata->uv[uvindex].uv);
+ luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(*luv, sculptdata->uv[uvindex].uv);
}
}
if (sima->flag & SI_LIVE_UNWRAP) {
@@ -666,7 +666,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
ARegion *region = CTX_wm_region(C);
float co[2];
BMFace *efa;
- MLoopUV *luv;
+ float(*luv)[2];
BMLoop *l;
BMIter iter, liter;
@@ -736,6 +736,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
data->totalUniqueUvs = unique_uvs;
/* Index for the UvElements. */
int counter = -1;
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* initialize the unique UVs */
for (int i = 0; i < bm->totvert; i++) {
UvElement *element = data->elementMap->vertex[i];
@@ -749,14 +751,13 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
continue;
}
- l = element->l;
- luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = BM_ELEM_CD_GET_FLOAT2_P(element->l, offsets.uv);
counter++;
data->uv[counter].element = element;
- data->uv[counter].uv = luv->uv;
+ data->uv[counter].uv = *luv;
if (data->tool != UV_SCULPT_TOOL_GRAB) {
- if (luv->flag & MLOOPUV_PINNED) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(element->l, offsets.pin)) {
data->uv[counter].is_locked = true;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc
index 6400a015ef1..61f66150ce4 100644
--- a/source/blender/editors/space_view3d/view3d_draw.cc
+++ b/source/blender/editors/space_view3d/view3d_draw.cc
@@ -2413,12 +2413,12 @@ void ED_view3d_datamask(const bContext *C,
CustomData_MeshMasks *r_cddata_masks)
{
if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) {
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR;
+ r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR;
r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR;
}
else if (v3d->shading.type == OB_SOLID) {
if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) {
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
+ r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2;
}
if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) {
r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR;
diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c
index 4f15fc240d3..96bcbaa412a 100644
--- a/source/blender/editors/transform/transform_convert_mesh_uv.c
+++ b/source/blender/editors/transform/transform_convert_mesh_uv.c
@@ -90,7 +90,8 @@ static void uv_set_connectivity_distance(const ToolSettings *ts,
BLI_LINKSTACK_INIT(queue);
BLI_LINKSTACK_INIT(queue_next);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
BMIter fiter, liter;
BMVert *f;
BMLoop *l;
@@ -105,7 +106,7 @@ static void uv_set_connectivity_distance(const ToolSettings *ts,
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
float dist;
- bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, cd_loop_uv_offset);
+ bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, offsets);
if (uv_vert_sel) {
BLI_LINKSTACK_PUSH(queue, l);
@@ -136,10 +137,10 @@ static void uv_set_connectivity_distance(const ToolSettings *ts,
BMLoop *l_other, *l_connected;
BMIter l_connected_iter;
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
float l_uv[2];
- copy_v2_v2(l_uv, luv->uv);
+ copy_v2_v2(l_uv, luv);
mul_v2_v2(l_uv, aspect);
BM_ITER_ELEM (l_other, &liter, l->f, BM_LOOPS_OF_FACE) {
@@ -147,9 +148,9 @@ static void uv_set_connectivity_distance(const ToolSettings *ts,
continue;
}
float other_uv[2], edge_vec[2];
- MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset);
+ float *luv_other = BM_ELEM_CD_GET_FLOAT_P(l_other, offsets.uv);
- copy_v2_v2(other_uv, luv_other->uv);
+ copy_v2_v2(other_uv, luv_other);
mul_v2_v2(other_uv, aspect);
sub_v2_v2v2(edge_vec, l_uv, other_uv);
@@ -179,14 +180,14 @@ static void uv_set_connectivity_distance(const ToolSettings *ts,
continue;
}
- MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset);
+ float *luv_connected = BM_ELEM_CD_GET_FLOAT_P(l_connected, offsets.uv);
connected_vert_sel = BM_elem_flag_test_bool(l_connected, TMP_LOOP_SELECT_TAG);
/* Check if this loop is connected in UV space.
* If the uv loops share the same selection state (if not, they are not connected as
* they have been ripped or other edit commands have separated them). */
bool connected = other_vert_sel == connected_vert_sel &&
- equals_v2v2(luv_other->uv, luv_connected->uv);
+ equals_v2v2(luv_other, luv_connected);
if (!connected) {
continue;
}
@@ -261,7 +262,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
int co_num;
} *island_center = NULL;
int count = 0, countsel = 0;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
continue;
@@ -291,15 +292,15 @@ static void createTransUVs(bContext *C, TransInfo *t)
/* Make sure that the loop element flag is cleared for when we use it in
* uv_set_connectivity_distance later. */
BM_elem_flag_disable(l, BM_ELEM_TAG);
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
countsel++;
if (island_center) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
if (element->flag == false) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(island_center[element->island].co, luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ add_v2_v2(island_center[element->island].co, luv);
island_center[element->island].co_num++;
element->flag = true;
}
@@ -353,8 +354,8 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
- MLoopUV *luv;
+ const bool selected = uvedit_uv_select_test(scene, l, offsets);
+ float(*luv)[2];
const float *center = NULL;
float prop_distance = FLT_MAX;
@@ -374,8 +375,8 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
}
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, prop_distance, selected);
+ luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv);
+ UVsToTransData(t->aspect, td++, td2d++, *luv, center, prop_distance, selected);
}
}
diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c
index 10368f7d43f..baa6f7dbd45 100644
--- a/source/blender/editors/uvedit/uvedit_buttons.c
+++ b/source/blender/editors/uvedit/uvedit_buttons.c
@@ -47,7 +47,7 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float
BMFace *f;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
int tot = 0;
zero_v2(center);
@@ -55,7 +55,7 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, f)) {
@@ -63,9 +63,9 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(center, luv->uv);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ add_v2_v2(center, luv);
tot++;
}
}
@@ -88,13 +88,13 @@ static void uvedit_translate(Scene *scene,
BMFace *f;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, f)) {
@@ -102,9 +102,9 @@ static void uvedit_translate(Scene *scene,
}
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(luv->uv, delta);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ add_v2_v2(luv, delta);
}
}
}
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 434bfbc64f9..e4ec558a511 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -117,13 +117,13 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
bool uvedit_vert_is_edge_select_any_other(const struct Scene *scene,
struct BMLoop *l,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
bool uvedit_vert_is_face_select_any_other(const struct Scene *scene,
struct BMLoop *l,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
bool uvedit_vert_is_all_other_faces_selected(const struct Scene *scene,
struct BMLoop *l,
- const int cd_loop_uv_offset);
+ BMUVOffsets offsets);
/* utility tool functions */
@@ -163,7 +163,7 @@ bool uvedit_select_is_any_selected_multi(const struct Scene *scene,
*/
const float *uvedit_first_selected_uv_from_vertex(struct Scene *scene,
struct BMVert *eve,
- int cd_loop_uv_offset);
+ BMUVOffsets offsets);
void UV_OT_select_all(struct wmOperatorType *ot);
void UV_OT_select(struct wmOperatorType *ot);
diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc
index d8e10435146..c45fb8a2cbd 100644
--- a/source/blender/editors/uvedit/uvedit_islands.cc
+++ b/source/blender/editors/uvedit/uvedit_islands.cc
@@ -65,15 +65,15 @@ static void island_uv_transform(FaceIsland *island,
* To convert post-transform to pre-transform, use `A * x + b == A * (x + c), c = A^-1 * b`
*/
- const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ const int cd_loop_uv_offset = island->offsets.uv;
const int faces_len = island->faces_len;
for (int i = 0; i < faces_len; i++) {
BMFace *f = island->faces[i];
BMLoop *l;
BMIter iter;
BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- mul_v2_m2_add_v2v2(luv->uv, matrix, luv->uv, pre_translate);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ mul_v2_m2_add_v2v2(luv, matrix, luv, pre_translate);
}
}
}
@@ -134,9 +134,8 @@ static float (*bm_face_array_calc_unique_uv_coords(
}
BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
- const MLoopUV *luv = static_cast<const MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset));
- copy_v2_v2(coords[coords_len++], luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ copy_v2_v2(coords[coords_len++], luv);
/* Un tag all connected so we don't add them twice.
* Note that we will tag other loops not part of `faces` but this is harmless,
@@ -150,9 +149,8 @@ static float (*bm_face_array_calc_unique_uv_coords(
do {
if (l_radial->v == l_iter->v) {
if (BM_elem_flag_test(l_radial, BM_ELEM_TAG)) {
- const MLoopUV *luv_radial = static_cast<const MLoopUV *>(
- BM_ELEM_CD_GET_VOID_P(l_radial, cd_loop_uv_offset));
- if (equals_v2v2(luv->uv, luv_radial->uv)) {
+ const float *luv_radial = BM_ELEM_CD_GET_FLOAT_P(l_radial, cd_loop_uv_offset);
+ if (equals_v2v2(luv, luv_radial)) {
/* Don't add this UV when met in another face in `faces`. */
BM_elem_flag_disable(l_iter, BM_ELEM_TAG);
}
@@ -172,7 +170,7 @@ static void face_island_uv_rotate_fit_aabb(FaceIsland *island)
BMFace **faces = island->faces;
const int faces_len = island->faces_len;
const float aspect_y = island->aspect_y;
- const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ const int cd_loop_uv_offset = island->offsets.uv;
/* Calculate unique coordinates since calculating a convex hull can be an expensive operation. */
int coords_len;
@@ -320,7 +318,7 @@ static float uv_nearest_grid_tile_distance(const int udim_grid[2],
* \{ */
struct SharedUVLoopData {
- int cd_loop_uv_offset;
+ BMUVOffsets offsets;
bool use_seams;
};
@@ -334,7 +332,7 @@ static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, v
}
}
- return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->cd_loop_uv_offset);
+ return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->offsets.uv);
}
/**
@@ -347,9 +345,9 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
const bool only_selected_uvs,
const bool use_seams,
const float aspect_y,
- const int cd_loop_uv_offset)
+ const BMUVOffsets uv_offsets)
{
- BLI_assert(cd_loop_uv_offset >= 0);
+ BLI_assert(uv_offsets.uv >= 0);
int island_added = 0;
BM_mesh_elem_table_ensure(bm, BM_FACE);
@@ -367,7 +365,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
bool value = false;
if (BM_elem_flag_test(f, BM_ELEM_SELECT) &&
- uvedit_face_select_test(scene, f, cd_loop_uv_offset)) {
+ uvedit_face_select_test(scene, f, uv_offsets)) {
value = true;
}
BM_elem_flag_set(f, BM_ELEM_TAG, value);
@@ -380,7 +378,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
}
struct SharedUVLoopData user_data = {0};
- user_data.cd_loop_uv_offset = cd_loop_uv_offset;
+ user_data.offsets = uv_offsets;
user_data.use_seams = use_seams;
const int group_len = BM_mesh_calc_face_groups(bm,
@@ -408,7 +406,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene,
MEM_callocN(sizeof(*island), __func__));
island->faces = faces;
island->faces_len = faces_len;
- island->cd_loop_uv_offset = cd_loop_uv_offset;
+ island->offsets = uv_offsets;
island->aspect_y = aspect_y;
BLI_addtail(island_list, island);
island_added += 1;
@@ -622,11 +620,10 @@ static bool island_has_pins(FaceIsland *island)
{
BMLoop *l;
BMIter iter;
- const int cd_loop_uv_offset = island->cd_loop_uv_offset;
+ const int pin_offset = island->offsets.pin;
for (int i = 0; i < island->faces_len; i++) {
BM_ITER_ELEM (l, &iter, island->faces[i], BM_LOOPS_OF_FACE) {
- MLoopUV *luv = static_cast<MLoopUV *>(BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset));
- if (luv->flag & MLOOPUV_PINNED) {
+ if (BM_ELEM_CD_GET_BOOL(l, pin_offset)) {
return true;
}
}
@@ -661,8 +658,9 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
bm = em->bm;
}
BLI_assert(bm);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- if (cd_loop_uv_offset == -1) {
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+ if (offsets.uv == -1) {
continue;
}
@@ -683,7 +681,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
params->only_selected_uvs,
params->use_seams,
aspect_y,
- cd_loop_uv_offset);
+ offsets);
/* Remove from linked list and append to blender::Vector. */
LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) {
@@ -713,7 +711,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
INIT_MINMAX2(bounds_min, bounds_max);
for (int i = 0; i < island->faces_len; i++) {
BMFace *f = island->faces[i];
- BM_face_uv_minmax(f, bounds_min, bounds_max, island->cd_loop_uv_offset);
+ BM_face_uv_minmax(f, bounds_min, bounds_max, island->offsets.uv);
}
selection_min_co[0] = MIN2(bounds_min[0], selection_min_co[0]);
@@ -727,7 +725,8 @@ void ED_uvedit_pack_islands_multi(const Scene *scene,
}
bm_face_array_calc_bounds(
- island->faces, island->faces_len, island->cd_loop_uv_offset, &island->bounds_rect);
+ island->faces, island->faces_len, island->offsets.uv, &island->bounds_rect);
+
}
/* Center of bounding box containing all selected UVs. */
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 0e77a8ba4ad..392a415c701 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -88,7 +88,7 @@ static int UNUSED_FUNCTION(ED_operator_uvmap_mesh)(bContext *C)
if (ob && ob->type == OB_MESH) {
Mesh *me = ob->data;
- if (CustomData_get_layer(&me->ldata, CD_MLOOPUV) != NULL) {
+ if (CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2) != NULL) {
return 1;
}
}
@@ -204,9 +204,9 @@ bool ED_uvedit_minmax_multi(
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -214,9 +214,9 @@ bool ED_uvedit_minmax_multi(
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- minmax_v2v2_v2(r_min, r_max, luv->uv);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ minmax_v2v2_v2(r_min, r_max, luv);
changed = true;
}
}
@@ -235,14 +235,12 @@ void ED_uvedit_select_all(BMesh *bm)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
-
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
}
}
}
@@ -262,9 +260,9 @@ static bool ED_uvedit_median_multi(const Scene *scene,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -272,9 +270,9 @@ static bool ED_uvedit_median_multi(const Scene *scene,
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- add_v2_v2(co, luv->uv);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ add_v2_v2(co, luv);
sel++;
}
}
@@ -371,7 +369,7 @@ static bool uvedit_uv_align_weld(Scene *scene,
const float cent[2])
{
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BMIter iter;
BMFace *efa;
@@ -383,19 +381,19 @@ static bool uvedit_uv_align_weld(Scene *scene,
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (!uvedit_uv_select_test(scene, l, offsets)) {
continue;
}
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv);
if (ELEM(tool, UV_ALIGN_X, UV_WELD)) {
- if (luv->uv[0] != cent[0]) {
- luv->uv[0] = cent[0];
+ if (luv[0] != cent[0]) {
+ luv[0] = cent[0];
changed = true;
}
}
if (ELEM(tool, UV_ALIGN_Y, UV_WELD)) {
- if (luv->uv[1] != cent[1]) {
- luv->uv[1] = cent[1];
+ if (luv[1] != cent[1]) {
+ luv[1] = cent[1];
changed = true;
}
}
@@ -404,17 +402,17 @@ static bool uvedit_uv_align_weld(Scene *scene,
return changed;
}
-/** Bitwise-or together, then choose #MLoopUV with highest value. */
+/** Bitwise-or together, then choose loop with highest value. */
typedef enum eUVEndPointPrecedence {
UVEP_INVALID = 0,
UVEP_SELECTED = (1 << 0),
UVEP_PINNED = (1 << 1), /* i.e. Pinned verts are preferred to selected. */
} eUVEndPointPrecedence;
-static eUVEndPointPrecedence uvedit_line_update_get_precedence(const MLoopUV *luv)
+static eUVEndPointPrecedence uvedit_line_update_get_precedence(const bool pinned)
{
eUVEndPointPrecedence precedence = UVEP_SELECTED;
- if (luv->flag & MLOOPUV_PINNED) {
+ if (pinned) {
precedence |= UVEP_PINNED;
}
return precedence;
@@ -424,16 +422,17 @@ static eUVEndPointPrecedence uvedit_line_update_get_precedence(const MLoopUV *lu
* Helper to find two endpoints (`a` and `b`) which have higher precedence, and are far apart.
* Note that is only a heuristic and won't always find the best two endpoints.
*/
-static bool uvedit_line_update_endpoint(const MLoopUV *luv,
+static bool uvedit_line_update_endpoint(const float *luv,
+ const bool pinned,
float uv_a[2],
eUVEndPointPrecedence *prec_a,
float uv_b[2],
eUVEndPointPrecedence *prec_b)
{
- eUVEndPointPrecedence flags = uvedit_line_update_get_precedence(luv);
+ eUVEndPointPrecedence flags = uvedit_line_update_get_precedence(pinned);
- float len_sq_a = len_squared_v2v2(uv_a, luv->uv);
- float len_sq_b = len_squared_v2v2(uv_b, luv->uv);
+ float len_sq_a = len_squared_v2v2(uv_a, luv);
+ float len_sq_b = len_squared_v2v2(uv_b, luv);
/* Caching the value of `len_sq_ab` is unlikely to be faster than recalculating.
* Profile before optimizing. */
@@ -441,13 +440,13 @@ static bool uvedit_line_update_endpoint(const MLoopUV *luv,
if ((*prec_a < flags && 0.0f < len_sq_b) || (*prec_a == flags && len_sq_ab < len_sq_b)) {
*prec_a = flags;
- copy_v2_v2(uv_a, luv->uv);
+ copy_v2_v2(uv_a, luv);
return true;
}
if ((*prec_b < flags && 0.0f < len_sq_a) || (*prec_b == flags && len_sq_ab < len_sq_a)) {
*prec_b = flags;
- copy_v2_v2(uv_b, luv->uv);
+ copy_v2_v2(uv_b, luv);
return true;
}
@@ -460,7 +459,7 @@ static bool uvedit_line_update_endpoint(const MLoopUV *luv,
*/
static bool uvedit_uv_straighten_elements(const UvElement *element,
const int len,
- const int cd_loop_uv_offset,
+ const BMUVOffsets offsets,
const eUVWeldAlign tool)
{
float uv_start[2];
@@ -472,8 +471,9 @@ static bool uvedit_uv_straighten_elements(const UvElement *element,
for (int i = 0; i < 10; i++) { /* Heuristic to prevent infinite loop. */
bool update = false;
for (int j = 0; j < len; j++) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(element[j].l, cd_loop_uv_offset);
- update |= uvedit_line_update_endpoint(luv, uv_start, &prec_start, uv_end, &prec_end);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(element[j].l, offsets.uv);
+ bool pinned = BM_ELEM_CD_GET_BOOL(element[j].l, offsets.pin);
+ update |= uvedit_line_update_endpoint(luv, pinned, uv_start, &prec_start, uv_end, &prec_end);
}
if (!update) {
break;
@@ -508,19 +508,19 @@ static bool uvedit_uv_straighten_elements(const UvElement *element,
bool changed = false;
for (int j = 0; j < len; j++) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(element[j].l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(element[j].l, offsets.uv);
/* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis:
* new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
* Maybe this should be a BLI func? Or is it already existing?
* Could use interp_v2_v2v2, but not sure it's worth it here. */
if (tool_local == UV_STRAIGHTEN_X) {
- luv->uv[0] = a * (luv->uv[1] - uv_start[1]) + uv_start[0];
+ luv[0] = a * (luv[1] - uv_start[1]) + uv_start[0];
}
else if (tool_local == UV_STRAIGHTEN_Y) {
- luv->uv[1] = a * (luv->uv[0] - uv_start[0]) + uv_start[1];
+ luv[1] = a * (luv[0] - uv_start[0]) + uv_start[1];
}
else {
- closest_to_line_segment_v2(luv->uv, luv->uv, uv_start, uv_end);
+ closest_to_line_segment_v2(luv, luv, uv_start, uv_end);
}
changed = true; /* TODO: Did the UV actually move? */
}
@@ -532,8 +532,8 @@ static bool uvedit_uv_straighten_elements(const UvElement *element,
*/
static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
{
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- if (cd_loop_uv_offset == -1) {
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+ if (offsets.uv == -1) {
return false;
}
@@ -546,7 +546,7 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool)
for (int i = 0; i < element_map->total_islands; i++) {
changed |= uvedit_uv_straighten_elements(element_map->storage + element_map->island_indices[i],
element_map->island_total_uvs[i],
- cd_loop_uv_offset,
+ offsets,
tool);
}
@@ -578,7 +578,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BMIter iter, liter;
BMFace *efa;
@@ -590,9 +590,9 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- minmax_v2v2_v2(min, max, luv->uv);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ minmax_v2v2_v2(min, max, luv);
}
}
}
@@ -701,8 +701,8 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
bool *changed = MEM_callocN(sizeof(bool) * objects_len, "uv_remove_doubles_selected.changed");
- /* Maximum index of an objects[i]'s MLoopUVs in MLoopUV_arr.
- * It helps find which MLoopUV in *MLoopUV_arr belongs to which object. */
+ /* Maximum index of an objects[i]'s UVs in UV_arr.
+ * It helps find which UV in *mloopuv_arr belongs to which object. */
uint *ob_mloopuv_max_idx = MEM_callocN(sizeof(uint) * objects_len,
"uv_remove_doubles_selected.ob_mloopuv_max_idx");
@@ -724,7 +724,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
int *duplicates = NULL;
BLI_array_declare(duplicates);
- MLoopUV **mloopuv_arr = NULL;
+ float **mloopuv_arr = NULL;
BLI_array_declare(mloopuv_arr);
int mloopuv_count = 0; /* Also used for *duplicates count. */
@@ -740,7 +740,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -748,9 +748,9 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- BLI_kdtree_2d_insert(tree, mloopuv_count, luv->uv);
+ 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_array_append(duplicates, -1);
BLI_array_append(mloopuv_arr, luv);
mloopuv_count++;
@@ -777,7 +777,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
if (duplicates[i] != i) {
/* If not self then accumulate uv for averaging.
* Self uv is already present in accumulator */
- add_v2_v2(mloopuv_arr[duplicates[i]]->uv, mloopuv_arr[i]->uv);
+ add_v2_v2(mloopuv_arr[duplicates[i]], mloopuv_arr[i]);
}
uv_duplicate_count[duplicates[i]]++;
}
@@ -787,14 +787,14 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
continue;
}
- mul_v2_fl(mloopuv_arr[i]->uv, 1.0f / (float)uv_duplicate_count[i]);
+ mul_v2_fl(mloopuv_arr[i], 1.0f / (float)uv_duplicate_count[i]);
}
MEM_freeN(uv_duplicate_count);
/* Update duplicated uvs. */
uint ob_index = 0;
for (int i = 0; i < mloopuv_count; i++) {
- /* Make sure we know which object owns the MLoopUV at this index.
+ /* Make sure we know which object owns the mloopuv at this index.
* Remember that in some cases the object will have no loop uv,
* thus we need the while loop, and not simply an if check. */
while (ob_mloopuv_max_idx[ob_index] < i) {
@@ -805,7 +805,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op)
continue;
}
- copy_v2_v2(mloopuv_arr[i]->uv, mloopuv_arr[duplicates[i]]->uv);
+ copy_v2_v2(mloopuv_arr[i], mloopuv_arr[duplicates[i]]);
changed[ob_index] = true;
}
@@ -853,7 +853,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen);
- MLoopUV **mloopuv_arr = NULL;
+ float **mloopuv_arr = NULL;
BLI_array_declare(mloopuv_arr);
int mloopuv_count = 0;
@@ -870,7 +870,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -878,9 +878,9 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- BLI_kdtree_2d_insert(tree, mloopuv_count, luv->uv);
+ 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_array_append(mloopuv_arr, luv);
mloopuv_count++;
}
@@ -903,7 +903,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -911,13 +911,13 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
KDTreeNearest_2d nearest;
- const int i = BLI_kdtree_2d_find_nearest(tree, luv->uv, &nearest);
+ const int i = BLI_kdtree_2d_find_nearest(tree, luv, &nearest);
if (i != -1 && nearest.dist < threshold) {
- copy_v2_v2(luv->uv, mloopuv_arr[i]->uv);
+ copy_v2_v2(luv, mloopuv_arr[i]);
changed = true;
}
}
@@ -1105,10 +1105,10 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Object *obedit, const float curs
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -1116,9 +1116,9 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Object *obedit, const float curs
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(luv->uv, cursor);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ copy_v2_v2(luv, cursor);
changed = true;
}
}
@@ -1133,10 +1133,10 @@ static bool uv_snap_uvs_offset(Scene *scene, Object *obedit, const float offset[
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -1144,9 +1144,9 @@ static bool uv_snap_uvs_offset(Scene *scene, Object *obedit, const float offset[
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(luv->uv, offset);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ add_v2_v2(luv, offset);
changed = true;
}
}
@@ -1162,9 +1162,9 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
BMFace *f;
BMLoop *l, *lsub;
BMIter iter, liter, lsubiter;
- MLoopUV *luv;
+ float *luv;
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* index every vert that has a selected UV using it, but only once so as to
* get unique indices and to count how much to malloc */
@@ -1172,7 +1172,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
if (uvedit_face_visible_test(scene, f)) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
+ BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, offsets));
}
}
else {
@@ -1191,15 +1191,15 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* Face: visible. */
!BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* Loop: unselected. */
{
- luv = BM_ELEM_CD_GET_VOID_P(lsub, cd_loop_uv_offset);
- add_v2_v2(uv, luv->uv);
+ luv = BM_ELEM_CD_GET_FLOAT_P(lsub, offsets.uv);
+ add_v2_v2(uv, luv);
uv_tot++;
}
}
if (uv_tot) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- mul_v2_v2fl(luv->uv, uv, 1.0f / (float)uv_tot);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ mul_v2_v2fl(luv, uv, 1.0f / (float)uv_tot);
changed = true;
}
}
@@ -1216,12 +1216,12 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
int width = 0, height = 0;
float w, h;
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
ED_space_image_get_size(sima, &width, &height);
w = (float)width;
@@ -1233,9 +1233,9 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- uv_snap_to_pixel(luv->uv, w, h);
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ uv_snap_to_pixel(luv, w, h);
}
}
@@ -1343,7 +1343,6 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
const ToolSettings *ts = scene->toolsettings;
const bool clear = RNA_boolean_get(op->ptr, "clear");
const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0;
@@ -1357,7 +1356,9 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_pin_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (synced_selection && (em->bm->totvertsel == 0)) {
continue;
@@ -1369,16 +1370,10 @@ static int uv_pin_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
changed = true;
- if (clear) {
- luv->flag &= ~MLOOPUV_PINNED;
- }
- else {
- luv->flag |= MLOOPUV_PINNED;
- }
+ BM_ELEM_CD_SET_BOOL(l, offsets.pin, !clear);
}
}
}
@@ -1417,24 +1412,23 @@ static void UV_OT_pin(wmOperatorType *ot)
/** \name Hide Operator
* \{ */
-/* Check if vertex/edge is selected or unselected based on #bool_test arg. Needed for select swap
- * support */
-#define UV_VERT_SEL_TEST(luv, bool_test) \
- ((((luv)->flag & MLOOPUV_VERTSEL) == MLOOPUV_VERTSEL) == bool_test)
+/* check if we are selected or unselected based on 'bool_test' arg,
+ * needed for select swap support */
+#define UV_VERT_SEL_TEST(l, bool_test) \
+ (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) == bool_test)
-#define UV_EDGE_SEL_TEST(luv, bool_test) \
- ((((luv)->flag & MLOOPUV_EDGESEL) == MLOOPUV_EDGESEL) == bool_test)
+#define UV_EDGE_SEL_TEST(l, bool_test) \
+ (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge) == bool_test)
-/* Is the specified UV face, selected or unselected depending on bool_test. */
-static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const int cd_loop_uv_offset)
+/* is every UV vert selected or unselected depending on bool_test */
+static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const BMUVOffsets offsets)
{
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- if (!UV_EDGE_SEL_TEST(luv, select_test)) {
+ if (!UV_EDGE_SEL_TEST(l_iter, select_test)) {
return false;
}
} while ((l_iter = l_iter->next) != l_first);
@@ -1460,9 +1454,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (EDBM_mesh_hide(em, swap)) {
@@ -1484,9 +1480,8 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (UV_VERT_SEL_TEST(luv, !swap) || UV_EDGE_SEL_TEST(luv, !swap)) {
+ if (UV_VERT_SEL_TEST(l, !swap)) {
hide = 1;
break;
}
@@ -1496,27 +1491,26 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
if (use_face_center) {
if (em->selectmode == SCE_SELECT_FACE) {
/* Deselect BMesh face if UV face is (de)selected depending on #swap. */
- if (bm_face_is_all_uv_sel(efa, !swap, cd_loop_uv_offset)) {
+ if (bm_face_is_all_uv_sel(efa, !swap, offsets)) {
BM_face_select_set(em->bm, efa, false);
}
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
}
else {
- if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) {
+ if (bm_face_is_all_uv_sel(efa, true, offsets) == !swap) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
/* For both cases rely on edge sel tests, since all vert sel tests are invalid in
* case of sticky selections. */
- if (UV_EDGE_SEL_TEST(luv, !swap) && (em->selectmode == SCE_SELECT_EDGE)) {
+ if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_EDGE)) {
BM_edge_select_set(em->bm, l->e, false);
}
- else if (UV_EDGE_SEL_TEST(luv, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) {
+ else if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) {
BM_vert_select_set(em->bm, l->v, false);
}
}
}
if (!swap) {
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
}
}
}
@@ -1524,12 +1518,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
/* Deselect BMesh face depending on the type of UV selectmode and the type of UV element
* being considered. */
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (UV_EDGE_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
+ if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
BM_face_select_set(em->bm, efa, false);
break;
}
- if (UV_VERT_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_VERTEX)) {
+ if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_VERTEX)) {
BM_face_select_set(em->bm, efa, false);
break;
}
@@ -1538,12 +1531,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
break;
}
}
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
}
else {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (UV_EDGE_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
+ if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) {
if (em->selectmode == SCE_SELECT_EDGE) {
BM_edge_select_set(em->bm, l->e, false);
}
@@ -1552,7 +1544,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
BM_vert_select_set(em->bm, l->next->v, false);
}
}
- else if (UV_VERT_SEL_TEST(luv, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) {
+ else if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) {
if (em->selectmode == SCE_SELECT_EDGE) {
BM_edge_select_set(em->bm, l->e, false);
}
@@ -1562,7 +1554,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op)
}
}
if (!swap) {
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
}
}
}
@@ -1632,9 +1624,11 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* NOTE: Selecting faces is delayed so that it doesn't select verts/edges and confuse certain
* UV selection checks.
@@ -1664,8 +1658,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL));
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
}
/* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -1688,8 +1682,9 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
if (!totsel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL));
+
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
}
}
/* BM_face_select_set(em->bm, efa, true); */
@@ -1703,8 +1698,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL));
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
}
/* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -1716,8 +1711,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL));
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select);
}
/* BM_face_select_set(em->bm, efa, true); */
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -1853,8 +1848,8 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
bool changed = false;
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -1870,14 +1865,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op)
if (l_iter == l_iter->radial_next) {
continue;
}
- if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ if (!uvedit_edge_select_test(scene, l_iter, offsets)) {
continue;
}
bool mark = false;
BMLoop *l_other = l_iter->radial_next;
do {
- if (!BM_loop_uv_share_edge_check(l_iter, l_other, cd_loop_uv_offset)) {
+ if (!BM_loop_uv_share_edge_check(l_iter, l_other, offsets.uv)) {
mark = true;
break;
}
@@ -1959,12 +1954,12 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (uvedit_face_visible_test(scene, efa)) {
BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) {
+ if (uvedit_edge_select_test(scene, loop, offsets)) {
BM_elem_flag_set(loop->e, BM_ELEM_SEAM, flag_set);
changed = true;
}
diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c
index 78436d17203..248f97392ae 100644
--- a/source/blender/editors/uvedit/uvedit_path.c
+++ b/source/blender/editors/uvedit/uvedit_path.c
@@ -71,7 +71,7 @@ struct PathSelectParams {
struct UserData_UV {
Scene *scene;
BMEditMesh *em;
- int cd_loop_uv_offset;
+ BMUVOffsets offsets;
};
static void path_select_properties(wmOperatorType *ot)
@@ -121,15 +121,15 @@ static bool verttag_test_cb(BMLoop *l, void *user_data_v)
/* All connected loops are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const int cd_loop_uv_offset = user_data->offsets.uv;
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
BMIter iter;
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) {
if (verttag_filter_cb(l_iter, user_data)) {
- const MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- if (equals_v2v2(luv->uv, luv_iter->uv)) {
- if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ if (equals_v2v2(luv, luv_iter)) {
+ if (!uvedit_uv_select_test(scene, l_iter, user_data->offsets)) {
return false;
}
}
@@ -142,15 +142,15 @@ static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v)
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ const uint cd_loop_uv_offset = user_data->offsets.uv;
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
BMIter iter;
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) {
if (verttag_filter_cb(l_iter, user_data)) {
- MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- if (equals_v2v2(luv->uv, luv_iter->uv)) {
- uvedit_uv_select_set(scene, em->bm, l_iter, val, false, cd_loop_uv_offset);
+ const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset);
+ if (equals_v2v2(luv, luv_iter)) {
+ uvedit_uv_select_set(scene, em->bm, l_iter, val, false, user_data->offsets);
}
}
}
@@ -162,7 +162,7 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
BMLoop *l_src,
BMLoop *l_dst,
const float aspect_y,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -171,14 +171,14 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene,
struct UserData_UV user_data = {
.scene = scene,
.em = em,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .offsets = offsets,
};
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .cd_loop_uv_offset = offsets.uv,
};
LinkNode *path = NULL;
@@ -253,13 +253,12 @@ static bool edgetag_test_cb(BMLoop *l, void *user_data_v)
/* All connected loops (UV) are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
BMIter iter;
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &iter, l->e, BM_LOOPS_OF_EDGE) {
if (edgetag_filter_cb(l_iter, user_data)) {
- if (BM_loop_uv_share_edge_check(l, l_iter, cd_loop_uv_offset)) {
- if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_edge_check(l, l_iter, user_data->offsets.uv)) {
+ if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) {
return false;
}
}
@@ -272,8 +271,7 @@ static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v)
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
- uvedit_edge_select_set_with_sticky(scene, em, l, val, false, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, l, val, false, user_data->offsets);
}
static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
@@ -282,7 +280,7 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
BMLoop *l_src,
BMLoop *l_dst,
const float aspect_y,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -291,14 +289,14 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene,
struct UserData_UV user_data = {
.scene = scene,
.em = em,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .offsets = offsets,
};
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .cd_loop_uv_offset = offsets.uv,
};
LinkNode *path = NULL;
@@ -375,11 +373,10 @@ static bool facetag_test_cb(BMFace *f, void *user_data_v)
/* All connected loops are selected or we return false. */
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
BMIter iter;
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &iter, f, BM_LOOPS_OF_FACE) {
- if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) {
return false;
}
}
@@ -390,8 +387,7 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v)
struct UserData_UV *user_data = user_data_v;
const Scene *scene = user_data->scene;
BMEditMesh *em = user_data->em;
- const int cd_loop_uv_offset = user_data->cd_loop_uv_offset;
- uvedit_face_select_set_with_sticky(scene, em, f, val, false, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, f, val, false, user_data->offsets);
}
static int mouse_mesh_uv_shortest_path_face(Scene *scene,
@@ -400,7 +396,7 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene,
BMFace *f_src,
BMFace *f_dst,
const float aspect_y,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
@@ -409,14 +405,14 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene,
struct UserData_UV user_data = {
.scene = scene,
.em = em,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .offsets = offsets,
};
const struct BMCalcPathUVParams params = {
.use_topology_distance = op_params->use_topology_distance,
.use_step_face = op_params->use_face_step,
.aspect_y = aspect_y,
- .cd_loop_uv_offset = cd_loop_uv_offset,
+ .cd_loop_uv_offset = offsets.uv,
};
LinkNode *path = NULL;
@@ -492,7 +488,7 @@ static bool uv_shortest_path_pick_ex(Scene *scene,
BMElem *ele_src,
BMElem *ele_dst,
const float aspect_y,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
const char uv_selectmode = ED_uvedit_select_mode_get(scene);
@@ -503,33 +499,18 @@ static bool uv_shortest_path_pick_ex(Scene *scene,
/* pass */
}
else if (ele_src->head.htype == BM_FACE) {
- flush = mouse_mesh_uv_shortest_path_face(scene,
- obedit,
- op_params,
- (BMFace *)ele_src,
- (BMFace *)ele_dst,
- aspect_y,
- cd_loop_uv_offset);
+ flush = mouse_mesh_uv_shortest_path_face(
+ scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst, aspect_y, offsets);
ok = true;
}
else if (ele_src->head.htype == BM_LOOP) {
if (uv_selectmode & UV_SELECT_EDGE) {
- flush = mouse_mesh_uv_shortest_path_edge(scene,
- obedit,
- op_params,
- (BMLoop *)ele_src,
- (BMLoop *)ele_dst,
- aspect_y,
- cd_loop_uv_offset);
+ flush = mouse_mesh_uv_shortest_path_edge(
+ scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets);
}
else {
- flush = mouse_mesh_uv_shortest_path_vert(scene,
- obedit,
- op_params,
- (BMLoop *)ele_src,
- (BMLoop *)ele_dst,
- aspect_y,
- cd_loop_uv_offset);
+ flush = mouse_mesh_uv_shortest_path_vert(
+ scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets);
}
ok = true;
}
@@ -586,7 +567,8 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float aspect_y;
{
@@ -628,8 +610,8 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
else {
l_src = ED_uvedit_active_edge_loop_get(bm);
if (l_src != NULL) {
- if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset) &&
- !uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset)) {
+ if (!uvedit_uv_select_test(scene, l_src, offsets) &&
+ !uvedit_uv_select_test(scene, l_src->next, offsets)) {
l_src = NULL;
}
ele_src = (BMElem *)l_src;
@@ -654,7 +636,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
else {
l_src = ED_uvedit_active_vert_loop_get(bm);
if (l_src != NULL) {
- if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) {
+ if (!uvedit_uv_select_test(scene, l_src, offsets)) {
l_src = NULL;
}
}
@@ -668,7 +650,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve
}
uv_shortest_path_pick_ex(
- scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets);
/* To support redo. */
int index;
@@ -697,7 +679,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float aspect_y;
{
@@ -743,7 +725,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op)
op_params.track_active = true;
if (!uv_shortest_path_pick_ex(
- scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) {
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets)) {
return OPERATOR_CANCELLED;
}
@@ -804,7 +786,9 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
BMElem *ele_src = NULL, *ele_dst = NULL;
/* Find 2x elements. */
@@ -833,7 +817,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op)
path_select_params_from_op(op, &op_params);
uv_shortest_path_pick_ex(
- scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset);
+ scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets);
found_valid_elements = true;
}
diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c
index 5497b9cd1e5..5e98e0cfac5 100644
--- a/source/blender/editors/uvedit/uvedit_rip.c
+++ b/source/blender/editors/uvedit/uvedit_rip.c
@@ -186,13 +186,13 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd
static void bm_loop_uv_select_single_vert_validate(BMLoop *l_init, const int cd_loop_uv_offset)
{
- const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset);
BMIter liter;
BMLoop *l;
bool is_single_vert = true;
BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(luv_init->uv, luv->uv)) {
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init, luv)) {
if (UL(l->prev)->is_select_edge || UL(l)->is_select_edge) {
is_single_vert = false;
break;
@@ -202,8 +202,8 @@ static void bm_loop_uv_select_single_vert_validate(BMLoop *l_init, const int cd_
if (is_single_vert == false) {
BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
if (UL(l)->is_select_vert_single) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(luv_init->uv, luv->uv)) {
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init, luv)) {
UL(l)->is_select_vert_single = false;
}
}
@@ -227,12 +227,12 @@ static void bm_loop_calc_uv_angle_from_dir(BMLoop *l,
{
/* Calculate 3 directions, return the shortest angle. */
float dir_test[3][2];
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset);
+ const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset);
- sub_v2_v2v2(dir_test[0], luv->uv, luv_prev->uv);
- sub_v2_v2v2(dir_test[2], luv->uv, luv_next->uv);
+ sub_v2_v2v2(dir_test[0], luv, luv_prev);
+ sub_v2_v2v2(dir_test[2], luv, luv_next);
dir_test[0][1] /= aspect_y;
dir_test[2][1] /= aspect_y;
@@ -302,8 +302,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
const int cd_loop_uv_offset)
{
UVRipSingle *rip = MEM_callocN(sizeof(*rip), __func__);
- const float *co_center =
- (((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_init_orig, cd_loop_uv_offset))->uv);
+ const float *co_center = BM_ELEM_CD_GET_FLOAT_P(l_init_orig, cd_loop_uv_offset);
rip->loops = BLI_gset_ptr_new(__func__);
/* Track the closest loop, start walking from this so in the event we have multiple
@@ -328,8 +327,8 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig,
BMLoop *l;
BM_ITER_ELEM (l, &liter, l_init_orig->v, BM_LOOPS_OF_VERT) {
if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(co_center, luv->uv)) {
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(co_center, luv)) {
uv_fan_count_all += 1;
/* Clear at the same time. */
UL(l)->is_select_vert_single = true;
@@ -462,19 +461,19 @@ static float uv_rip_pairs_calc_uv_angle(BMLoop *l_init,
const int cd_loop_uv_offset)
{
BMIter liter;
- const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset);
float angle_of_side = 0.0f;
BMLoop *l;
BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
if (UL(l)->in_rip_pairs) {
if (UL(l)->side == side) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(luv_init->uv, luv->uv)) {
- const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init, luv)) {
+ const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset);
+ const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset);
float dir_prev[2], dir_next[2];
- sub_v2_v2v2(dir_prev, luv_prev->uv, luv->uv);
- sub_v2_v2v2(dir_next, luv_next->uv, luv->uv);
+ sub_v2_v2v2(dir_prev, luv_prev, luv);
+ sub_v2_v2v2(dir_next, luv_next, luv);
dir_prev[1] /= aspect_y;
dir_next[1] /= aspect_y;
const float luv_angle = angle_v2v2(dir_prev, dir_next);
@@ -490,15 +489,15 @@ static float uv_rip_pairs_calc_uv_angle(BMLoop *l_init,
static int uv_rip_pairs_loop_count_on_side(BMLoop *l_init, uint side, const int cd_loop_uv_offset)
{
- const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset);
+ const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset);
int count = 0;
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) {
if (UL(l)->in_rip_pairs) {
if (UL(l)->side == side) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (equals_v2v2(luv_init->uv, luv->uv)) {
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ if (equals_v2v2(luv_init, luv)) {
count += 1;
}
}
@@ -694,18 +693,18 @@ static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip,
GSET_ITER (gs_iter, rip->loops) {
BMLoop *l = BLI_gsetIterator_getKey(&gs_iter);
int side = UL(l)->side;
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- add_v2_v2(r_center, luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ add_v2_v2(r_center, luv);
float dir[2];
if (!UL(l)->is_select_edge) {
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- sub_v2_v2v2(dir, luv_next->uv, luv->uv);
+ const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset);
+ sub_v2_v2v2(dir, luv_next, luv);
add_v2_v2(r_dir_side[side], dir);
}
if (!UL(l->prev)->is_select_edge) {
- const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
- sub_v2_v2v2(dir, luv_prev->uv, luv->uv);
+ const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset);
+ sub_v2_v2v2(dir, luv_prev, luv);
add_v2_v2(r_dir_side[side], dir);
}
side_total[side] += 1;
@@ -735,7 +734,10 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
Mesh *me = (Mesh *)obedit->data;
BMEditMesh *em = me->edit_mesh;
BMesh *bm = em->bm;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BMFace *efa;
BMIter iter, liter;
@@ -759,13 +761,11 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
bool is_all = true;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_VERTSEL) {
- const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_EDGESEL) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
UL(l)->is_select_edge = true;
}
- else if ((luv_prev->flag & MLOOPUV_EDGESEL) == 0) {
+ else if (!BM_ELEM_CD_GET_OPT_BOOL(l->prev, offsets.select_edge)) {
/* #bm_loop_uv_select_single_vert_validate validates below. */
UL(l)->is_select_vert_single = true;
is_all = false;
@@ -793,7 +793,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (UL(l)->is_select_vert_single) {
- bm_loop_uv_select_single_vert_validate(l, cd_loop_uv_offset);
+ bm_loop_uv_select_single_vert_validate(l, offsets.uv);
}
}
}
@@ -809,13 +809,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (!UL(l)->is_select_all) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_VERTSEL) {
- luv->flag &= ~MLOOPUV_VERTSEL;
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
changed = true;
}
- if (luv->flag & MLOOPUV_EDGESEL) {
- luv->flag &= ~MLOOPUV_EDGESEL;
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
changed = true;
}
}
@@ -830,12 +829,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (UL(l)->is_select_edge) {
if (!UL(l)->in_rip_pairs) {
- UVRipPairs *rip = uv_rip_pairs_from_loop(l, aspect_y, cd_loop_uv_offset);
+ UVRipPairs *rip = uv_rip_pairs_from_loop(l, aspect_y, offsets.uv);
float center[2];
float dir_cursor[2];
float dir_side[2][2];
int side_from_cursor = -1;
- if (uv_rip_pairs_calc_center_and_direction(rip, cd_loop_uv_offset, center, dir_side)) {
+ if (uv_rip_pairs_calc_center_and_direction(rip, offsets.uv, center, dir_side)) {
for (int i = 0; i < 2; i++) {
sub_v2_v2v2(dir_cursor, center, co);
normalize_v2(dir_cursor);
@@ -848,7 +847,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
ULData *ul = UL(l_iter);
if (ul->side == side_from_cursor) {
- uvedit_uv_select_disable(scene, em->bm, l_iter, cd_loop_uv_offset);
+ uvedit_uv_select_disable(scene, bm, l_iter, offsets);
changed = true;
}
/* Ensure we don't operate on these again. */
@@ -858,7 +857,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
}
}
else if (UL(l)->is_select_vert_single) {
- UVRipSingle *rip = uv_rip_single_from_loop(l, co, aspect_y, cd_loop_uv_offset);
+ UVRipSingle *rip = uv_rip_single_from_loop(l, co, aspect_y, offsets.uv);
/* We only ever use one side. */
const int side_from_cursor = 0;
GSetIterator gs_iter;
@@ -866,7 +865,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const
BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter);
ULData *ul = UL(l_iter);
if (ul->side == side_from_cursor) {
- uvedit_uv_select_disable(scene, em->bm, l_iter, cd_loop_uv_offset);
+ uvedit_uv_select_disable(scene, bm, l_iter, offsets);
changed = true;
}
/* Ensure we don't operate on these again. */
diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c
index 777cc1d97e4..faa7b0e9b73 100644
--- a/source/blender/editors/uvedit/uvedit_select.c
+++ b/source/blender/editors/uvedit/uvedit_select.c
@@ -198,7 +198,7 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const b
static void uvedit_vertex_select_tagged(BMEditMesh *em,
Scene *scene,
bool select,
- int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMFace *efa;
BMLoop *l;
@@ -207,7 +207,7 @@ static void uvedit_vertex_select_tagged(BMEditMesh *em,
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
}
}
}
@@ -225,34 +225,32 @@ bool uvedit_face_visible_test(const Scene *scene, BMFace *efa)
return uvedit_face_visible_test_ex(scene->toolsettings, efa);
}
-bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int cd_loop_uv_offset)
+bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const BMUVOffsets offsets)
{
if (ts->uv_flag & UV_SYNC_SELECTION) {
return BM_elem_flag_test(efa, BM_ELEM_SELECT);
}
BMLoop *l;
- MLoopUV *luv;
BMIter liter;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (ts->uv_selectmode & UV_SELECT_VERTEX) {
- if ((luv->flag & MLOOPUV_VERTSEL) == 0) {
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) {
return false;
}
}
else {
- if ((luv->flag & MLOOPUV_EDGESEL) == 0) {
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
return false;
}
}
}
return true;
}
-bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const int cd_loop_uv_offset)
+bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const BMUVOffsets offsets)
{
- return uvedit_face_select_test_ex(scene->toolsettings, efa, cd_loop_uv_offset);
+ return uvedit_face_select_test_ex(scene->toolsettings, efa, offsets);
}
void uvedit_face_select_set_with_sticky(const Scene *scene,
@@ -260,12 +258,12 @@ void uvedit_face_select_set_with_sticky(const Scene *scene,
BMFace *efa,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
const char sticky = ts->uv_sticky;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- uvedit_face_select_set(scene, em->bm, efa, select, do_history, cd_loop_uv_offset);
+ uvedit_face_select_set(scene, em->bm, efa, select, do_history, offsets);
return;
}
if (!uvedit_face_visible_test(scene, efa)) {
@@ -275,12 +273,12 @@ void uvedit_face_select_set_with_sticky(const Scene *scene,
* (not part of any face selections). This now uses the sticky location mode logic instead. */
switch (sticky) {
case SI_STICKY_DISABLE: {
- uvedit_face_select_set(scene, em->bm, efa, select, do_history, cd_loop_uv_offset);
+ uvedit_face_select_set(scene, em->bm, efa, select, do_history, offsets);
break;
}
default: {
/* SI_STICKY_LOC and SI_STICKY_VERTEX modes. */
- uvedit_face_select_shared_vert(scene, em, efa, select, do_history, cd_loop_uv_offset);
+ uvedit_face_select_shared_vert(scene, em, efa, select, do_history, offsets);
}
}
}
@@ -290,23 +288,20 @@ void uvedit_face_select_shared_vert(const Scene *scene,
BMFace *efa,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (select) {
- luv->flag |= MLOOPUV_EDGESEL;
- uvedit_uv_select_shared_vert(
- scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
+ uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets);
}
else {
- luv->flag &= ~MLOOPUV_EDGESEL;
- if (!uvedit_vert_is_face_select_any_other(scene, l, cd_loop_uv_offset)) {
- uvedit_uv_select_shared_vert(
- scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
+ if (!uvedit_vert_is_face_select_any_other(scene, l, offsets)) {
+ uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets);
}
}
}
@@ -317,20 +312,20 @@ void uvedit_face_select_set(const Scene *scene,
BMFace *efa,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
if (select) {
- uvedit_face_select_enable(scene, bm, efa, do_history, cd_loop_uv_offset);
+ uvedit_face_select_enable(scene, bm, efa, do_history, offsets);
}
else {
- uvedit_face_select_disable(scene, bm, efa, cd_loop_uv_offset);
+ uvedit_face_select_disable(scene, bm, efa, offsets);
}
}
void uvedit_face_select_enable(
- const Scene *scene, BMesh *bm, BMFace *efa, const bool do_history, const int cd_loop_uv_offset)
+ const Scene *scene, BMesh *bm, BMFace *efa, const bool do_history, const BMUVOffsets offsets)
{
- BLI_assert(cd_loop_uv_offset >= 0);
+ BLI_assert(offsets.uv >= 0);
const ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -341,12 +336,11 @@ void uvedit_face_select_enable(
}
else {
BMLoop *l;
- MLoopUV *luv;
BMIter liter;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
}
}
}
@@ -354,9 +348,9 @@ void uvedit_face_select_enable(
void uvedit_face_select_disable(const Scene *scene,
BMesh *bm,
BMFace *efa,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
- BLI_assert(cd_loop_uv_offset >= 0);
+ BLI_assert(offsets.uv >= 0);
const ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
@@ -364,17 +358,16 @@ void uvedit_face_select_disable(const Scene *scene,
}
else {
BMLoop *l;
- MLoopUV *luv;
BMIter liter;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
}
}
}
-bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_loop_uv_offset)
+bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const BMUVOffsets offsets)
{
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE) {
@@ -387,18 +380,16 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_
BM_elem_flag_test(l->next->v, BM_ELEM_SELECT);
}
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
if (ts->uv_selectmode & UV_SELECT_VERTEX) {
- MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- return (luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL);
+ return BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) &&
+ BM_ELEM_CD_GET_OPT_BOOL(l->next, offsets.select_vert);
}
- return (luv->flag & MLOOPUV_EDGESEL);
+ return BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge);
}
-bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
+bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const BMUVOffsets offsets)
{
- return uvedit_edge_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
+ return uvedit_edge_select_test_ex(scene->toolsettings, l, offsets);
}
void uvedit_edge_select_set_with_sticky(const Scene *scene,
@@ -406,11 +397,11 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene,
BMLoop *l,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- uvedit_edge_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_set(scene, em->bm, l, select, do_history, offsets);
return;
}
@@ -418,19 +409,17 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene,
switch (sticky) {
case SI_STICKY_DISABLE: {
if (uvedit_face_visible_test(scene, l->f)) {
- uvedit_edge_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_set(scene, em->bm, l, select, do_history, offsets);
}
break;
}
case SI_STICKY_VERTEX: {
- uvedit_edge_select_shared_vert(
- scene, em, l, select, SI_STICKY_VERTEX, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_shared_vert(scene, em, l, select, SI_STICKY_VERTEX, do_history, offsets);
break;
}
default: {
/* SI_STICKY_LOC (Fallback) */
- uvedit_edge_select_shared_vert(
- scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets);
break;
}
}
@@ -449,31 +438,28 @@ void uvedit_edge_select_shared_vert(const Scene *scene,
const bool select,
const int sticky_flag,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BLI_assert(ELEM(sticky_flag, SI_STICKY_LOC, SI_STICKY_VERTEX));
/* Set edge flags. Rely on this for face visibility checks */
- uvedit_edge_select_set_noflush(scene, l, select, sticky_flag, cd_loop_uv_offset);
+ uvedit_edge_select_set_noflush(scene, l, select, sticky_flag, offsets);
/* Vert selections. */
BMLoop *l_iter = l;
do {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- if (select && (luv->flag & MLOOPUV_EDGESEL)) {
+ if (select && BM_ELEM_CD_GET_OPT_BOOL(l_iter, offsets.select_edge)) {
+ uvedit_uv_select_shared_vert(scene, em, l_iter, true, SI_STICKY_LOC, do_history, offsets);
uvedit_uv_select_shared_vert(
- scene, em, l_iter, true, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
- uvedit_uv_select_shared_vert(
- scene, em, l_iter->next, true, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ scene, em, l_iter->next, true, SI_STICKY_LOC, do_history, offsets);
}
- else if (!select && !(luv->flag & MLOOPUV_EDGESEL)) {
- if (!uvedit_vert_is_edge_select_any_other(scene, l, cd_loop_uv_offset)) {
- uvedit_uv_select_shared_vert(
- scene, em, l_iter, false, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ else if (!select && !BM_ELEM_CD_GET_OPT_BOOL(l_iter, offsets.select_edge)) {
+ if (!uvedit_vert_is_edge_select_any_other(scene, l, offsets)) {
+ uvedit_uv_select_shared_vert(scene, em, l_iter, false, SI_STICKY_LOC, do_history, offsets);
}
- if (!uvedit_vert_is_edge_select_any_other(scene, l->next, cd_loop_uv_offset)) {
+ if (!uvedit_vert_is_edge_select_any_other(scene, l->next, offsets)) {
uvedit_uv_select_shared_vert(
- scene, em, l_iter->next, false, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ scene, em, l_iter->next, false, SI_STICKY_LOC, do_history, offsets);
}
}
} while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != SI_STICKY_LOC));
@@ -484,16 +470,14 @@ void uvedit_edge_select_set_noflush(const Scene *scene,
BMLoop *l,
const bool select,
const int sticky_flag,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
- MLoopUV *luv;
BMLoop *l_iter = l;
do {
if (uvedit_face_visible_test(scene, l_iter->f)) {
if ((sticky_flag == SI_STICKY_VERTEX) ||
- BM_loop_uv_share_edge_check(l, l_iter, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_EDGESEL);
+ BM_loop_uv_share_edge_check(l, l_iter, offsets.uv)) {
+ BM_ELEM_CD_SET_BOOL(l_iter, offsets.select_edge, select);
}
}
} while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != SI_STICKY_DISABLE));
@@ -504,19 +488,18 @@ void uvedit_edge_select_set(const Scene *scene,
BMLoop *l,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
-
+ const BMUVOffsets offsets)
{
if (select) {
- uvedit_edge_select_enable(scene, bm, l, do_history, cd_loop_uv_offset);
+ uvedit_edge_select_enable(scene, bm, l, do_history, offsets);
}
else {
- uvedit_edge_select_disable(scene, bm, l, cd_loop_uv_offset);
+ uvedit_edge_select_disable(scene, bm, l, offsets);
}
}
void uvedit_edge_select_enable(
- const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const int cd_loop_uv_offset)
+ const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
@@ -538,20 +521,16 @@ void uvedit_edge_select_enable(
}
}
else {
- MLoopUV *luv, *luv_next;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
- luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
- luv_next->flag |= MLOOPUV_VERTSEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
+ BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true);
}
}
void uvedit_edge_select_disable(const Scene *scene,
BMesh *bm,
BMLoop *l,
- const int cd_loop_uv_offset)
-
+ const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
@@ -568,29 +547,24 @@ void uvedit_edge_select_disable(const Scene *scene,
}
}
else {
- MLoopUV *luv, *luv_next;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
- luv->flag &= ~MLOOPUV_EDGESEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
if ((ts->uv_selectmode & UV_SELECT_VERTEX) == 0) {
/* Deselect UV vertex if not part of another edge selection */
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
- if (!(luv_next->flag & MLOOPUV_EDGESEL)) {
- luv_next->flag &= ~MLOOPUV_VERTSEL;
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l->next, offsets.select_edge)) {
+ BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
}
- if (!(luv_prev->flag & MLOOPUV_EDGESEL)) {
- luv->flag &= ~MLOOPUV_VERTSEL;
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l->prev, offsets.select_edge)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
}
}
else {
- luv_next->flag &= ~MLOOPUV_VERTSEL;
- luv->flag &= ~MLOOPUV_VERTSEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
+ BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
}
}
}
-bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_loop_uv_offset)
+bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const BMUVOffsets offsets)
{
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (ts->selectmode & SCE_SELECT_FACE) {
@@ -602,8 +576,6 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo
return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT);
}
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
if (ts->selectmode & SCE_SELECT_FACE) {
/* Are you looking for `uvedit_face_select_test(...)` instead? */
}
@@ -612,12 +584,12 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo
/* Are you looking for `uvedit_edge_select_test(...)` instead? */
}
- return (luv->flag & MLOOPUV_VERTSEL) != 0;
+ return BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert);
}
-bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset)
+bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const BMUVOffsets offsets)
{
- return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset);
+ return uvedit_uv_select_test_ex(scene->toolsettings, l, offsets);
}
void uvedit_uv_select_set_with_sticky(const Scene *scene,
@@ -625,11 +597,11 @@ void uvedit_uv_select_set_with_sticky(const Scene *scene,
BMLoop *l,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
if (ts->uv_flag & UV_SYNC_SELECTION) {
- uvedit_uv_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, do_history, offsets);
return;
}
@@ -637,19 +609,17 @@ void uvedit_uv_select_set_with_sticky(const Scene *scene,
switch (sticky) {
case SI_STICKY_DISABLE: {
if (uvedit_face_visible_test(scene, l->f)) {
- uvedit_uv_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, do_history, offsets);
}
break;
}
case SI_STICKY_VERTEX: {
- uvedit_uv_select_shared_vert(
- scene, em, l, select, SI_STICKY_VERTEX, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_VERTEX, do_history, offsets);
break;
}
default: {
/* SI_STICKY_LOC. */
- uvedit_uv_select_shared_vert(
- scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets);
break;
}
}
@@ -668,7 +638,7 @@ void uvedit_uv_select_shared_vert(const Scene *scene,
const bool select,
const int sticky_flag,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BLI_assert(ELEM(sticky_flag, SI_STICKY_LOC, SI_STICKY_VERTEX));
@@ -686,13 +656,12 @@ void uvedit_uv_select_shared_vert(const Scene *scene,
if (sticky_flag == SI_STICKY_VERTEX) {
do_select = true;
}
- else if (BM_loop_uv_share_vert_check(l, l_radial_iter, cd_loop_uv_offset)) {
+ else if (BM_loop_uv_share_vert_check(l, l_radial_iter, offsets.uv)) {
do_select = true;
}
if (do_select) {
- uvedit_uv_select_set(
- scene, em->bm, l_radial_iter, select, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l_radial_iter, select, do_history, offsets);
}
}
}
@@ -705,18 +674,18 @@ void uvedit_uv_select_set(const Scene *scene,
BMLoop *l,
const bool select,
const bool do_history,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
if (select) {
- uvedit_uv_select_enable(scene, bm, l, do_history, cd_loop_uv_offset);
+ uvedit_uv_select_enable(scene, bm, l, do_history, offsets);
}
else {
- uvedit_uv_select_disable(scene, bm, l, cd_loop_uv_offset);
+ uvedit_uv_select_disable(scene, bm, l, offsets);
}
}
void uvedit_uv_select_enable(
- const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const int cd_loop_uv_offset)
+ const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
@@ -737,15 +706,11 @@ void uvedit_uv_select_enable(
}
}
else {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag |= MLOOPUV_VERTSEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
}
}
-void uvedit_uv_select_disable(const Scene *scene,
- BMesh *bm,
- BMLoop *l,
- const int cd_loop_uv_offset)
+void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets offsets)
{
const ToolSettings *ts = scene->toolsettings;
@@ -758,21 +723,20 @@ void uvedit_uv_select_disable(const Scene *scene,
}
}
else {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag &= ~MLOOPUV_VERTSEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
}
}
static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene *scene,
BMLoop *l_src,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMLoop *l_other = NULL;
BMLoop *l_iter = l_src->radial_next;
if (l_iter != l_src) {
do {
if (uvedit_face_visible_test(scene, l_iter->f) &&
- BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) {
+ BM_loop_uv_share_edge_check(l_src, l_iter, offsets.uv)) {
/* Check UV's are contiguous. */
if (l_other == NULL) {
l_other = l_iter;
@@ -791,10 +755,9 @@ static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene
static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scene *scene,
BMLoop *l_edge,
BMVert *v_pivot,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
- BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_edge, cd_loop_uv_offset) == NULL);
+ BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_edge, offsets) == NULL);
BMLoop *l_step = l_edge;
l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next;
@@ -802,16 +765,15 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen
do {
BLI_assert(BM_vert_in_edge(l_step->e, v_pivot));
l_step_last = l_step;
- l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step, cd_loop_uv_offset);
+ l_step = uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step, offsets);
if (l_step) {
l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next;
}
} while (l_step != NULL);
if (l_step_last != NULL) {
- BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step_last, cd_loop_uv_offset) == NULL);
+ BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step_last, offsets) ==
+ NULL);
}
return l_step_last;
@@ -831,11 +793,11 @@ bool uv_find_nearest_edge(
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv, *luv_next;
+ float *luv, *luv_next;
int i;
bool found = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
@@ -844,11 +806,11 @@ bool uv_find_nearest_edge(
continue;
}
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv);
+ luv_next = BM_ELEM_CD_GET_VOID_P(l->next, offsets.uv);
float delta[2];
- closest_to_line_segment_v2(delta, co, luv->uv, luv_next->uv);
+ closest_to_line_segment_v2(delta, co, luv, luv_next);
sub_v2_v2(delta, co);
mul_v2_v2(delta, hit->scale);
@@ -857,7 +819,7 @@ bool uv_find_nearest_edge(
/* Ensures that successive selection attempts will select other edges sharing the same
* UV coordinates as the previous selection. */
- if ((penalty != 0.0f) && uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ if ((penalty != 0.0f) && uvedit_edge_select_test(scene, l, offsets)) {
dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty);
}
if (dist_test_sq < hit->dist_sq) {
@@ -898,7 +860,7 @@ bool uv_find_nearest_face_ex(
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool found = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BMIter iter;
BMFace *efa;
@@ -964,9 +926,9 @@ bool uv_find_nearest_face_multi(
static bool uv_nearest_between(const BMLoop *l, const float co[2], const int cd_loop_uv_offset)
{
- const float *uv_prev = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset))->uv;
- const float *uv_curr = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv;
- const float *uv_next = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset))->uv;
+ const float *uv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset);
+ const float *uv_curr = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ const float *uv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset);
return ((line_point_side_v2(uv_prev, uv_curr, co) > 0.0f) &&
(line_point_side_v2(uv_next, uv_curr, co) <= 0.0f));
@@ -984,7 +946,7 @@ bool uv_find_nearest_vert(
BM_mesh_elem_index_ensure(em->bm, BM_VERT);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -995,24 +957,24 @@ bool uv_find_nearest_vert(
BMLoop *l;
int i;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
float delta[2];
- sub_v2_v2v2(delta, co, luv->uv);
+ sub_v2_v2v2(delta, co, luv);
mul_v2_v2(delta, hit->scale);
float dist_test_sq = len_squared_v2(delta);
/* Ensures that successive selection attempts will select other vertices sharing the same
* UV coordinates */
- if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, offsets)) {
dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty_dist);
}
if (dist_test_sq <= hit->dist_sq) {
if (dist_test_sq == hit->dist_sq) {
- if (!uv_nearest_between(l, co, cd_loop_uv_offset)) {
+ if (!uv_nearest_between(l, co, offsets.uv)) {
continue;
}
}
@@ -1060,7 +1022,7 @@ static bool uvedit_nearest_uv(const Scene *scene,
BMFace *efa;
const float *uv_best = NULL;
float dist_best = *dist_sq;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
continue;
@@ -1068,11 +1030,11 @@ static bool uvedit_nearest_uv(const Scene *scene,
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
do {
- if (ignore_selected && uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ if (ignore_selected && uvedit_uv_select_test(scene, l_iter, offsets)) {
continue;
}
- const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv;
+ const float *uv = BM_ELEM_CD_GET_FLOAT_P(l_iter, offsets.uv);
float co_tmp[2];
mul_v2_v2v2(co_tmp, scale, uv);
const float dist_test = len_squared_v2v2(co, co_tmp);
@@ -1134,7 +1096,7 @@ BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
const float co[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BMIter liter;
BMLoop *l;
@@ -1146,8 +1108,8 @@ BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene,
continue;
}
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- const float dist_test_sq = len_squared_v2v2(co, luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ const float dist_test_sq = len_squared_v2v2(co, luv);
if (dist_test_sq < dist_best_sq) {
dist_best_sq = dist_test_sq;
l_found = l;
@@ -1162,8 +1124,7 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
const float co[2])
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- BLI_assert(cd_loop_uv_offset >= 0);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BMIter eiter;
BMLoop *l;
@@ -1174,9 +1135,9 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
if (!uvedit_face_visible_test(scene, l->f)) {
continue;
}
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset);
+ const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv, luv_next);
if (dist_test_sq < dist_best_sq) {
dist_best_sq = dist_test_sq;
l_found = l;
@@ -1191,9 +1152,7 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene,
/** \name Helper functions for UV selection.
* \{ */
-bool uvedit_vert_is_edge_select_any_other(const Scene *scene,
- BMLoop *l,
- const int cd_loop_uv_offset)
+bool uvedit_vert_is_edge_select_any_other(const Scene *scene, BMLoop *l, const BMUVOffsets offsets)
{
BMEdge *e_iter = l->e;
do {
@@ -1203,8 +1162,8 @@ bool uvedit_vert_is_edge_select_any_other(const Scene *scene,
/* Use #l_other to check if the uvs are connected (share the same uv coordinates)
* and #l_radial_iter for the actual edge selection test. */
l_other = (l_radial_iter->v != l->v) ? l_radial_iter->next : l_radial_iter;
- if (BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) &&
- uvedit_edge_select_test(scene, l_radial_iter, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_vert_check(l, l_other, offsets.uv) &&
+ uvedit_edge_select_test(scene, l_radial_iter, offsets)) {
return true;
}
}
@@ -1214,9 +1173,7 @@ bool uvedit_vert_is_edge_select_any_other(const Scene *scene,
return false;
}
-bool uvedit_vert_is_face_select_any_other(const Scene *scene,
- BMLoop *l,
- const int cd_loop_uv_offset)
+bool uvedit_vert_is_face_select_any_other(const Scene *scene, BMLoop *l, const BMUVOffsets offsets)
{
BMIter liter;
BMLoop *l_iter;
@@ -1224,8 +1181,8 @@ bool uvedit_vert_is_face_select_any_other(const Scene *scene,
if (!uvedit_face_visible_test(scene, l_iter->f) || (l_iter->f == l->f)) {
continue;
}
- if (BM_loop_uv_share_vert_check(l, l_iter, cd_loop_uv_offset) &&
- uvedit_face_select_test(scene, l_iter->f, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) &&
+ uvedit_face_select_test(scene, l_iter->f, offsets)) {
return true;
}
}
@@ -1234,7 +1191,7 @@ bool uvedit_vert_is_face_select_any_other(const Scene *scene,
bool uvedit_vert_is_all_other_faces_selected(const Scene *scene,
BMLoop *l,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMIter liter;
BMLoop *l_iter;
@@ -1242,22 +1199,19 @@ bool uvedit_vert_is_all_other_faces_selected(const Scene *scene,
if (!uvedit_face_visible_test(scene, l_iter->f) || (l_iter->f == l->f)) {
continue;
}
- if (BM_loop_uv_share_vert_check(l, l_iter, cd_loop_uv_offset) &&
- !uvedit_face_select_test(scene, l_iter->f, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) &&
+ !uvedit_face_select_test(scene, l_iter->f, offsets)) {
return false;
}
}
return true;
}
-/**
- * Clear specified UV flag (vert/edge/pinned).
- */
-static void bm_uv_flag_clear(const Scene *scene,
- BMesh *bm,
- const int flag,
- const int cd_loop_uv_offset)
+static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUVOffsets offsets)
{
+ if (offsets.select_vert == -1) {
+ return;
+ }
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -1266,8 +1220,7 @@ static void bm_uv_flag_clear(const Scene *scene,
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag &= ~flag;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
}
}
}
@@ -1282,7 +1235,10 @@ static void bm_uv_flag_clear(const Scene *scene,
void ED_uvedit_selectmode_flush(const Scene *scene, BMEditMesh *em)
{
const ToolSettings *ts = scene->toolsettings;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0);
UNUSED_VARS_NDEBUG(ts);
@@ -1297,16 +1253,9 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMEditMesh *em)
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv, *luv_next;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
- if ((luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL)) {
- luv->flag |= MLOOPUV_EDGESEL;
- }
- else {
- luv->flag &= ~MLOOPUV_EDGESEL;
- }
+ bool edge_selected = BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) &&
+ BM_ELEM_CD_GET_OPT_BOOL(l->next, offsets.select_vert);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, edge_selected);
}
}
}
@@ -1323,7 +1272,9 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em)
/* Careful when using this in face select mode.
* For face selections with sticky mode enabled, this can create invalid selection states. */
const ToolSettings *ts = scene->toolsettings;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0);
UNUSED_VARS_NDEBUG(ts);
@@ -1336,12 +1287,9 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em)
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv, *luv_next;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
- if ((luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL)) {
- luv->flag |= MLOOPUV_EDGESEL;
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) &&
+ BM_ELEM_CD_GET_OPT_BOOL(l->next, offsets.select_vert)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
}
}
}
@@ -1350,7 +1298,9 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em)
void uvedit_deselect_flush(const Scene *scene, BMEditMesh *em)
{
const ToolSettings *ts = scene->toolsettings;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0);
UNUSED_VARS_NDEBUG(ts);
@@ -1363,14 +1313,9 @@ void uvedit_deselect_flush(const Scene *scene, BMEditMesh *em)
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv, *luv_next;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
-
- if (luv->flag & MLOOPUV_EDGESEL) {
- if (!(luv->flag & MLOOPUV_VERTSEL) || !(luv_next->flag & MLOOPUV_VERTSEL)) {
- luv->flag &= ~MLOOPUV_EDGESEL;
- }
+ if ((!BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) ||
+ (!BM_ELEM_CD_GET_OPT_BOOL(l->next, offsets.select_vert))) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
}
}
}
@@ -1393,13 +1338,13 @@ enum eUVEdgeLoopBoundaryMode {
static BMLoop *bm_select_edgeloop_double_side_next(const Scene *scene,
BMLoop *l_step,
BMVert *v_from,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
if (l_step->f->len == 4) {
BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from);
BMLoop *l_step_over = (v_from == l_step->v) ? l_step->next : l_step->prev;
l_step_over = uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step_over, cd_loop_uv_offset);
+ scene, l_step_over, offsets);
if (l_step_over) {
return (l_step_over->v == v_from_next) ? l_step_over->prev : l_step_over->next;
}
@@ -1410,11 +1355,11 @@ static BMLoop *bm_select_edgeloop_double_side_next(const Scene *scene,
static BMLoop *bm_select_edgeloop_single_side_next(const Scene *scene,
BMLoop *l_step,
BMVert *v_from,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from);
return uvedit_loop_find_other_boundary_loop_with_visible_face(
- scene, l_step, v_from_next, cd_loop_uv_offset);
+ scene, l_step, v_from_next, offsets);
}
/* TODO(@campbellbarton): support this in the BMesh API, as we have for clearing other types. */
@@ -1437,7 +1382,7 @@ static void bm_loop_tags_clear(BMesh *bm)
static void uv_select_edgeloop_double_side_tag(const Scene *scene,
BMEditMesh *em,
BMLoop *l_init_pair[2],
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
bm_loop_tags_clear(em->bm);
@@ -1451,8 +1396,8 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene,
if (!uvedit_face_visible_test(scene, l_step_pair[0]->f) ||
!uvedit_face_visible_test(scene, l_step_pair[1]->f) ||
/* Check loops have not diverged. */
- (uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step_pair[0], cd_loop_uv_offset) != l_step_pair[1])) {
+ (uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step_pair[0], offsets) !=
+ l_step_pair[1])) {
break;
}
@@ -1465,7 +1410,7 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene,
/* Walk over both sides, ensure they keep on the same edge. */
for (int i = 0; i < ARRAY_SIZE(l_step_pair); i++) {
l_step_pair[i] = bm_select_edgeloop_double_side_next(
- scene, l_step_pair[i], v_from, cd_loop_uv_offset);
+ scene, l_step_pair[i], v_from, offsets);
}
if ((l_step_pair[0] && BM_elem_flag_test(l_step_pair[0], BM_ELEM_TAG)) ||
@@ -1486,7 +1431,7 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene,
static void uv_select_edgeloop_single_side_tag(const Scene *scene,
BMEditMesh *em,
BMLoop *l_init,
- const int cd_loop_uv_offset,
+ const BMUVOffsets offsets,
enum eUVEdgeLoopBoundaryMode boundary_mode,
int r_count_by_select[2])
{
@@ -1505,13 +1450,12 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene,
if (!uvedit_face_visible_test(scene, l_step->f) ||
/* Check the boundary is still a boundary. */
- (uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step, cd_loop_uv_offset) != NULL)) {
+ (uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step, offsets) != NULL)) {
break;
}
if (r_count_by_select != NULL) {
- r_count_by_select[uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)] += 1;
+ r_count_by_select[uvedit_edge_select_test(scene, l_step, offsets)] += 1;
/* Early exit when mixed could be optional if needed. */
if (r_count_by_select[0] && r_count_by_select[1]) {
r_count_by_select[0] = r_count_by_select[1] = -1;
@@ -1524,7 +1468,7 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene,
BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from);
BMFace *f_step_prev = l_step->f;
- l_step = bm_select_edgeloop_single_side_next(scene, l_step, v_from, cd_loop_uv_offset);
+ l_step = bm_select_edgeloop_single_side_next(scene, l_step, v_from, offsets);
if (l_step && BM_elem_flag_test(l_step, BM_ELEM_TAG)) {
break;
@@ -1546,10 +1490,13 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool select;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (extend) {
- select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset);
+ select = !uvedit_edge_select_test(scene, hit->l, offsets);
}
else {
select = true;
@@ -1557,7 +1504,7 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BMLoop *l_init_pair[2] = {
hit->l,
- uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset),
+ uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets),
};
/* When selecting boundaries, support cycling between selection modes. */
@@ -1569,13 +1516,13 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
int count_by_select[2];
/* If the loops selected toggle the boundaries. */
uv_select_edgeloop_single_side_tag(
- scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select);
+ scene, em, l_init_pair[0], offsets, boundary_mode, count_by_select);
if (count_by_select[!select] == 0) {
boundary_mode = UV_EDGE_LOOP_BOUNDARY_ALL;
/* If the boundary is selected, toggle back to the loop. */
uv_select_edgeloop_single_side_tag(
- scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select);
+ scene, em, l_init_pair[0], offsets, boundary_mode, count_by_select);
if (count_by_select[!select] == 0) {
boundary_mode = UV_EDGE_LOOP_BOUNDARY_LOOP;
}
@@ -1583,11 +1530,10 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
}
if (l_init_pair[1] == NULL) {
- uv_select_edgeloop_single_side_tag(
- scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, NULL);
+ uv_select_edgeloop_single_side_tag(scene, em, l_init_pair[0], offsets, boundary_mode, NULL);
}
else {
- uv_select_edgeloop_double_side_tag(scene, em, l_init_pair, cd_loop_uv_offset);
+ uv_select_edgeloop_double_side_tag(scene, em, l_init_pair, offsets);
}
/* Apply the selection. */
@@ -1605,13 +1551,11 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
if (ts->uv_selectmode == UV_SELECT_VERTEX) {
- uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, false, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(
- scene, em, l_iter->next, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, false, offsets);
+ uvedit_uv_select_set_with_sticky(scene, em, l_iter->next, select, false, offsets);
}
else {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_iter, select, false, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, l_iter, select, false, offsets);
}
}
}
@@ -1632,7 +1576,10 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BMEditMesh *em = BKE_editmesh_from_object(obedit);
bool select;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (!extend) {
uv_select_all_perform(scene, obedit, SEL_DESELECT);
@@ -1641,7 +1588,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false);
if (extend) {
- select = !uvedit_face_select_test(scene, hit->l->f, cd_loop_uv_offset);
+ select = !uvedit_face_select_test(scene, hit->l->f, offsets);
}
else {
select = true;
@@ -1649,7 +1596,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
BMLoop *l_pair[2] = {
hit->l,
- uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset),
+ uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets),
};
for (int side = 0; side < 2; side++) {
@@ -1659,13 +1606,13 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c
break;
}
- uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, offsets);
BM_elem_flag_enable(l_step->f, BM_ELEM_TAG);
if (l_step->f->len == 4) {
BMLoop *l_step_opposite = l_step->next->next;
l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step_opposite, cd_loop_uv_offset);
+ scene, l_step_opposite, offsets);
}
else {
l_step = NULL;
@@ -1701,7 +1648,10 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
(ts->uv_selectmode & UV_SELECT_VERTEX);
bool select;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (!extend) {
uv_select_all_perform(scene, obedit, SEL_DESELECT);
@@ -1710,7 +1660,7 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
BM_mesh_elem_hflag_disable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false);
if (extend) {
- select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset);
+ select = !uvedit_edge_select_test(scene, hit->l, offsets);
}
else {
select = true;
@@ -1718,7 +1668,7 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
BMLoop *l_pair[2] = {
hit->l,
- uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset),
+ uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets),
};
for (int side = 0; side < 2; side++) {
@@ -1734,23 +1684,22 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
/* While selecting face loops is now done in a separate function #uv_select_faceloop(),
* this check is still kept for edge ring selection, to keep it consistent with how edge
* ring selection works in face mode in the 3D viewport. */
- uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, offsets);
}
else if (use_vertex_select) {
- uvedit_uv_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset);
- uvedit_uv_select_set_with_sticky(
- scene, em, l_step->next, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, l_step, select, false, offsets);
+ uvedit_uv_select_set_with_sticky(scene, em, l_step->next, select, false, offsets);
}
else {
/* Edge select mode */
- uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, offsets);
}
BM_elem_flag_enable(l_step->e, BM_ELEM_TAG);
if (l_step->f->len == 4) {
BMLoop *l_step_opposite = l_step->next->next;
l_step = uvedit_loop_find_other_radial_loop_with_visible_face(
- scene, l_step_opposite, cd_loop_uv_offset);
+ scene, l_step_opposite, offsets);
if (l_step == NULL) {
/* Ensure we touch the opposite edge if we can't walk over it. */
l_step = l_step_opposite;
@@ -1767,10 +1716,10 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c
if (l_step && BM_elem_flag_test(l_step->e, BM_ELEM_TAG)) {
/* Previously this check was not done and this resulted in the final edge in the edge ring
* cycle to be skipped during selection (caused by old sticky selection behavior). */
- if (select && uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)) {
+ if (select && uvedit_edge_select_test(scene, l_step, offsets)) {
break;
}
- if (!select && !uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)) {
+ if (!select && !uvedit_edge_select_test(scene, l_step, offsets)) {
break;
}
}
@@ -1814,7 +1763,10 @@ static void uv_select_linked_multi(Scene *scene,
char *flag;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
@@ -1846,7 +1798,7 @@ static void uv_select_linked_multi(Scene *scene,
}
else {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
bool add_to_stack = true;
if (uv_sync_select) {
/* Special case, vertex/edge & sync select being enabled.
@@ -1860,16 +1812,15 @@ static void uv_select_linked_multi(Scene *scene,
* - There are no connected fully selected faces UV-connected to this loop.
*/
BLI_assert(!select_faces);
- if (uvedit_face_select_test(scene, l->f, cd_loop_uv_offset)) {
+ if (uvedit_face_select_test(scene, l->f, offsets)) {
/* pass */
}
else {
BMIter liter_other;
BMLoop *l_other;
BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) {
- if ((l != l_other) &&
- !BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) &&
- uvedit_face_select_test(scene, l_other->f, cd_loop_uv_offset)) {
+ if ((l != l_other) && !BM_loop_uv_share_vert_check(l, l_other, offsets.uv) &&
+ uvedit_face_select_test(scene, l_other->f, offsets)) {
add_to_stack = false;
break;
}
@@ -1951,7 +1902,7 @@ static void uv_select_linked_multi(Scene *scene,
}
else {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
found_selected = true;
break;
}
@@ -1970,7 +1921,7 @@ static void uv_select_linked_multi(Scene *scene,
BM_face_select_set(em->bm, efa, value); \
} \
else { \
- uvedit_face_select_set(scene, em->bm, efa, value, false, cd_loop_uv_offset); \
+ uvedit_face_select_set(scene, em->bm, efa, value, false, offsets); \
} \
(void)0
@@ -2011,7 +1962,7 @@ static void uv_select_linked_multi(Scene *scene,
const float *uvedit_first_selected_uv_from_vertex(Scene *scene,
BMVert *eve,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMIter liter;
BMLoop *l;
@@ -2021,9 +1972,9 @@ const float *uvedit_first_selected_uv_from_vertex(Scene *scene,
continue;
}
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- return luv->uv;
+ if (uvedit_uv_select_test(scene, l, offsets)) {
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ return luv;
}
}
@@ -2058,7 +2009,10 @@ static int uv_select_more_less(bContext *C, const bool select)
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (ts->uv_flag & UV_SYNC_SELECTION) {
if (select) {
@@ -2089,15 +2043,14 @@ static int uv_select_more_less(bContext *C, const bool select)
int sel_state = 0;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_VERTSEL) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) {
sel_state |= NEIGHBORING_FACE_IS_SEL;
}
else {
sel_state |= CURR_FACE_IS_UNSEL;
}
- if (!(luv->flag & MLOOPUV_EDGESEL)) {
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
sel_state |= CURR_FACE_IS_UNSEL;
}
@@ -2114,12 +2067,12 @@ static int uv_select_more_less(bContext *C, const bool select)
#undef CURR_FACE_IS_UNSEL
}
else {
- if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (!uvedit_face_select_test(scene, efa, offsets)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
/* Deselect face when at least one of the surrounding faces is not selected */
- if (!uvedit_vert_is_all_other_faces_selected(scene, l, cd_loop_uv_offset)) {
+ if (!uvedit_vert_is_all_other_faces_selected(scene, l, offsets)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
changed = true;
break;
@@ -2143,9 +2096,7 @@ static int uv_select_more_less(bContext *C, const bool select)
if (uvedit_face_visible_test(scene, efa)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
- if (((luv->flag & MLOOPUV_VERTSEL) != 0) == select) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) == select) {
BM_elem_flag_enable(l->next, BM_ELEM_TAG);
BM_elem_flag_enable(l->prev, BM_ELEM_TAG);
changed = true;
@@ -2229,20 +2180,19 @@ bool uvedit_select_is_any_selected(const Scene *scene, Object *obedit)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
if (ts->uv_flag & UV_SYNC_SELECTION) {
return (em->bm->totvertsel || em->bm->totedgesel || em->bm->totfacesel);
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
+
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) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_VERTSEL) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert)) {
return true;
}
}
@@ -2270,16 +2220,18 @@ static void uv_select_all(const Scene *scene, BMEditMesh *em, bool select_all)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- const int uv_select_flags = (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
+
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) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- SET_FLAG_FROM_TEST(luv->flag, select_all, uv_select_flags);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select_all);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select_all);
}
}
}
@@ -2289,27 +2241,30 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em)
const ToolSettings *ts = scene->toolsettings;
BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
char uv_selectmode = ts->uv_selectmode;
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) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (ELEM(uv_selectmode, UV_SELECT_EDGE, UV_SELECT_FACE)) {
- /* Use #MLOOPUV_EDGESEL to flag edges that must be selected. */
- luv->flag ^= MLOOPUV_EDGESEL;
- luv->flag &= ~MLOOPUV_VERTSEL;
+ if ((uv_selectmode == UV_SELECT_EDGE) || (uv_selectmode == UV_SELECT_FACE)) {
+ /* Use UV edge selection to find vertices and edges that must be selected. */
+ bool es = BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, !es);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
}
- /* Use #MLOOPUV_VERTSEL to flag verts that must be selected. */
- else if (ELEM(uv_selectmode, UV_SELECT_VERTEX, UV_SELECT_ISLAND)) {
- luv->flag ^= MLOOPUV_VERTSEL;
- luv->flag &= ~MLOOPUV_EDGESEL;
+ /* Use UV vertex selection to find vertices and edges that must be selected. */
+ else if ((uv_selectmode == UV_SELECT_VERTEX) || (uv_selectmode == UV_SELECT_ISLAND)) {
+ bool vs = BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, !vs);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
}
}
}
@@ -2533,21 +2488,24 @@ static bool uv_mouse_select_multi(bContext *C,
if (found) {
Object *obedit = hit.ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (selectmode == UV_SELECT_FACE) {
- is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset);
+ is_selected = uvedit_face_select_test(scene, hit.efa, offsets);
}
else if (selectmode == UV_SELECT_EDGE) {
- is_selected = uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset);
+ is_selected = uvedit_edge_select_test(scene, hit.l, offsets);
}
else {
/* Vertex or island. For island (if we were using #uv_find_nearest_face_multi_ex, see above),
* `hit.l` is NULL, use `hit.efa` instead. */
if (hit.l != NULL) {
- is_selected = uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset);
+ is_selected = uvedit_uv_select_test(scene, hit.l, offsets);
}
else {
- is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset);
+ is_selected = uvedit_face_select_test(scene, hit.efa, offsets);
}
}
}
@@ -2570,7 +2528,10 @@ static bool uv_mouse_select_multi(bContext *C,
if (found) {
Object *obedit = hit.ob;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (selectmode == UV_SELECT_ISLAND) {
const bool extend = params->sel_op == SEL_OP_ADD;
@@ -2610,17 +2571,15 @@ static bool uv_mouse_select_multi(bContext *C,
}
if (selectmode == UV_SELECT_FACE) {
- uvedit_face_select_set_with_sticky(
- scene, em, hit.efa, select_value, true, cd_loop_uv_offset);
+ uvedit_face_select_set_with_sticky(scene, em, hit.efa, select_value, true, offsets);
flush = 1;
}
else if (selectmode == UV_SELECT_EDGE) {
- uvedit_edge_select_set_with_sticky(
- scene, em, hit.l, select_value, true, cd_loop_uv_offset);
+ uvedit_edge_select_set_with_sticky(scene, em, hit.l, select_value, true, offsets);
flush = 1;
}
else if (selectmode == UV_SELECT_VERTEX) {
- uvedit_uv_select_set_with_sticky(scene, em, hit.l, select_value, true, cd_loop_uv_offset);
+ uvedit_uv_select_set_with_sticky(scene, em, hit.l, select_value, true, offsets);
flush = 1;
}
else {
@@ -3126,7 +3085,6 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
if (ts->uv_flag & UV_SYNC_SELECTION) {
BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled");
@@ -3145,7 +3103,10 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
bool is_sel = false;
@@ -3157,12 +3118,13 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
/* are we all selected? */
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if ((luv->flag & MLOOPUV_VERTSEL) || (luv->flag & MLOOPUV_EDGESEL)) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) ||
+ BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
is_sel = true;
}
- if (!(luv->flag & MLOOPUV_VERTSEL) || !(luv->flag & MLOOPUV_EDGESEL)) {
+ if (!BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_vert) ||
+ !BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
is_unsel = true;
}
@@ -3174,8 +3136,8 @@ static int uv_select_split_exec(bContext *C, wmOperator *op)
if (is_sel && is_unsel) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
}
changed = true;
@@ -3239,12 +3201,12 @@ static void uv_select_flush_from_tag_sticky_loc_internal(const Scene *scene,
const uint efa_index,
BMLoop *l,
const bool select,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
UvMapVert *start_vlist = NULL, *vlist_iter;
BMFace *efa_vlist;
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
vlist_iter = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v));
@@ -3274,7 +3236,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(const Scene *scene,
l_other = BM_iter_at_index(
em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index);
- uvedit_uv_select_set(scene, em->bm, l_other, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l_other, select, false, offsets);
}
vlist_iter = vlist_iter->next;
}
@@ -3303,7 +3265,10 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 &&
ELEM(ts->uv_sticky, SI_STICKY_VERTEX, SI_STICKY_LOC)) {
@@ -3320,17 +3285,16 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, efa_index) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
if (select) {
- luv->flag |= MLOOPUV_EDGESEL;
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
uv_select_flush_from_tag_sticky_loc_internal(
- scene, em, vmap, efa_index, l, select, cd_loop_uv_offset);
+ scene, em, vmap, efa_index, l, select, offsets);
}
else {
- luv->flag &= ~MLOOPUV_EDGESEL;
- if (!uvedit_vert_is_face_select_any_other(scene, l, cd_loop_uv_offset)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
+ if (!uvedit_vert_is_face_select_any_other(scene, l, offsets)) {
uv_select_flush_from_tag_sticky_loc_internal(
- scene, em, vmap, efa_index, l, select, cd_loop_uv_offset);
+ scene, em, vmap, efa_index, l, select, offsets);
}
}
}
@@ -3341,7 +3305,7 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
- uvedit_face_select_set(scene, em->bm, efa, select, false, cd_loop_uv_offset);
+ uvedit_face_select_set(scene, em->bm, efa, select, false, offsets);
}
}
}
@@ -3371,11 +3335,14 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
BMLoop *l;
BMIter iter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) {
/* Tag all verts as untouched, then touch the ones that have a face center
- * in the loop and select all MLoopUV's that use a touched vert. */
+ * in the loop and select all UV's that use a touched vert. */
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -3390,7 +3357,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
}
}
}
@@ -3409,7 +3376,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
uv_select_flush_from_tag_sticky_loc_internal(
- scene, em, vmap, efa_index, l, select, cd_loop_uv_offset);
+ scene, em, vmap, efa_index, l, select, offsets);
}
}
}
@@ -3419,7 +3386,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_flag_test(l, BM_ELEM_TAG)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
}
}
}
@@ -3427,10 +3394,10 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
}
/**
- * Flush the selection from UV edge flags based on sticky modes.
+ * Flush the selection from UV edges based on sticky modes.
*
* Useful when performing edge selections in different sticky modes, since setting the required
- * edge flags (#MLOOPUV_EDGESEL) is done manually or using #uvedit_edge_select_set_noflush,
+ * edge selection is done manually or using #uvedit_edge_select_set_noflush,
* but dealing with sticky modes for vertex selections is best done in a separate function.
*
* \note Current behavior is selecting only; deselecting can be added but the behavior isn't
@@ -3443,15 +3410,18 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh *
BMLoop *l;
BMIter iter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 &&
ELEM(ts->uv_sticky, SI_STICKY_LOC, SI_STICKY_VERTEX)) {
- /* Use the #MLOOPUV_EDGESEL flag to identify which verts must to be selected */
+ /* Use UV edge selection to identify which verts must to be selected */
struct UvVertMap *vmap;
uint efa_index;
/* Clear UV vert flags */
- bm_uv_flag_clear(scene, em->bm, MLOOPUV_VERTSEL, cd_loop_uv_offset);
+ bm_clear_uv_vert_selection(scene, em->bm, offsets);
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
vmap = BM_uv_vert_map_create(em->bm, false, false);
@@ -3465,14 +3435,12 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh *
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
/* Select verts based on UV edge flag. */
- if (luv->flag & MLOOPUV_EDGESEL) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
uv_select_flush_from_tag_sticky_loc_internal(
- scene, em, vmap, efa_index, l, true, cd_loop_uv_offset);
+ scene, em, vmap, efa_index, l, true, offsets);
uv_select_flush_from_tag_sticky_loc_internal(
- scene, em, vmap, efa_index, l->next, true, cd_loop_uv_offset);
+ scene, em, vmap, efa_index, l->next, true, offsets);
}
}
}
@@ -3481,17 +3449,13 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh *
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv, *luv_next, *luv_prev;
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset);
-
- if (luv->flag & MLOOPUV_EDGESEL) {
- luv->flag |= MLOOPUV_VERTSEL;
- luv_next->flag |= MLOOPUV_VERTSEL;
+
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.select_edge)) {
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
+ BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true);
}
- else if (!(luv_prev->flag & MLOOPUV_EDGESEL)) {
- luv->flag &= ~MLOOPUV_VERTSEL;
+ else if (!BM_ELEM_CD_GET_OPT_BOOL(l->prev, offsets.select_edge)) {
+ BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false);
}
}
}
@@ -3514,7 +3478,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
rctf rectf;
bool pinned;
const bool use_face_center = ((ts->uv_flag & UV_SYNC_SELECTION) ?
@@ -3553,7 +3517,10 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* do actual selection */
if (use_face_center && !pinned) {
@@ -3565,7 +3532,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (uvedit_face_visible_test(scene, efa)) {
- BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent);
+ BM_face_uv_calc_center_median(efa, offsets.uv, cent);
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
changed = true;
@@ -3586,13 +3553,12 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
}
BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev;
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset);
+ float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (BLI_rctf_isect_pt_v(&rectf, luv->uv) && BLI_rctf_isect_pt_v(&rectf, luv_prev->uv)) {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_prev, select, false, cd_loop_uv_offset);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (BLI_rctf_isect_pt_v(&rectf, luv) && BLI_rctf_isect_pt_v(&rectf, luv_prev)) {
+ uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
changed = true;
do_second_pass = false;
}
@@ -3609,13 +3575,12 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
continue;
}
BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev;
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset);
+ float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (BLI_rctf_isect_segment(&rectf, luv_prev->uv, luv->uv)) {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_prev, select, false, cd_loop_uv_offset);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (BLI_rctf_isect_segment(&rectf, luv_prev, luv)) {
+ uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
changed = true;
}
l_prev = l;
@@ -3635,19 +3600,19 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
}
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (select != uvedit_uv_select_test(scene, l, offsets)) {
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) {
/* UV_SYNC_SELECTION - can't do pinned selection */
- if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ if (BLI_rctf_isect_pt_v(&rectf, luv)) {
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
}
}
else if (pinned) {
- if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.pin) && BLI_rctf_isect_pt_v(&rectf, luv)) {
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
}
}
@@ -3663,7 +3628,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op)
}
if (ts->uv_sticky == SI_STICKY_VERTEX) {
- uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+ uvedit_vertex_select_tagged(em, scene, select, offsets);
}
}
@@ -3754,7 +3719,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
+ float *luv;
int x, y, radius, width, height;
float zoomx, zoomy;
float offset[2], ellipse[2];
@@ -3804,16 +3769,19 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* do selection */
if (use_face_center) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
/* assume not touched */
- if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (select != uvedit_face_select_test(scene, efa, offsets)) {
float cent[2];
- BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent);
+ BM_face_uv_calc_center_median(efa, offsets.uv, cent);
if (uv_circle_select_is_point_inside(cent, offset, ellipse)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
changed = true;
@@ -3833,13 +3801,12 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
}
BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev;
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset);
+ float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uv_circle_select_is_edge_inside(luv->uv, luv_prev->uv, offset, ellipse)) {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_prev, select, false, cd_loop_uv_offset);
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (uv_circle_select_is_edge_inside(luv, luv_prev, offset, ellipse)) {
+ uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
changed = true;
}
l_prev = l;
@@ -3856,11 +3823,11 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
}
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (uv_circle_select_is_point_inside(luv->uv, offset, ellipse)) {
+ if (select != uvedit_uv_select_test(scene, l, offsets)) {
+ luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (uv_circle_select_is_point_inside(luv, offset, ellipse)) {
changed = true;
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
}
@@ -3876,7 +3843,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op)
}
if (ts->uv_sticky == SI_STICKY_VERTEX) {
- uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+ uvedit_vertex_select_tagged(em, scene, select, offsets);
}
}
@@ -4006,15 +3973,18 @@ static bool do_lasso_select_mesh_uv(bContext *C,
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
if (use_face_center) { /* Face Center Select. */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
/* assume not touched */
- if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (select != uvedit_face_select_test(scene, efa, offsets)) {
float cent[2];
- BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent);
+ BM_face_uv_calc_center_median(efa, offsets.uv, cent);
if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, cent)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
changed = true;
@@ -4035,16 +4005,14 @@ static bool do_lasso_select_mesh_uv(bContext *C,
}
BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev;
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset);
+ float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (do_lasso_select_mesh_uv_is_point_inside(
- region, &rect, mcoords, mcoords_len, luv->uv) &&
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, luv) &&
do_lasso_select_mesh_uv_is_point_inside(
- region, &rect, mcoords, mcoords_len, luv_prev->uv)) {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_prev, select, false, cd_loop_uv_offset);
+ region, &rect, mcoords, mcoords_len, luv_prev)) {
+ uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
do_second_pass = false;
changed = true;
}
@@ -4061,14 +4029,13 @@ static bool do_lasso_select_mesh_uv(bContext *C,
continue;
}
BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev;
- MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset);
+ float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (do_lasso_select_mesh_uv_is_edge_inside(
- region, &rect, mcoords, mcoords_len, luv->uv, luv_prev->uv)) {
- uvedit_edge_select_set_with_sticky(
- scene, em, l_prev, select, false, cd_loop_uv_offset);
+ region, &rect, mcoords, mcoords_len, luv, luv_prev)) {
+ uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets);
changed = true;
}
l_prev = l;
@@ -4086,11 +4053,11 @@ static bool do_lasso_select_mesh_uv(bContext *C,
}
bool has_selected = false;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ if (select != uvedit_uv_select_test(scene, l, offsets)) {
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
if (do_lasso_select_mesh_uv_is_point_inside(
- region, &rect, mcoords, mcoords_len, luv->uv)) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ region, &rect, mcoords, mcoords_len, luv)) {
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
changed = true;
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
has_selected = true;
@@ -4107,7 +4074,7 @@ static bool do_lasso_select_mesh_uv(bContext *C,
}
if (ts->uv_sticky == SI_STICKY_VERTEX) {
- uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
+ uvedit_vertex_select_tagged(em, scene, select, offsets);
}
}
@@ -4188,7 +4155,6 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
@@ -4198,8 +4164,11 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op)
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
bool changed = false;
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, efa)) {
@@ -4207,10 +4176,9 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_PINNED) {
- uvedit_uv_select_enable(scene, em->bm, l, false, cd_loop_uv_offset);
+ if BM_ELEM_CD_GET_OPT_BOOL (l, offsets.pin) {
+ uvedit_uv_select_enable(scene, em->bm, l, false, offsets);
changed = true;
}
}
@@ -4370,7 +4338,7 @@ static int uv_select_overlap(bContext *C, const bool extend)
BMFace *efa;
BMLoop *l;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
/* Triangulate each UV face and store it inside the BVH. */
int face_index;
@@ -4393,8 +4361,8 @@ static int uv_select_overlap(bContext *C, const bool extend)
int vert_index;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, vert_index) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- copy_v2_v2(uv_verts[vert_index], luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ copy_v2_v2(uv_verts[vert_index], luv);
}
BLI_polyfill_calc(uv_verts, face_len, 0, indices);
@@ -4451,20 +4419,26 @@ static int uv_select_overlap(bContext *C, const bool extend)
BMEditMesh *em_b = BKE_editmesh_from_object(obedit_b);
BMFace *face_a = em_a->bm->ftable[o_a->face_index];
BMFace *face_b = em_b->bm->ftable[o_b->face_index];
- const int cd_loop_uv_offset_a = CustomData_get_offset(&em_a->bm->ldata, CD_MLOOPUV);
- const int cd_loop_uv_offset_b = CustomData_get_offset(&em_b->bm->ldata, CD_MLOOPUV);
+ const char *uv_a_name = CustomData_get_active_layer_name(&em_a->bm->ldata, CD_PROP_FLOAT2);
+ const char *uv_b_name = CustomData_get_active_layer_name(&em_b->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em_a->bm, uv_a_name);
+ BM_uv_map_ensure_vert_selection_attribute(em_b->bm, uv_b_name);
+ BM_uv_map_ensure_edge_selection_attribute(em_a->bm, uv_a_name);
+ BM_uv_map_ensure_edge_selection_attribute(em_b->bm, uv_b_name);
+ const BMUVOffsets offsets_a = BM_uv_map_get_offsets(em_a->bm);
+ const BMUVOffsets offsets_b = BM_uv_map_get_offsets(em_b->bm);
/* Skip if both faces are already selected. */
- if (uvedit_face_select_test(scene, face_a, cd_loop_uv_offset_a) &&
- uvedit_face_select_test(scene, face_b, cd_loop_uv_offset_b)) {
+ if (uvedit_face_select_test(scene, face_a, offsets_a) &&
+ uvedit_face_select_test(scene, face_b, offsets_b)) {
continue;
}
/* Main tri-tri overlap test. */
const float endpoint_bias = -1e-4f;
if (overlap_tri_tri_uv_test(o_a->tri, o_b->tri, endpoint_bias)) {
- uvedit_face_select_enable(scene, em_a->bm, face_a, false, cd_loop_uv_offset_a);
- uvedit_face_select_enable(scene, em_b->bm, face_b, false, cd_loop_uv_offset_b);
+ uvedit_face_select_enable(scene, em_a->bm, face_a, false, offsets_a);
+ uvedit_face_select_enable(scene, em_b->bm, face_b, false, offsets_b);
}
}
@@ -4517,8 +4491,8 @@ void UV_OT_select_overlap(wmOperatorType *ot)
static float get_uv_vert_needle(const eUVSelectSimilar type,
BMVert *vert,
const float ob_m3[3][3],
- MLoopUV *luv,
- const int cd_loop_uv_offset)
+ BMLoop *loop,
+ const BMUVOffsets offsets)
{
float result = 0.0f;
switch (type) {
@@ -4526,7 +4500,7 @@ static float get_uv_vert_needle(const eUVSelectSimilar type,
BMFace *f;
BMIter iter;
BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) {
- result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+ result += BM_face_calc_area_uv(f, offsets.uv);
}
} break;
case UV_SSIM_AREA_3D: {
@@ -4544,7 +4518,7 @@ static float get_uv_vert_needle(const eUVSelectSimilar type,
}
} break;
case UV_SSIM_PIN:
- return (luv->flag & MLOOPUV_PINNED) ? 1.0f : 0.0f;
+ return (BM_ELEM_CD_GET_OPT_BOOL(loop, offsets.pin)) ? 1.0f : 0.0f;
default:
BLI_assert_unreachable();
return false;
@@ -4556,9 +4530,9 @@ static float get_uv_vert_needle(const eUVSelectSimilar type,
static float get_uv_edge_needle(const eUVSelectSimilar type,
BMEdge *edge,
const float ob_m3[3][3],
- MLoopUV *luv_a,
- MLoopUV *luv_b,
- const int cd_loop_uv_offset)
+ BMLoop *loop_a,
+ BMLoop *loop_b,
+ const BMUVOffsets offsets)
{
float result = 0.0f;
switch (type) {
@@ -4566,7 +4540,7 @@ static float get_uv_edge_needle(const eUVSelectSimilar type,
BMFace *f;
BMIter iter;
BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) {
- result += BM_face_calc_area_uv(f, cd_loop_uv_offset);
+ result += BM_face_calc_area_uv(f, offsets.uv);
}
} break;
case UV_SSIM_AREA_3D: {
@@ -4576,8 +4550,11 @@ static float get_uv_edge_needle(const eUVSelectSimilar type,
result += BM_face_calc_area_with_mat3(f, ob_m3);
}
} break;
- case UV_SSIM_LENGTH_UV:
- return len_v2v2(luv_a->uv, luv_b->uv);
+ case UV_SSIM_LENGTH_UV: {
+ float *luv_a = BM_ELEM_CD_GET_FLOAT_P(loop_a, offsets.uv);
+ float *luv_b = BM_ELEM_CD_GET_FLOAT_P(loop_b, offsets.uv);
+ return len_v2v2(luv_a, luv_b);
+ } break;
case UV_SSIM_LENGTH_3D:
return len_v3v3(edge->v1->co, edge->v2->co);
case UV_SSIM_SIDES: {
@@ -4588,10 +4565,10 @@ static float get_uv_edge_needle(const eUVSelectSimilar type,
}
} break;
case UV_SSIM_PIN:
- if (luv_a->flag & MLOOPUV_PINNED) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(loop_a, offsets.pin)) {
result += 1.0f;
}
- if (luv_b->flag & MLOOPUV_PINNED) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(loop_b, offsets.pin)) {
result += 1.0f;
}
break;
@@ -4606,12 +4583,12 @@ static float get_uv_edge_needle(const eUVSelectSimilar type,
static float get_uv_face_needle(const eUVSelectSimilar type,
BMFace *face,
const float ob_m3[3][3],
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
float result = 0.0f;
switch (type) {
case UV_SSIM_AREA_UV:
- return BM_face_calc_area_uv(face, cd_loop_uv_offset);
+ return BM_face_calc_area_uv(face, offsets.uv);
case UV_SSIM_AREA_3D:
return BM_face_calc_area_with_mat3(face, ob_m3);
case UV_SSIM_SIDES:
@@ -4620,8 +4597,7 @@ static float get_uv_face_needle(const eUVSelectSimilar type,
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_PINNED) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l, offsets.pin)) {
result += 1.0f;
}
}
@@ -4638,14 +4614,14 @@ static float get_uv_face_needle(const eUVSelectSimilar type,
static float get_uv_island_needle(const eUVSelectSimilar type,
const struct FaceIsland *island,
const float ob_m3[3][3],
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
float result = 0.0f;
switch (type) {
case UV_SSIM_AREA_UV:
for (int i = 0; i < island->faces_len; i++) {
- result += BM_face_calc_area_uv(island->faces[i], cd_loop_uv_offset);
+ result += BM_face_calc_area_uv(island->faces[i], offsets.uv);
}
break;
case UV_SSIM_AREA_3D:
@@ -4703,7 +4679,7 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@@ -4716,11 +4692,10 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
- if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (!uvedit_uv_select_test(scene, l, offsets)) {
continue;
}
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset);
+ float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets);
BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
}
}
@@ -4740,7 +4715,8 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
}
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@@ -4753,14 +4729,13 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
continue; /* Already selected. */
}
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- const float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset);
+ const float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets);
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
if (select) {
- uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_uv_select_set(scene, em->bm, l, select, false, offsets);
changed = true;
}
}
@@ -4816,7 +4791,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@@ -4829,13 +4804,11 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
- if (!uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ if (!uvedit_edge_select_test(scene, l, offsets)) {
continue;
}
- MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset);
+ float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets);
if (tree_1d) {
BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
}
@@ -4857,7 +4830,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
}
bool changed = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@@ -4870,16 +4843,14 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) {
- if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_edge_select_test(scene, l, offsets)) {
continue; /* Already selected. */
}
- MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
- float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset);
+ float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets);
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
if (select) {
- uvedit_edge_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset);
+ uvedit_edge_select_set(scene, em->bm, l, select, false, offsets);
changed = true;
}
}
@@ -4929,7 +4900,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BMFace *face;
BMIter iter;
@@ -4937,11 +4908,11 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
if (!uvedit_face_visible_test(scene, face)) {
continue;
}
- if (!uvedit_face_select_test(scene, face, cd_loop_uv_offset)) {
+ if (!uvedit_face_select_test(scene, face, offsets)) {
continue;
}
- float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset);
+ float needle = get_uv_face_needle(type, face, ob_m3, offsets);
if (tree_1d) {
BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
}
@@ -4960,7 +4931,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
BMesh *bm = em->bm;
bool changed = false;
bool do_history = false;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
float ob_m3[3][3];
copy_m3_m4(ob_m3, ob->object_to_world);
@@ -4971,15 +4942,15 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
if (!uvedit_face_visible_test(scene, face)) {
continue;
}
- if (uvedit_face_select_test(scene, face, cd_loop_uv_offset)) {
+ if (uvedit_face_select_test(scene, face, offsets)) {
continue;
}
- float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset);
+ float needle = get_uv_face_needle(type, face, ob_m3, offsets);
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
if (select) {
- uvedit_face_select_set(scene, em->bm, face, select, do_history, cd_loop_uv_offset);
+ uvedit_face_select_set(scene, bm, face, select, do_history, offsets);
changed = true;
}
}
@@ -4996,7 +4967,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op)
static bool uv_island_selected(const Scene *scene, struct FaceIsland *island)
{
BLI_assert(island && island->faces_len);
- return uvedit_face_select_test(scene, island->faces[0], island->cd_loop_uv_offset);
+ return uvedit_face_select_test(scene, island->faces[0], island->offsets);
}
static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
@@ -5022,20 +4993,14 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if (cd_loop_uv_offset == -1) {
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
+ if (offsets.uv == -1) {
continue;
}
float aspect_y = 1.0f; /* Placeholder value, aspect doesn't change connectivity. */
- island_list_len += bm_mesh_calc_uv_islands(scene,
- em->bm,
- &island_list_ptr[ob_index],
- face_selected,
- false,
- false,
- aspect_y,
- cd_loop_uv_offset);
+ island_list_len += bm_mesh_calc_uv_islands(
+ scene, em->bm, &island_list_ptr[ob_index], face_selected, false, false, aspect_y, offsets);
}
struct FaceIsland **island_array = MEM_callocN(sizeof(*island_array) * island_list_len,
@@ -5047,7 +5012,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
if (cd_loop_uv_offset == -1) {
continue;
}
@@ -5061,7 +5026,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
if (!uv_island_selected(scene, island)) {
continue;
}
- float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset);
+ float needle = get_uv_island_needle(type, island, ob_m3, island->offsets);
if (tree_1d) {
BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle);
}
@@ -5077,7 +5042,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
if (cd_loop_uv_offset == -1) {
continue;
}
@@ -5091,7 +5056,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
if (uv_island_selected(scene, island)) {
continue;
}
- float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset);
+ float needle = get_uv_island_needle(type, island, ob_m3, island->offsets);
bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare);
if (!select) {
continue;
@@ -5099,7 +5064,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op)
bool do_history = false;
for (int j = 0; j < island->faces_len; j++) {
uvedit_face_select_set(
- scene, em->bm, island->faces[j], select, do_history, island->cd_loop_uv_offset);
+ scene, em->bm, island->faces[j], select, do_history, island->offsets);
}
changed = true;
}
@@ -5231,7 +5196,8 @@ void UV_OT_select_similar(wmOperatorType *ot)
BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, int *r_faces_len)
{
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
CLAMP_MAX(len_max, bm->totface);
int faces_len = 0;
BMFace **faces = MEM_mallocN(sizeof(*faces) * len_max, __func__);
@@ -5240,7 +5206,7 @@ BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, in
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (uvedit_face_visible_test(scene, f)) {
- if (uvedit_face_select_test(scene, f, cd_loop_uv_offset)) {
+ if (uvedit_face_select_test(scene, f, offsets)) {
faces[faces_len++] = f;
if (faces_len == len_max) {
goto finally;
@@ -5259,7 +5225,8 @@ finally:
BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, int *r_edges_len)
{
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
CLAMP_MAX(len_max, bm->totloop);
int edges_len = 0;
BMLoop **edges = MEM_mallocN(sizeof(*edges) * len_max, __func__);
@@ -5282,7 +5249,7 @@ BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, in
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
- if (uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) {
+ if (uvedit_edge_select_test(scene, l_iter, offsets)) {
BM_elem_flag_enable(l_iter, BM_ELEM_TAG);
edges[edges_len++] = l_iter;
@@ -5294,7 +5261,7 @@ BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, in
if (l_iter != l_iter->radial_next) {
BMLoop *l_radial_iter = l_iter->radial_next;
do {
- if (BM_loop_uv_share_edge_check(l_iter, l_radial_iter, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_edge_check(l_iter, l_radial_iter, offsets.uv)) {
BM_elem_flag_enable(l_radial_iter, BM_ELEM_TAG);
}
} while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
@@ -5315,7 +5282,8 @@ finally:
BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, int *r_verts_len)
{
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
CLAMP_MAX(len_max, bm->totloop);
int verts_len = 0;
BMLoop **verts = MEM_mallocN(sizeof(*verts) * len_max, __func__);
@@ -5338,8 +5306,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in
BMLoop *l_iter;
BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) {
if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- if (luv->flag & MLOOPUV_VERTSEL) {
+ if (BM_ELEM_CD_GET_OPT_BOOL(l_iter, offsets.select_vert)) {
BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
verts[verts_len++] = l_iter;
@@ -5351,7 +5318,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in
BMIter liter_disk;
BMLoop *l_disk_iter;
BM_ITER_ELEM (l_disk_iter, &liter_disk, l_iter->v, BM_LOOPS_OF_VERT) {
- if (BM_loop_uv_share_vert_check(l_iter, l_disk_iter, cd_loop_uv_offset)) {
+ if (BM_loop_uv_share_vert_check(l_iter, l_disk_iter, offsets.uv)) {
BM_elem_flag_enable(l_disk_iter, BM_ELEM_TAG);
}
}
@@ -5381,7 +5348,7 @@ finally:
*/
static void uv_isolate_selected_islands(const Scene *scene,
BMEditMesh *em,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BLI_assert((scene->toolsettings->uv_flag & UV_SYNC_SELECTION) == 0);
BMFace *efa;
@@ -5403,7 +5370,7 @@ static void uv_isolate_selected_islands(const Scene *scene,
}
BM_elem_flag_enable(efa, BM_ELEM_TAG);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (!uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ if (!uvedit_edge_select_test(scene, l, offsets)) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
is_island_not_selected[element->island] = true;
}
@@ -5419,8 +5386,8 @@ static void uv_isolate_selected_islands(const Scene *scene,
UvElement *element = BM_uv_element_get(elementmap, efa, l);
/* Deselect all elements of islands which are not completely selected. */
if (is_island_not_selected[element->island] == true) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false);
}
}
}
@@ -5435,7 +5402,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
char sticky = ts->uv_sticky;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
@@ -5449,7 +5419,7 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
BM_elem_flag_enable(l, BM_ELEM_TAG);
}
}
@@ -5466,8 +5436,8 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
- uvedit_edge_select_set_noflush(scene, l, true, sticky, cd_loop_uv_offset);
+ if (uvedit_edge_select_test(scene, l, offsets)) {
+ uvedit_edge_select_set_noflush(scene, l, true, sticky, offsets);
}
}
}
@@ -5480,10 +5450,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
if (uvedit_face_visible_test(scene, efa)) {
- if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (uvedit_face_select_test(scene, efa, offsets)) {
BM_elem_flag_enable(efa, BM_ELEM_TAG);
}
- uvedit_face_select_set(scene, em->bm, efa, false, false, cd_loop_uv_offset);
+ uvedit_face_select_set(scene, em->bm, efa, false, false, offsets);
}
}
uv_select_flush_from_tag_face(scene, obedit, true);
@@ -5491,7 +5461,7 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit)
else if (ts->uv_selectmode == UV_SELECT_ISLAND) {
/* Island mode. */
- uv_isolate_selected_islands(scene, em, cd_loop_uv_offset);
+ uv_isolate_selected_islands(scene, em, offsets);
}
ED_uvedit_selectmode_flush(scene, em);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 865262e6947..6be2300cca3 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -322,16 +322,14 @@ static bool stitch_check_uvs_stitchable(UvElement *element,
limit = ssc->limit_dist;
if (ssc->use_limit) {
- MLoopUV *luv, *luv_iter;
BMLoop *l;
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = element_iter->l;
- luv_iter = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv_iter = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
- if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit &&
- fabsf(luv->uv[1] - luv_iter->uv[1]) < limit) {
+ if (fabsf(luv[0] - luv_iter[0]) < limit && fabsf(luv[1] - luv_iter[1]) < limit) {
return 1;
}
return 0;
@@ -355,23 +353,19 @@ static bool stitch_check_edges_stitchable(UvEdge *edge,
if (ssc->use_limit) {
BMLoop *l;
- MLoopUV *luv_orig1, *luv_iter1;
- MLoopUV *luv_orig2, *luv_iter2;
l = state->uvs[edge->uv1]->l;
- luv_orig1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv_orig1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = state->uvs[edge_iter->uv1]->l;
- luv_iter1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv_iter1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = state->uvs[edge->uv2]->l;
- luv_orig2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv_orig2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = state->uvs[edge_iter->uv2]->l;
- luv_iter2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv_iter2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
- if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit &&
- fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit &&
- fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit &&
- fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit) {
+ if (fabsf(luv_orig1[0] - luv_iter1[0]) < limit && fabsf(luv_orig1[1] - luv_iter1[1]) < limit &&
+ fabsf(luv_orig2[0] - luv_iter2[0]) < limit && fabsf(luv_orig2[1] - luv_iter2[1]) < limit) {
return 1;
}
return 0;
@@ -462,18 +456,16 @@ static void stitch_calculate_island_snapping(StitchState *state,
for (j = 0; j < numOfIslandUVs; j++, element++) {
/* stitchable uvs have already been processed, don't process */
if (!(element->flag & STITCH_PROCESSED)) {
- MLoopUV *luv;
BMLoop *l;
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
if (final) {
- stitch_uv_rotate(
- rotation_mat, island_stitch_data[i].medianPoint, luv->uv, state->aspect);
+ stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, luv, state->aspect);
- add_v2_v2(luv->uv, island_stitch_data[i].translation);
+ add_v2_v2(luv, island_stitch_data[i].translation);
}
else {
@@ -511,13 +503,12 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge,
float edgecos, edgesin;
int index1, index2;
float rotation;
- MLoopUV *luv1, *luv2;
element1 = state->uvs[edge->uv1];
element2 = state->uvs[edge->uv2];
- luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV);
- luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV);
+ float *luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_PROP_FLOAT2);
+ float *luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_PROP_FLOAT2);
if (ssc->mode == STITCH_VERT) {
index1 = uvfinal_map[element1 - state->element_map->storage];
@@ -530,8 +521,8 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge,
/* the idea here is to take the directions of the edges and find the rotation between
* final and initial direction. This, using inner and outer vector products,
* gives the angle. Directions are differences so... */
- uv1[0] = luv2->uv[0] - luv1->uv[0];
- uv1[1] = luv2->uv[1] - luv1->uv[1];
+ uv1[0] = luv2[0] - luv1[0];
+ uv1[1] = luv2[1] - luv1[1];
uv1[1] /= state->aspect;
@@ -901,24 +892,23 @@ static void stitch_propagate_uv_final_position(Scene *scene,
BMesh *bm = state->em->bm;
StitchPreviewer *preview = state->stitch_preview;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
if (element->flag & STITCH_STITCHABLE) {
UvElement *element_iter = element;
/* propagate to coincident uvs */
do {
BMLoop *l;
- MLoopUV *luv;
l = element_iter->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
element_iter->flag |= STITCH_PROCESSED;
/* either flush to preview or to the MTFace, if final */
if (final) {
- copy_v2_v2(luv->uv, final_position[index].uv);
+ copy_v2_v2(luv, final_position[index].uv);
- uvedit_uv_select_enable(scene, state->em->bm, l, false, cd_loop_uv_offset);
+ uvedit_uv_select_enable(scene, state->em->bm, l, false, offsets);
}
else {
int face_preview_pos =
@@ -1053,7 +1043,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
*********************************************************************/
if (!final) {
BMLoop *l;
- MLoopUV *luv;
+ float *luv;
int stitchBufferIndex = 0, unstitchBufferIndex = 0;
int preview_size = (ssc->mode == STITCH_VERT) ? 2 : 4;
/* initialize the preview buffers */
@@ -1074,17 +1064,17 @@ static int stitch_process_data(StitchStateContainer *ssc,
UvElement *element = (UvElement *)state->uvs[i];
if (element->flag & STITCH_STITCHABLE) {
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv);
stitchBufferIndex++;
}
else if (element->flag & STITCH_SELECTED) {
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv);
unstitchBufferIndex++;
}
}
@@ -1097,24 +1087,24 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (edge->flag & STITCH_STITCHABLE) {
l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv);
l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv);
stitchBufferIndex++;
BLI_assert(stitchBufferIndex <= preview->num_stitchable);
}
else if (edge->flag & STITCH_SELECTED) {
l = element1->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv);
l = element2->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv);
unstitchBufferIndex++;
BLI_assert(unstitchBufferIndex <= preview->num_unstitchable);
@@ -1152,7 +1142,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (!final) {
BMIter liter;
BMLoop *l;
- MLoopUV *luv;
+ float *luv;
uint buffer_index = 0;
/* initialize the preview buffers */
@@ -1171,7 +1161,7 @@ static int stitch_process_data(StitchStateContainer *ssc,
return 0;
}
- /* copy data from MLoopUVs to the preview display buffers */
+ /* copy data from UVs to the preview display buffers */
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
/* just to test if face was added for processing.
* uvs of unselected vertices will return NULL */
@@ -1184,27 +1174,27 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (face_preview_pos != STITCH_NO_PREVIEW) {
preview->uvs_per_polygon[preview_position[index].polycount_position] = efa->len;
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
- copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv->uv);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
+ copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv);
}
}
/* if this is the static_island on the active object */
if (element->island == ssc->static_island) {
BMLoop *fl = BM_FACE_FIRST_LOOP(efa);
- MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV);
+ float *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_PROP_FLOAT2);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
if (i < numoftris) {
/* using next since the first uv is already accounted for */
BMLoop *lnext = l->next;
- MLoopUV *luvnext = CustomData_bmesh_get(
- &bm->ldata, lnext->next->head.data, CD_MLOOPUV);
- luv = CustomData_bmesh_get(&bm->ldata, lnext->head.data, CD_MLOOPUV);
+ float *luvnext = CustomData_bmesh_get(
+ &bm->ldata, lnext->next->head.data, CD_PROP_FLOAT2);
+ luv = CustomData_bmesh_get(&bm->ldata, lnext->head.data, CD_PROP_FLOAT2);
- memcpy(preview->static_tris + buffer_index, fuv->uv, sizeof(float[2]));
- memcpy(preview->static_tris + buffer_index + 2, luv->uv, sizeof(float[2]));
- memcpy(preview->static_tris + buffer_index + 4, luvnext->uv, sizeof(float[2]));
+ memcpy(preview->static_tris + buffer_index, fuv, sizeof(float[2]));
+ memcpy(preview->static_tris + buffer_index + 2, luv, sizeof(float[2]));
+ memcpy(preview->static_tris + buffer_index + 4, luvnext, sizeof(float[2]));
buffer_index += 6;
}
else {
@@ -1238,14 +1228,14 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l;
- MLoopUV *luv;
+ float *luv;
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
uvfinal_map[element - state->element_map->storage] = i;
- copy_v2_v2(final_position[i].uv, luv->uv);
+ copy_v2_v2(final_position[i].uv, luv);
final_position[i].count = 1;
if (ssc->snap_islands && element->island == ssc->static_island && !stitch_midpoints) {
@@ -1257,16 +1247,16 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (element_iter->separate) {
if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) {
l = element_iter->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
if (stitch_midpoints) {
- add_v2_v2(final_position[i].uv, luv->uv);
+ add_v2_v2(final_position[i].uv, luv);
final_position[i].count++;
}
else if (element_iter->island == ssc->static_island) {
/* if multiple uvs on the static island exist,
* last checked remains. to disambiguate we need to limit or use
* edge stitch */
- copy_v2_v2(final_position[i].uv, luv->uv);
+ copy_v2_v2(final_position[i].uv, luv);
}
}
}
@@ -1281,17 +1271,17 @@ static int stitch_process_data(StitchStateContainer *ssc,
UvEdge *edge = state->selection_stack[i];
if (edge->flag & STITCH_STITCHABLE) {
- MLoopUV *luv2, *luv1;
+ float *luv2, *luv1;
BMLoop *l;
UvEdge *edge_iter;
l = state->uvs[edge->uv1]->l;
- luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = state->uvs[edge->uv2]->l;
- luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
- copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
- copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ copy_v2_v2(final_position[edge->uv1].uv, luv1);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2);
final_position[edge->uv1].count = 1;
final_position[edge->uv2].count = 1;
@@ -1306,19 +1296,19 @@ static int stitch_process_data(StitchStateContainer *ssc,
for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) {
if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) {
l = state->uvs[edge_iter->uv1]->l;
- luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
l = state->uvs[edge_iter->uv2]->l;
- luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
if (stitch_midpoints) {
- add_v2_v2(final_position[edge->uv1].uv, luv1->uv);
+ add_v2_v2(final_position[edge->uv1].uv, luv1);
final_position[edge->uv1].count++;
- add_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ add_v2_v2(final_position[edge->uv2].uv, luv2);
final_position[edge->uv2].count++;
}
else if (edge_iter->element->island == ssc->static_island) {
- copy_v2_v2(final_position[edge->uv1].uv, luv1->uv);
- copy_v2_v2(final_position[edge->uv2].uv, luv2->uv);
+ copy_v2_v2(final_position[edge->uv1].uv, luv1);
+ copy_v2_v2(final_position[edge->uv2].uv, luv2);
}
}
}
@@ -1343,20 +1333,18 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l;
- MLoopUV *luv;
+ float *luv;
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
/* accumulate each islands' translation from stitchable elements.
* It is important to do here because in final pass MTFaces
* get modified and result is zero. */
- island_stitch_data[element->island].translation[0] += final_position[i].uv[0] -
- luv->uv[0];
- island_stitch_data[element->island].translation[1] += final_position[i].uv[1] -
- luv->uv[1];
- island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
- island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv[1];
island_stitch_data[element->island].numOfElements++;
}
}
@@ -1398,20 +1386,18 @@ static int stitch_process_data(StitchStateContainer *ssc,
if (element->flag & STITCH_STITCHABLE) {
BMLoop *l;
- MLoopUV *luv;
+ float *luv;
l = element->l;
- luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV);
+ luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2);
/* accumulate each islands' translation from stitchable elements.
* it is important to do here because in final pass MTFaces
* get modified and result is zero. */
- island_stitch_data[element->island].translation[0] += final_position[i].uv[0] -
- luv->uv[0];
- island_stitch_data[element->island].translation[1] += final_position[i].uv[1] -
- luv->uv[1];
- island_stitch_data[element->island].medianPoint[0] += luv->uv[0];
- island_stitch_data[element->island].medianPoint[1] += luv->uv[1];
+ island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv[0];
+ island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv[1];
+ island_stitch_data[element->island].medianPoint[0] += luv[0];
+ island_stitch_data[element->island].medianPoint[1] += luv[1];
island_stitch_data[element->island].numOfElements++;
}
}
@@ -1645,13 +1631,12 @@ static void stitch_switch_selection_mode_all(StitchStateContainer *ssc)
static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect)
{
BMLoop *l1 = edge->element->l;
- MLoopUV *luv1, *luv2;
float tangent[2];
- luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV);
- luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV);
+ float *luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_PROP_FLOAT2);
+ float *luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_PROP_FLOAT2);
- sub_v2_v2v2(tangent, luv2->uv, luv1->uv);
+ sub_v2_v2v2(tangent, luv2, luv1);
tangent[1] /= aspect;
@@ -1845,7 +1830,7 @@ static StitchState *stitch_init(bContext *C,
float aspx, aspy;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
state = MEM_callocN(sizeof(StitchState), "stitch state obj");
@@ -2076,7 +2061,7 @@ static StitchState *stitch_init(bContext *C,
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
UvElement *element = BM_uv_element_get(state->element_map, efa, l);
if (element) {
stitch_select_uv(element, state, 1);
@@ -2097,7 +2082,7 @@ static StitchState *stitch_init(bContext *C,
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_edge_select_test(scene, l, offsets)) {
UvEdge *edge = uv_edge_get(l, state);
if (edge) {
stitch_select_edge(edge, state, true);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 071f1c44c6b..1924c4c4e65 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -100,9 +100,8 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
BMIter iter;
- int cd_loop_uv_offset;
- if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) {
+ if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) {
ED_mesh_uv_add(obedit->data, NULL, true, true, NULL);
}
@@ -111,7 +110,10 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
return 0;
}
- cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(em->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(em->bm, active_uv_name);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* select new UV's (ignore UV_SYNC_SELECTION in this case) */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
@@ -119,8 +121,8 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true);
}
}
@@ -218,9 +220,9 @@ static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const Unwr
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
- if (cd_loop_uv_offset == -1) {
+ if (offsets.uv == -1) {
return (em->bm->totfacesel != 0);
}
@@ -237,7 +239,7 @@ static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const Unwr
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
break;
}
}
@@ -303,7 +305,7 @@ void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy)
static bool uvedit_is_face_affected(const Scene *scene,
BMFace *efa,
const UnwrapOptions *options,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
return false;
@@ -317,7 +319,7 @@ static bool uvedit_is_face_affected(const Scene *scene,
BMLoop *l;
BMIter iter;
BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) {
- if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
+ if (uvedit_uv_select_test(scene, l, offsets)) {
return true;
}
}
@@ -333,19 +335,19 @@ static void uvedit_prepare_pinned_indices(ParamHandle *handle,
const Scene *scene,
BMFace *efa,
const UnwrapOptions *options,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- bool pin = luv->flag & MLOOPUV_PINNED;
+ bool pin = BM_ELEM_CD_GET_BOOL(l, offsets.pin);
if (options->pin_unselected && !pin) {
- pin = !uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
+ pin = !uvedit_uv_select_test(scene, l, offsets);
}
if (pin) {
int bmvertindex = BM_elem_index_get(l->v);
- GEO_uv_prepare_pin_index(handle, bmvertindex, luv->uv);
+ const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ GEO_uv_prepare_pin_index(handle, bmvertindex, luv);
}
}
}
@@ -355,7 +357,7 @@ static void construct_param_handle_face_add(ParamHandle *handle,
BMFace *efa,
ParamKey face_index,
const UnwrapOptions *options,
- const int cd_loop_uv_offset)
+ const BMUVOffsets offsets)
{
ParamKey *vkeys = BLI_array_alloca(vkeys, efa->len);
bool *pin = BLI_array_alloca(pin, efa->len);
@@ -370,13 +372,13 @@ static void construct_param_handle_face_add(ParamHandle *handle,
/* let parametrizer split the ngon, it can make better decisions
* about which split is best for unwrapping than poly-fill. */
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
- vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv->uv);
+ vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv);
co[i] = l->v->co;
- uv[i] = luv->uv;
- pin[i] = (luv->flag & MLOOPUV_PINNED) != 0;
- select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
+ uv[i] = luv;
+ pin[i] = BM_ELEM_CD_GET_OPT_BOOL(l, offsets.pin);
+ select[i] = uvedit_uv_select_test(scene, l, offsets);
if (options->pin_unselected && !select[i]) {
pin[i] = true;
}
@@ -394,8 +396,8 @@ static void construct_param_edge_set_seams(ParamHandle *handle,
return; /* Seams are not required with these options. */
}
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
- if (cd_loop_uv_offset == -1) {
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+ if (offsets.uv == -1) {
return; /* UVs aren't present on BMesh. Nothing to do. */
}
@@ -412,11 +414,11 @@ static void construct_param_edge_set_seams(ParamHandle *handle,
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, edge, BM_LOOPS_OF_EDGE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, offsets.uv);
ParamKey vkeys[2];
- vkeys[0] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv->uv);
- vkeys[1] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->next->v), luv_next->uv);
+ vkeys[0] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv);
+ vkeys[1] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->next->v), luv_next);
/* Set the seam. */
GEO_uv_parametrizer_edge_set_seam(handle, vkeys);
@@ -452,16 +454,16 @@ static ParamHandle *construct_param_handle(const Scene *scene,
/* we need the vert indices */
BM_mesh_elem_index_ensure(bm, BM_VERT);
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) {
- uvedit_prepare_pinned_indices(handle, scene, efa, options, cd_loop_uv_offset);
+ if (uvedit_is_face_affected(scene, efa, options, offsets)) {
+ uvedit_prepare_pinned_indices(handle, scene, efa, options, offsets);
}
}
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) {
- construct_param_handle_face_add(handle, scene, efa, i, options, cd_loop_uv_offset);
+ if (uvedit_is_face_affected(scene, efa, options, offsets)) {
+ construct_param_handle_face_add(handle, scene, efa, i, options, offsets);
}
}
@@ -509,22 +511,21 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
- if (cd_loop_uv_offset == -1) {
+ if (offsets.uv == -1) {
continue;
}
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) {
- uvedit_prepare_pinned_indices(handle, scene, efa, options, cd_loop_uv_offset);
+ if (uvedit_is_face_affected(scene, efa, options, offsets)) {
+ uvedit_prepare_pinned_indices(handle, scene, efa, options, offsets);
}
}
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) {
- construct_param_handle_face_add(
- handle, scene, efa, i + offset, options, cd_loop_uv_offset);
+ if (uvedit_is_face_affected(scene, efa, options, offsets)) {
+ construct_param_handle_face_add(handle, scene, efa, i + offset, options, offsets);
}
}
@@ -539,7 +540,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene,
}
static void texface_from_original_index(const Scene *scene,
- const int cd_loop_uv_offset,
+ const BMUVOffsets offsets,
BMFace *efa,
int index,
float **r_uv,
@@ -548,7 +549,6 @@ static void texface_from_original_index(const Scene *scene,
{
BMLoop *l;
BMIter liter;
- MLoopUV *luv;
*r_uv = NULL;
*r_pin = 0;
@@ -560,10 +560,10 @@ static void texface_from_original_index(const Scene *scene,
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (BM_elem_index_get(l->v) == index) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- *r_uv = luv->uv;
- *r_pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0;
- *r_select = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ *r_uv = luv;
+ *r_pin = BM_ELEM_CD_GET_OPT_BOOL(l, offsets.pin);
+ *r_select = uvedit_uv_select_test(scene, l, offsets);
break;
}
}
@@ -609,7 +609,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
/* similar to the above, we need a way to map edges to their original ones */
BMEdge **edgeMap;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
ParamHandle *handle = GEO_uv_parametrizer_construct_begin();
@@ -711,34 +711,14 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene,
/* This is where all the magic is done.
* If the vertex exists in the, we pass the original uv pointer to the solver, thus
* flushing the solution to the edit mesh. */
- texface_from_original_index(scene,
- cd_loop_uv_offset,
- origFace,
- origVertIndices[mloop[0].v],
- &uv[0],
- &pin[0],
- &select[0]);
- texface_from_original_index(scene,
- cd_loop_uv_offset,
- origFace,
- origVertIndices[mloop[1].v],
- &uv[1],
- &pin[1],
- &select[1]);
- texface_from_original_index(scene,
- cd_loop_uv_offset,
- origFace,
- origVertIndices[mloop[2].v],
- &uv[2],
- &pin[2],
- &select[2]);
- texface_from_original_index(scene,
- cd_loop_uv_offset,
- origFace,
- origVertIndices[mloop[3].v],
- &uv[3],
- &pin[3],
- &select[3]);
+ texface_from_original_index(
+ scene, offsets, origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0]);
+ texface_from_original_index(
+ scene, offsets, origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1]);
+ texface_from_original_index(
+ scene, offsets, origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2]);
+ texface_from_original_index(
+ scene, offsets, origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3]);
GEO_uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select);
}
@@ -1569,21 +1549,21 @@ static void shrink_loop_uv_by_aspect_ratio(BMFace *efa,
BMLoop *l;
BMIter iter;
BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
if (aspect_y > 1.0f) {
/* Reduce round-off error, i.e. `u = (u - 0.5) / aspect_y + 0.5`. */
- luv->uv[0] = luv->uv[0] / aspect_y + (0.5f - 0.5f / aspect_y);
+ luv[0] = luv[0] / aspect_y + (0.5f - 0.5f / aspect_y);
}
else {
/* Reduce round-off error, i.e. `v = (v - 0.5) * aspect_y + 0.5`. */
- luv->uv[1] = luv->uv[1] * aspect_y + (0.5f - 0.5f * aspect_y);
+ luv[1] = luv[1] * aspect_y + (0.5f - 0.5f * aspect_y);
}
}
}
static void correct_uv_aspect(Object *ob, BMEditMesh *em)
{
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
float aspx, aspy;
ED_uvedit_get_aspect(ob, &aspx, &aspy);
const float aspect_y = aspx / aspy;
@@ -1612,7 +1592,7 @@ static void correct_uv_aspect_per_face(Object *ob, BMEditMesh *em)
/* Lazily initialize aspect ratio for materials. */
copy_vn_fl(material_aspect_y, materials_num, -1.0f);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BMFace *efa;
BMIter iter;
@@ -1701,7 +1681,6 @@ static void uv_map_clip_correct(const Scene *scene,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
float dx, dy, min[2], max[2];
const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect");
const bool clip_to_bounds = (RNA_struct_find_property(op->ptr, "clip_to_bounds") &&
@@ -1714,7 +1693,7 @@ static void uv_map_clip_correct(const Scene *scene,
Object *ob = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
/* Correct for image aspect ratio. */
if (correct_aspect) {
@@ -1733,13 +1712,13 @@ static void uv_map_clip_correct(const Scene *scene,
continue;
}
- if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- minmax_v2v2_v2(min, max, luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ minmax_v2v2_v2(min, max, luv);
}
}
}
@@ -1750,13 +1729,13 @@ static void uv_map_clip_correct(const Scene *scene,
continue;
}
- if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- clamp_v2(luv->uv, 0.0f, 1.0f);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ clamp_v2(luv, 0.0f, 1.0f);
}
}
}
@@ -1783,22 +1762,22 @@ static void uv_map_clip_correct(const Scene *scene,
Object *ob = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
continue;
}
- if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
+ if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
- luv->uv[0] = (luv->uv[0] - min[0]) * dx;
- luv->uv[1] = (luv->uv[1] - min[1]) * dy;
+ luv[0] = (luv[0] - min[0]) * dx;
+ luv[1] = (luv[1] - min[1]) * dy;
}
}
}
@@ -1818,7 +1797,7 @@ static void uvedit_unwrap(const Scene *scene,
UnwrapResultInfo *result_info)
{
BMEditMesh *em = BKE_editmesh_from_object(obedit);
- if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) {
return;
}
@@ -2284,8 +2263,8 @@ static int smart_project_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- BLI_assert(cd_loop_uv_offset >= 0);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
+ BLI_assert(offsets.uv >= 0);
ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__);
uint thick_faces_len = 0;
@@ -2295,8 +2274,8 @@ static int smart_project_exec(bContext *C, wmOperator *op)
}
if (only_selected_uvs) {
- if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ if (!uvedit_face_select_test(scene, efa, offsets)) {
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
continue;
}
}
@@ -2316,8 +2295,8 @@ static int smart_project_exec(bContext *C, wmOperator *op)
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- zero_v2(luv->uv);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ zero_v2(luv);
changed = true;
}
@@ -2377,8 +2356,8 @@ static int smart_project_exec(bContext *C, wmOperator *op)
BMIter liter;
BMLoop *l;
BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) {
- MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- mul_v2_m3v3(luv->uv, axis_mat, l->v->co);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ mul_v2_m3v3(luv, axis_mat, l->v->co);
}
changed = true;
}
@@ -2521,7 +2500,6 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
float rotmat[4][4];
float objects_pos_offset[4];
bool changed_multi = false;
@@ -2555,7 +2533,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
if (use_orthographic) {
uv_map_rotation_matrix_ex(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f, objects_pos_offset);
@@ -2566,8 +2544,8 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ BLI_uvproject_from_view_ortho(luv, l->v->co, rotmat);
}
changed = true;
}
@@ -2587,8 +2565,8 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- BLI_uvproject_from_camera(luv->uv, l->v->co, uci);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ BLI_uvproject_from_camera(luv, l->v->co, uci);
}
changed = true;
}
@@ -2605,9 +2583,9 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
BLI_uvproject_from_view(
- luv->uv, l->v->co, rv3d->persmat, rotmat, region->winx, region->winy);
+ luv, l->v->co, rv3d->persmat, rotmat, region->winx, region->winy);
}
changed = true;
}
@@ -2755,16 +2733,15 @@ static void uv_map_mirror(BMEditMesh *em, BMFace *efa)
{
BMLoop *l;
BMIter liter;
- MLoopUV *luv;
float **uvs = BLI_array_alloca(uvs, efa->len);
float dx;
int i, mi;
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- uvs[i] = luv->uv;
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
+ uvs[i] = luv;
}
mi = 0;
@@ -2805,7 +2782,6 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
if (em->bm->totfacesel == 0) {
continue;
@@ -2816,7 +2792,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
float center[3], rotmat[4][4];
uv_map_transform(C, op, rotmat);
@@ -2828,16 +2804,15 @@ static int sphere_project_exec(bContext *C, wmOperator *op)
}
if (only_selected_uvs) {
- if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ if (!uvedit_face_select_test(scene, efa, offsets)) {
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
continue;
}
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-
- uv_sphere_project(luv->uv, l->v->co, center, rotmat);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ uv_sphere_project(luv, l->v->co, center, rotmat);
}
uv_map_mirror(em, efa);
@@ -2917,7 +2892,6 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
if (em->bm->totfacesel == 0) {
continue;
@@ -2928,7 +2902,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
continue;
}
- const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
float center[3], rotmat[4][4];
uv_map_transform(C, op, rotmat);
@@ -2939,14 +2913,14 @@ static int cylinder_project_exec(bContext *C, wmOperator *op)
continue;
}
- if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
- uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset);
+ if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) {
+ uvedit_face_select_disable(scene, em->bm, efa, offsets);
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- uv_cylinder_project(luv->uv, l->v->co, center, rotmat);
+ float *luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv);
+ uv_cylinder_project(luv, l->v->co, center, rotmat);
}
uv_map_mirror(em, efa);
@@ -2997,13 +2971,10 @@ static void uvedit_unwrap_cube_project(const Scene *scene,
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
- MLoopUV *luv;
float loc[3];
int cox, coy;
- int cd_loop_uv_offset;
-
- cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
if (center) {
copy_v3_v3(loc, center);
@@ -3023,17 +2994,17 @@ static void uvedit_unwrap_cube_project(const Scene *scene,
if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
continue;
}
- if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
- uvedit_face_select_disable(scene, bm, efa, cd_loop_uv_offset);
+ if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) {
+ uvedit_face_select_disable(scene, bm, efa, offsets);
continue;
}
axis_dominant_v3(&cox, &coy, efa->no);
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- luv->uv[0] = 0.5f + ((l->v->co[cox] - loc[cox]) / cube_size);
- luv->uv[1] = 0.5f + ((l->v->co[coy] - loc[coy]) / cube_size);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ luv[0] = 0.5f + ((l->v->co[cox] - loc[cox]) / cube_size);
+ luv[1] = 0.5f + ((l->v->co[coy] - loc[coy]) / cube_size);
}
}
}
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index 64e7be5169c..2a00f7e88c5 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -43,6 +43,7 @@
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math_color.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
@@ -587,18 +588,18 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, mesh->totloop);
int *material_indices = (int *)CustomData_add_layer_named(
&mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, mesh->totpoly, "material_index");
- MLoopUV *loopsuv[2] = {nullptr};
+ blender::float2 *loopsuv[2] = {nullptr};
if (hasTex) {
// First UV layer
- loopsuv[0] = static_cast<MLoopUV *>(CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0]));
- CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0);
+ loopsuv[0] = static_cast<blender::float2 *>(CustomData_add_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0]));
+ CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 0);
// Second UV layer
- loopsuv[1] = static_cast<MLoopUV *>(CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1]));
- CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1);
+ loopsuv[1] = static_cast<blender::float2 *>(CustomData_add_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1]));
+ CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 1);
}
// colors and transparency (the latter represented by grayscale colors)
@@ -744,24 +745,24 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
// Second UV layer (loopsuv[1]) has tips: (texCoord(1)).
for (int L = 0; L < 2; L++) {
if (is_odd) {
- loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
- loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+ loopsuv[L][0][0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0][1] = svRep[2]->texCoord(L).y();
- loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x();
- loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y();
+ loopsuv[L][1][0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][1][1] = svRep[0]->texCoord(L).y();
- loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x();
- loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y();
+ loopsuv[L][2][0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][2][1] = svRep[1]->texCoord(L).y();
}
else {
- loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x();
- loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y();
+ loopsuv[L][0][0] = svRep[2]->texCoord(L).x();
+ loopsuv[L][0][1] = svRep[2]->texCoord(L).y();
- loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x();
- loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y();
+ loopsuv[L][1][0] = svRep[1]->texCoord(L).x();
+ loopsuv[L][1][1] = svRep[1]->texCoord(L).y();
- loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x();
- loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y();
+ loopsuv[L][2][0] = svRep[0]->texCoord(L).x();
+ loopsuv[L][2][1] = svRep[0]->texCoord(L).y();
}
loopsuv[L] += 3;
}
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 3dad2a1a19a..ce70c60c04e 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -301,7 +301,7 @@ void GPU_pass_cache_free(void);
typedef struct GPUMaterialAttribute {
struct GPUMaterialAttribute *next, *prev;
int type; /* eCustomDataType */
- char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ char name[68]; /* MAX_CUSTOMDATA_LAYER_NAME */
char input_name[12 + 1]; /* GPU_MAX_SAFE_ATTR_NAME + 1 */
eGPUType gputype;
eGPUDefaultValue default_value; /* Only for volumes attributes. */
@@ -335,8 +335,8 @@ typedef struct GPUUniformAttr {
struct GPUUniformAttr *next, *prev;
/* Meaningful part of the attribute set key. */
- char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
- /** Hash of name[64] + use_dupli. */
+ char name[68]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ /** Hash of name[68] + use_dupli. */
uint32_t hash_code;
bool use_dupli;
diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc
index 76d95ac1b55..fb480326def 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.cc
+++ b/source/blender/gpu/intern/gpu_vertex_format.cc
@@ -199,7 +199,7 @@ void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count)
for (int i = 0; i < attr_len; i++, attr++) {
const char *attr_name = GPU_vertformat_attr_name_get(format, attr, 0);
for (int j = 1; j < load_count; j++) {
- char load_name[64];
+ char load_name[68 /* MAX_CUSTOMDATA_LAYER_NAME */];
BLI_snprintf(load_name, sizeof(load_name), "%s%d", attr_name, j);
GPUVertAttr *dst_attr = &format->attrs[format->attr_len++];
*dst_attr = *attr;
diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
index 084d26198bc..2f66e246ab1 100644
--- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc
@@ -240,8 +240,10 @@ void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
mesh_sample.setUVs(uv_sample);
}
- write_custom_data(
- abc_poly_mesh_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
+ write_custom_data(abc_poly_mesh_schema_.getArbGeomParams(),
+ m_custom_data_config,
+ &mesh->ldata,
+ CD_PROP_FLOAT2);
}
if (args_.export_params->normals) {
@@ -307,7 +309,7 @@ void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *me
}
write_custom_data(
- abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV);
+ abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_PROP_FLOAT2);
}
if (args_.export_params->orcos) {
diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc
index 3349f9fc30b..0302325a36e 100644
--- a/source/blender/io/alembic/intern/abc_customdata.cc
+++ b/source/blender/io/alembic/intern/abc_customdata.cc
@@ -50,7 +50,7 @@ static void get_uvs(const CDStreamConfig &config,
std::vector<uint32_t> &uvidx,
const void *cd_data)
{
- const MLoopUV *mloopuv_array = static_cast<const MLoopUV *>(cd_data);
+ const float2 *mloopuv_array = static_cast<const float2 *>(cd_data);
if (!mloopuv_array) {
return;
@@ -68,14 +68,14 @@ static void get_uvs(const CDStreamConfig &config,
/* Iterate in reverse order to match exported polygons. */
for (int i = 0; i < num_poly; i++) {
MPoly &current_poly = mpoly[i];
- const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+ const float2 *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; j++, count++) {
loopuv--;
uvidx[count] = count;
- uvs[count][0] = loopuv->uv[0];
- uvs[count][1] = loopuv->uv[1];
+ uvs[count][0] = (*loopuv)[0];
+ uvs[count][1] = (*loopuv)[1];
}
}
}
@@ -87,13 +87,13 @@ static void get_uvs(const CDStreamConfig &config,
for (int i = 0; i < num_poly; i++) {
MPoly &current_poly = mpoly[i];
MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop;
- const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
+ const float2 *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop;
for (int j = 0; j < current_poly.totloop; j++) {
looppoly--;
loopuv--;
- Imath::V2f uv(loopuv->uv[0], loopuv->uv[1]);
+ Imath::V2f uv((*loopuv)[0], (*loopuv)[1]);
bool found_same = false;
/* Find UV already in uvs array. */
@@ -119,17 +119,17 @@ static void get_uvs(const CDStreamConfig &config,
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
{
- const int active_uvlayer = CustomData_get_active_layer(data, CD_MLOOPUV);
+ const int active_uvlayer = CustomData_get_active_layer(data, CD_PROP_FLOAT2);
if (active_uvlayer < 0) {
return "";
}
- const void *cd_data = CustomData_get_layer_n(data, CD_MLOOPUV, active_uvlayer);
+ const void *cd_data = CustomData_get_layer_n(data, CD_PROP_FLOAT2, active_uvlayer);
get_uvs(config, sample.uvs, sample.indices, cd_data);
- return CustomData_get_layer_name(data, CD_MLOOPUV, active_uvlayer);
+ return CustomData_get_layer_name(data, CD_PROP_FLOAT2, active_uvlayer);
}
/* Convention to write UVs:
@@ -286,7 +286,7 @@ void write_custom_data(const OCompoundProperty &prop,
const void *cd_data = CustomData_get_layer_n(data, cd_data_type, i);
const char *name = CustomData_get_layer_name(data, cd_data_type, i);
- if (cd_data_type == CD_MLOOPUV) {
+ if (cd_data_type == CD_PROP_FLOAT2) {
/* Already exported. */
if (i == active_layer) {
continue;
@@ -320,7 +320,7 @@ static void read_uvs(const CDStreamConfig &config,
{
MPoly *mpolys = config.mpoly;
MLoop *mloops = config.mloop;
- MLoopUV *mloopuvs = static_cast<MLoopUV *>(data);
+ float2 *mloopuvs = static_cast<float2 *>(data);
uint uv_index, loop_index, rev_loop_index;
@@ -337,9 +337,9 @@ static void read_uvs(const CDStreamConfig &config,
uv_index = (*indices)[loop_index];
const Imath::V2f &uv = (*uvs)[uv_index];
- MLoopUV &loopuv = mloopuvs[rev_loop_index];
- loopuv.uv[0] = uv[0];
- loopuv.uv[1] = uv[1];
+ float2 &loopuv = mloopuvs[rev_loop_index];
+ loopuv[0] = uv[0];
+ loopuv[1] = uv[1];
}
}
}
@@ -500,7 +500,8 @@ static void read_custom_data_uvs(const ICompoundProperty &prop,
return;
}
- void *cd_data = config.add_customdata_cb(config.mesh, prop_header.getName().c_str(), CD_MLOOPUV);
+ void *cd_data = config.add_customdata_cb(
+ config.mesh, prop_header.getName().c_str(), CD_PROP_FLOAT2);
read_uvs(config, cd_data, uv_scope, sample.getVals(), uvs_indices);
}
diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h
index 0ddba866016..203ae16fd4b 100644
--- a/source/blender/io/alembic/intern/abc_customdata.h
+++ b/source/blender/io/alembic/intern/abc_customdata.h
@@ -11,9 +11,10 @@
#include <map>
+#include "BLI_math_vec_types.hh"
+
struct CustomData;
struct MLoop;
-struct MLoopUV;
struct MPoly;
struct MVert;
struct Mesh;
@@ -37,7 +38,7 @@ struct CDStreamConfig {
MVert *mvert;
int totvert;
- MLoopUV *mloopuv;
+ float2 *mloopuv;
CustomData *loopdata;
diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc
index 2531bd62609..6aa29aaf974 100644
--- a/source/blender/io/alembic/intern/abc_reader_mesh.cc
+++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc
@@ -176,7 +176,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
{
MPoly *mpolys = config.mpoly;
MLoop *mloops = config.mloop;
- MLoopUV *mloopuvs = config.mloopuv;
+ float2 *mloopuvs = config.mloopuv;
const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
@@ -220,7 +220,6 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
last_vertex_index = loop.v;
if (do_uvs) {
- MLoopUV &loopuv = mloopuvs[rev_loop_index];
uv_index = (*uvs_indices)[do_uvs_per_loop ? loop_index : loop.v];
/* Some Alembic files are broken (or at least export UVs in a way we don't expect). */
@@ -228,8 +227,8 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
continue;
}
- loopuv.uv[0] = (*uvs)[uv_index][0];
- loopuv.uv[1] = (*uvs)[uv_index][1];
+ mloopuvs[rev_loop_index][0] = (*uvs)[uv_index][0];
+ mloopuvs[rev_loop_index][1] = (*uvs)[uv_index][1];
}
}
}
@@ -371,8 +370,8 @@ BLI_INLINE void read_uvs_params(CDStreamConfig &config,
name = uv.getName();
}
- void *cd_ptr = config.add_customdata_cb(config.mesh, name.c_str(), CD_MLOOPUV);
- config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
+ void *cd_ptr = config.add_customdata_cb(config.mesh, name.c_str(), CD_PROP_FLOAT2);
+ config.mloopuv = static_cast<float2 *>(cd_ptr);
}
static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
@@ -380,7 +379,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type)
eCustomDataType cd_data_type = static_cast<eCustomDataType>(data_type);
/* unsupported custom data type -- don't do anything. */
- if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) {
+ if (!ELEM(cd_data_type, CD_PROP_FLOAT2, CD_PROP_BYTE_COLOR)) {
return nullptr;
}
diff --git a/source/blender/io/collada/EffectExporter.cpp b/source/blender/io/collada/EffectExporter.cpp
index e8a715633e1..d53f8c0997c 100644
--- a/source/blender/io/collada/EffectExporter.cpp
+++ b/source/blender/io/collada/EffectExporter.cpp
@@ -29,9 +29,9 @@ static std::string getActiveUVLayerName(Object *ob)
{
Mesh *me = (Mesh *)ob->data;
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (num_layers) {
- return std::string(bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV));
+ return std::string(bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2));
}
return "";
diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp
index f6f9026481c..44f52dc797c 100644
--- a/source/blender/io/collada/GeometryExporter.cpp
+++ b/source/blender/io/collada/GeometryExporter.cpp
@@ -15,6 +15,7 @@
#include "DNA_meshdata_types.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_utildefines.h"
#include "BKE_attribute.hh"
@@ -77,7 +78,7 @@ void GeometryExporter::operator()(Object *ob)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -160,7 +161,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
/* writes <source> for normal coords */
createNormalsSource(geom_id, me, nor);
- bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
+ bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2));
/* writes <source> for uv coords if mesh has uv coords */
if (has_uvs) {
@@ -363,13 +364,12 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
til.push_back(normals_input);
/* if mesh has uv coords writes <input> for TEXCOORD */
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
- int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
+ int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2);
for (int i = 0; i < num_layers; i++) {
- int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i);
+ int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, i);
if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) {
- // char *name = CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, i);
COLLADASW::Input texcoord_input(
COLLADASW::InputSemantic::TEXCOORD,
makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())),
@@ -532,15 +532,16 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
int totuv = me->totloop;
const Span<MPoly> polys = me->polys();
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
/* write <source> for each layer
* each <source> will get id like meshName + "map-channel-1" */
- int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2);
for (int a = 0; a < num_layers; a++) {
- int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a);
+ int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, a);
if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) {
- MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
+ const blender::float2 *uv_map = static_cast<const blender::float2 *>(
+ CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a));
COLLADASW::FloatSourceF source(mSW);
std::string layer_id = makeTexcoordSourceId(
@@ -558,9 +559,9 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
for (const int i : polys.index_range()) {
const MPoly *mpoly = &polys[i];
- MLoopUV *mloop = mloops + mpoly->loopstart;
+ const blender::float2 *mloop = uv_map + mpoly->loopstart;
for (int j = 0; j < mpoly->totloop; j++) {
- source.appendValues(mloop[j].uv[0], mloop[j].uv[1]);
+ source.appendValues(mloop[j][0], mloop[j][1]);
}
}
diff --git a/source/blender/io/collada/InstanceWriter.cpp b/source/blender/io/collada/InstanceWriter.cpp
index d88f24b8e8b..76ada0be099 100644
--- a/source/blender/io/collada/InstanceWriter.cpp
+++ b/source/blender/io/collada/InstanceWriter.cpp
@@ -38,13 +38,13 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial &bind_materia
// create <bind_vertex_input> for each uv map
Mesh *me = (Mesh *)ob->data;
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
int map_index = 0;
- int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2);
for (int b = 0; b < num_layers; b++) {
if (!active_uv_only || b == active_uv_index) {
- char *name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, b);
+ char *name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, b);
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++));
}
}
diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp
index 1a28adf50a5..b05b26e618c 100644
--- a/source/blender/io/collada/MeshImporter.cpp
+++ b/source/blender/io/collada/MeshImporter.cpp
@@ -244,7 +244,7 @@ void MeshImporter::set_vcol(MLoopCol *mloopcol,
}
}
-void MeshImporter::set_face_uv(MLoopUV *mloopuv,
+void MeshImporter::set_face_uv(blender::float2 *mloopuv,
UVDataWrapper &uvs,
int start_index,
COLLADAFW::IndexList &index_list,
@@ -255,7 +255,7 @@ void MeshImporter::set_face_uv(MLoopUV *mloopuv,
for (int index = 0; index < count; index++) {
int uv_index = indices[index + start_index];
- uvs.getUV(uv_index, mloopuv[index].uv);
+ uvs.getUV(uv_index, mloopuv[index]);
}
}
@@ -471,10 +471,10 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
COLLADAFW::String &uvname = info->mName;
/* Allocate space for UV_data */
CustomData_add_layer_named(
- &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str());
+ &me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str());
}
/* activate the first uv map */
- CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, 0);
+ CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, 0);
}
int totcolset = collada_mesh->getColors().getInputInfosArray().getCount();
@@ -717,8 +717,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
uvset_index++) {
/* get mtface by face index and uv set index */
COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index];
- MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_named(
- &me->ldata, CD_MLOOPUV, index_list.getName().c_str());
+ blender::float2 *mloopuv = static_cast<blender::float2 *>(CustomData_get_layer_named(
+ &me->ldata, CD_PROP_FLOAT2, index_list.getName().c_str()));
if (mloopuv == nullptr) {
fprintf(stderr,
"Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n",
diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h
index a59b24d4f24..2fd880cc46d 100644
--- a/source/blender/io/collada/MeshImporter.h
+++ b/source/blender/io/collada/MeshImporter.h
@@ -95,7 +95,7 @@ class MeshImporter : public MeshImporterBase {
bool set_poly_indices(
MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count);
- void set_face_uv(MLoopUV *mloopuv,
+ void set_face_uv(blender::float2 *mloopuv,
UVDataWrapper &uvs,
int start_index,
COLLADAFW::IndexList &index_list,
diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp
index 96ff78a715a..8a093e0c5e1 100644
--- a/source/blender/io/collada/collada_utils.cpp
+++ b/source/blender/io/collada/collada_utils.cpp
@@ -322,7 +322,7 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
int bc_get_active_UVLayer(Object *ob)
{
Mesh *me = (Mesh *)ob->data;
- return CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
+ return CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2);
}
std::string bc_url_encode(std::string data)
@@ -1071,9 +1071,9 @@ void bc_copy_m4d_v44(double (&r)[4][4], std::vector<std::vector<double>> &a)
*/
static std::string bc_get_active_uvlayer_name(Mesh *me)
{
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (num_layers) {
- char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV);
+ char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2);
if (layer_name) {
return std::string(layer_name);
}
@@ -1096,9 +1096,9 @@ static std::string bc_get_active_uvlayer_name(Object *ob)
*/
static std::string bc_get_uvlayer_name(Mesh *me, int layer)
{
- int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2);
if (num_layers && layer < num_layers) {
- char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, layer);
+ char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, layer);
if (layer_name) {
return std::string(layer_name);
}
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 8138f38fcad..adfaff41dd7 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -199,7 +199,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type
int numloops;
/* unsupported custom data type -- don't do anything. */
- if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) {
+ if (!ELEM(cd_data_type, CD_PROP_FLOAT2, CD_PROP_BYTE_COLOR)) {
return nullptr;
}
@@ -364,7 +364,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
const CustomDataLayer *layer = &ldata->layers[layer_idx];
std::string layer_name = std::string(layer->name);
- if (layer->type != CD_MLOOPUV) {
+ if (layer->type != CD_PROP_FLOAT2) {
continue;
}
@@ -411,7 +411,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
const CustomDataLayer *layer = &ldata->layers[layer_idx];
- if (layer->type != CD_MLOOPUV) {
+ if (layer->type != CD_PROP_FLOAT2) {
continue;
}
@@ -446,15 +446,15 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
continue;
}
- MLoopUV *mloopuv = static_cast<MLoopUV *>(layer->data);
+ float2 *mloopuv = static_cast<float2 *>(layer->data);
if (is_left_handed_) {
uv_index = rev_loop_index;
}
else {
uv_index = loop_index;
}
- mloopuv[uv_index].uv[0] = sample.uvs[usd_uv_index][0];
- mloopuv[uv_index].uv[1] = sample.uvs[usd_uv_index][1];
+ mloopuv[uv_index][0] = sample.uvs[usd_uv_index][0];
+ mloopuv[uv_index][1] = sample.uvs[usd_uv_index][1];
}
}
}
@@ -906,7 +906,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
existing_mesh, positions_.size(), 0, 0, face_indices_.size(), face_counts_.size());
for (pxr::TfToken token : uv_tokens) {
- add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV);
+ add_customdata_cb(active_mesh, token.GetText(), CD_PROP_FLOAT2);
}
}
diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc
index 2be9b1c065a..f4ae9d20e52 100644
--- a/source/blender/io/usd/intern/usd_writer_abstract.cc
+++ b/source/blender/io/usd/intern/usd_writer_abstract.cc
@@ -30,7 +30,7 @@ static std::string get_mesh_active_uvlayer_name(const Object *ob)
const Mesh *me = static_cast<Mesh *>(ob->data);
- const char *name = CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV);
+ const char *name = CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2);
return name ? name : "";
}
diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc
index e7d79e888e4..8b47da4fc00 100644
--- a/source/blender/io/usd/intern/usd_writer_mesh.cc
+++ b/source/blender/io/usd/intern/usd_writer_mesh.cc
@@ -9,6 +9,7 @@
#include <pxr/usd/usdShade/materialBindingAPI.h>
#include "BLI_assert.h"
+#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.h"
#include "BKE_attribute.h"
@@ -113,7 +114,7 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_
const CustomData *ldata = &mesh->ldata;
for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) {
const CustomDataLayer *layer = &ldata->layers[layer_idx];
- if (layer->type != CD_MLOOPUV) {
+ if (layer->type != CD_PROP_FLOAT2) {
continue;
}
@@ -125,10 +126,10 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_
pxr::UsdGeomPrimvar uv_coords_primvar = primvarsAPI.CreatePrimvar(
primvar_name, pxr::SdfValueTypeNames->TexCoord2fArray, pxr::UsdGeomTokens->faceVarying);
- MLoopUV *mloopuv = static_cast<MLoopUV *>(layer->data);
+ const float2 *mloopuv = static_cast<const float2 *>(layer->data);
pxr::VtArray<pxr::GfVec2f> uv_coords;
for (int loop_idx = 0; loop_idx < mesh->totloop; loop_idx++) {
- uv_coords.push_back(pxr::GfVec2f(mloopuv[loop_idx].uv));
+ uv_coords.push_back(pxr::GfVec2f((const float *)(mloopuv[loop_idx])));
}
if (!uv_coords_primvar.HasValue()) {
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
index a95f917869b..9028efb875a 100644
--- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
+++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
@@ -291,27 +291,31 @@ Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
void OBJMesh::store_uv_coords_and_indices()
{
- const Span<MPoly> polys = export_mesh_eval_->polys();
- const Span<MLoop> loops = export_mesh_eval_->loops();
- const int totvert = export_mesh_eval_->totvert;
- const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
- CustomData_get_layer(&export_mesh_eval_->ldata, CD_MLOOPUV));
- if (!mloopuv) {
+ const StringRef active_uv_name = CustomData_get_active_layer_name(&export_mesh_eval_->ldata,
+ CD_PROP_FLOAT2);
+ if (active_uv_name.is_empty()) {
tot_uv_vertices_ = 0;
return;
}
+ const Span<MPoly> polys = export_mesh_eval_->polys();
+ const Span<MLoop> loops = export_mesh_eval_->loops();
+ const int totvert = export_mesh_eval_->totvert;
+ const bke::AttributeAccessor attributes = export_mesh_eval_->attributes();
+ const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
+
const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT};
- UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(polys.data(),
- nullptr,
- nullptr,
- loops.data(),
- mloopuv,
- polys.size(),
- totvert,
- limit,
- false,
- false);
+ UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
+ polys.data(),
+ nullptr,
+ nullptr,
+ loops.data(),
+ reinterpret_cast<const float(*)[2]>(uv_map.data()),
+ polys.size(),
+ totvert,
+ limit,
+ false,
+ false);
uv_indices_.resize(polys.size());
/* At least total vertices of a mesh will be present in its texture map. So
@@ -330,7 +334,7 @@ void OBJMesh::store_uv_coords_and_indices()
/* Store UV vertex coordinates. */
uv_coords_.resize(tot_uv_vertices_);
const int loopstart = polys[uv_vert->poly_index].loopstart;
- Span<float> vert_uv_coords(mloopuv[loopstart + uv_vert->loop_of_poly_index].uv, 2);
+ Span<float> vert_uv_coords(uv_map[loopstart + uv_vert->loop_of_poly_index], 2);
uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]);
/* Store UV vertex indices. */
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
index 56ad7fd4563..f27bbd296e4 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
@@ -267,22 +267,41 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh)
if (global_vertices_.uv_vertices.size() <= 0) {
return;
}
- MLoopUV *mluv_dst = static_cast<MLoopUV *>(CustomData_add_layer(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh_geometry_.total_loops_));
+
+ bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
+ bke::SpanAttributeWriter<float2> uv_map = attributes.lookup_or_add_for_write_only_span<float2>(
+ "UVMap", ATTR_DOMAIN_CORNER);
+
int tot_loop_idx = 0;
+ bool added_uv = false;
for (const PolyElem &curr_face : mesh_geometry_.face_elements_) {
for (int idx = 0; idx < curr_face.corner_count_; ++idx) {
const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx];
- const int uv_index = curr_corner.uv_vert_index;
- float2 uv(0, 0);
- if (uv_index >= 0 && uv_index < global_vertices_.uv_vertices.size()) {
- uv = global_vertices_.uv_vertices[uv_index];
+ if (curr_corner.uv_vert_index >= 0 &&
+ curr_corner.uv_vert_index < global_vertices_.uv_vertices.size()) {
+ uv_map.span[tot_loop_idx] = global_vertices_.uv_vertices[curr_corner.uv_vert_index];
+ added_uv = true;
+ }
+ else {
+ uv_map.span[tot_loop_idx] = {0.f, 0.f};
}
- copy_v2_v2(mluv_dst[tot_loop_idx].uv, uv);
tot_loop_idx++;
}
}
+
+ uv_map.finish();
+
+ /* If we have an object without UVs which resides in the same .obj file
+ * as an object which *does* have UVs we can end up adding and UV layer
+ * filled with zeroes.
+ * We could maybe check before creating this layer but that would need
+ * iterating over the whole mesh to check for UVs and as this is probably
+ * the exception rather than the rule, just delete it afterwards.
+ */
+ if (!added_uv) {
+ attributes.remove("UVMap");
+ }
}
static Material *get_or_create_material(Main *bmain,
diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
index f459e1ab1bd..da60a661d9f 100644
--- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
+++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
@@ -107,9 +107,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest {
const float3 *lnors = (const float3 *)CustomData_get_layer(&mesh->ldata, CD_NORMAL);
float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0);
EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f);
- const MLoopUV *mloopuv = static_cast<const MLoopUV *>(
- CustomData_get_layer(&mesh->ldata, CD_MLOOPUV));
- float2 uv_first = mloopuv ? float2(mloopuv->uv) : float2(0, 0);
+ const float2 *mloopuv = static_cast<const float2 *>(
+ CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2));
+ float2 uv_first = mloopuv ? *mloopuv : float2(0, 0);
EXPECT_V2_NEAR(uv_first, exp.uv_first, 0.0001f);
if (exp.color_first.x >= 0) {
const float4 *colors = (const float4 *)CustomData_get_layer(&mesh->vdata, CD_PROP_COLOR);
diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h
index 0355ed3febe..5694522dbbc 100644
--- a/source/blender/makesdna/DNA_customdata_types.h
+++ b/source/blender/makesdna/DNA_customdata_types.h
@@ -36,7 +36,8 @@ typedef struct CustomDataLayer {
/** Shape keyblock unique id reference. */
int uid;
/** Layer name, MAX_CUSTOMDATA_LAYER_NAME. */
- char name[64];
+ char name[68];
+ char _pad1[4];
/** Layer data. */
void *data;
/**
@@ -48,7 +49,7 @@ typedef struct CustomDataLayer {
const struct AnonymousAttributeID *anonymous_id;
} CustomDataLayer;
-#define MAX_CUSTOMDATA_LAYER_NAME 64
+#define MAX_CUSTOMDATA_LAYER_NAME 68
typedef struct CustomDataExternal {
/** FILE_MAX. */
diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h
index eef3b59c20d..3d3cc20a571 100644
--- a/source/blender/makesdna/DNA_dynamicpaint_types.h
+++ b/source/blender/makesdna/DNA_dynamicpaint_types.h
@@ -113,7 +113,7 @@ typedef struct DynamicPaintSurface {
float init_color[4];
struct Tex *init_texture;
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char init_layername[64];
+ char init_layername[68];
int dry_speed, diss_speed;
float color_dry_threshold;
@@ -130,13 +130,13 @@ typedef struct DynamicPaintSurface {
char _pad2[4];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
/** 1024 = FILE_MAX. */
char image_output_path[1024];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char output_name[64];
+ char output_name[68];
/** MAX_CUSTOMDATA_LAYER_NAME */ /* some surfaces have 2 outputs. */
- char output_name2[64];
+ char output_name2[68];
} DynamicPaintSurface;
diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h
index 5a1636879bb..10fa1004f3d 100644
--- a/source/blender/makesdna/DNA_fluid_types.h
+++ b/source/blender/makesdna/DNA_fluid_types.h
@@ -784,14 +784,15 @@ typedef struct FluidFlowSettings {
float texture_offset;
char _pad2[4];
/* MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
+ char _pad3[4];
short vgroup_density;
short type; /* Smoke, flames, both, outflow, liquid. */
short behavior; /* Inflow, outflow, static. */
short source;
short texture_type;
- short _pad3[3];
+ short _pad4[3];
int flags; /* Absolute emission etc. */
} FluidFlowSettings;
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index f1c2dcaae68..bb121cbd919 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -186,9 +186,9 @@ enum {
*
* // access UV coordinates (works for all loop data, vertex colors... etc).
* float *uvtri_co[3] = {
- * mloopuv[lt->tri[0]].uv,
- * mloopuv[lt->tri[1]].uv,
- * mloopuv[lt->tri[2]].uv,
+ * mloopuv[lt->tri[0]],
+ * mloopuv[lt->tri[1]],
+ * mloopuv[lt->tri[2]],
* };
* \endcode
*
@@ -340,21 +340,6 @@ typedef enum eMVertSkinFlag {
* \{ */
/**
- * UV coordinate for a polygon face & flag for selection & other options.
- */
-typedef struct MLoopUV {
- float uv[2];
- int flag;
-} MLoopUV;
-
-/** #MLoopUV.flag */
-enum {
- MLOOPUV_EDGESEL = (1 << 0),
- MLOOPUV_VERTSEL = (1 << 1),
- MLOOPUV_PINNED = (1 << 2),
-};
-
-/**
* \note While alpha is not currently in the 3D Viewport,
* this may eventually be added back, keep this value set to 255.
*/
@@ -474,6 +459,26 @@ enum {
/** \name Deprecated Structs
* \{ */
+#ifdef DNA_DEPRECATED_ALLOW
+
+/**
+ * UV coordinate for a polygon face & flag for selection & other options.
+ * Deprecated, but kept to read old files. UV coordinates are now stored as #CD_PROP_FLOAT2 layers.
+ */
+typedef struct MLoopUV {
+ float uv[2];
+ int flag;
+} MLoopUV;
+
+/** #MLoopUV.flag */
+enum {
+ MLOOPUV_EDGESEL = (1 << 0),
+ MLOOPUV_VERTSEL = (1 << 1),
+ MLOOPUV_PINNED = (1 << 2),
+};
+
+#endif
+
/**
* Used in Blender pre 2.63, See #MLoop, #MPoly for face data stored in the blend file.
* Use for reading old files and in a handful of cases which should be removed eventually.
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index c4180071352..5fca67321b1 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -143,7 +143,8 @@ typedef struct MappingInfoModifierData {
struct Object *map_object;
char map_bone[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
+ char _pad1[4];
int uvlayer_tmp;
int texmapping;
} MappingInfoModifierData;
@@ -558,7 +559,7 @@ typedef struct DisplaceModifierData {
struct Object *map_object;
char map_bone[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
int uvlayer_tmp;
int texmapping;
/* end MappingInfoModifierData */
@@ -570,7 +571,7 @@ typedef struct DisplaceModifierData {
float midlevel;
int space;
short flag;
- char _pad[6];
+ char _pad2[2];
} DisplaceModifierData;
/** #DisplaceModifierData.flag */
@@ -614,9 +615,8 @@ typedef struct UVProjectModifierData {
float aspectx, aspecty;
float scalex, scaley;
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
int uvlayer_tmp;
- char _pad[4];
} UVProjectModifierData;
#define MOD_UVPROJECT_MAXPROJECTORS 10
@@ -719,7 +719,8 @@ typedef struct WaveModifierData {
struct Object *map_object;
char map_bone[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
+ char _pad1[4];
int uvlayer_tmp;
int texmapping;
/* End MappingInfoModifierData. */
@@ -729,14 +730,14 @@ typedef struct WaveModifierData {
char defgrp_name[64];
short flag;
- char _pad[2];
+ char _pad2[2];
float startx, starty, height, width;
float narrow, speed, damp, falloff;
float timeoffs, lifetime;
- char _pad1[4];
- void *_pad2;
+ char _pad3[4];
+ void *_pad4;
} WaveModifierData;
/** #WaveModifierData.flag */
@@ -1051,9 +1052,9 @@ typedef struct ParticleInstanceModifierData {
float rotation, random_rotation;
float particle_amount, particle_offset;
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char index_layer_name[64];
+ char index_layer_name[68];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char value_layer_name[64];
+ char value_layer_name[68];
void *_pad1;
} ParticleInstanceModifierData;
@@ -1074,8 +1075,9 @@ typedef struct ExplodeModifierData {
short flag, vgroup;
float protect;
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvname[64];
- void *_pad1;
+ char uvname[68];
+ char _pad1[4];
+ void *_pad2;
} ExplodeModifierData;
typedef struct MultiresModifierData {
@@ -1389,8 +1391,8 @@ typedef struct OceanModifierData {
/** FILE_MAX. */
char cachepath[1024];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char foamlayername[64];
- char spraylayername[64];
+ char foamlayername[68];
+ char spraylayername[68];
char cached;
char geometry_mode;
@@ -1438,7 +1440,8 @@ typedef struct WarpModifierData {
struct Object *map_object;
char map_bone[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
+ char _pad1[4];
int uvlayer_tmp;
int texmapping;
/* End #MappingInfoModifierData. */
@@ -1457,8 +1460,8 @@ typedef struct WarpModifierData {
float falloff_radius;
char flag;
char falloff_type;
- char _pad[6];
- void *_pad1;
+ char _pad2[6];
+ void *_pad3;
} WarpModifierData;
/** #WarpModifierData.flag */
@@ -1519,10 +1522,9 @@ typedef struct WeightVGEditModifierData {
/** How to map the texture (using MOD_DISP_MAP_* enums). */
int mask_tex_mapping;
/** Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME. */
- char mask_tex_uvlayer_name[64];
+ char mask_tex_uvlayer_name[68];
/* Padding... */
- char _pad0[4];
void *_pad1;
} WeightVGEditModifierData;
@@ -1573,12 +1575,13 @@ typedef struct WeightVGMixModifierData {
/** How to map the texture. */
int mask_tex_mapping;
/** Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME. */
- char mask_tex_uvlayer_name[64];
+ char mask_tex_uvlayer_name[68];
+ char _pad1[4];
char flag;
/* Padding... */
- char _pad1[3];
+ char _pad2[3];
} WeightVGMixModifierData;
/** #WeightVGMixModifierData.mix_mode (how second vgroup's weights affect first ones). */
@@ -1661,7 +1664,8 @@ typedef struct WeightVGProximityModifierData {
/** How to map the texture. */
int mask_tex_mapping;
/** Name of the UV Map. MAX_CUSTOMDATA_LAYER_NAME. */
- char mask_tex_uvlayer_name[64];
+ char mask_tex_uvlayer_name[68];
+ char _pad1[4];
/** Distances mapping to 0.0/1.0 weights. */
float min_dist, max_dist;
@@ -1935,7 +1939,8 @@ typedef struct UVWarpModifierData {
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
char vgroup_name[64];
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvlayer_name[64];
+ char uvlayer_name[68];
+ char _pad[4];
} UVWarpModifierData;
/** #UVWarpModifierData.flag */
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 3161238dc2e..dc34c53e28f 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -1156,12 +1156,11 @@ typedef struct NodeShaderTexPointDensity {
short interpolation;
short color_source;
short ob_color_source;
- /** Vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME. */
- char vertex_attribute_name[64];
/* Used at runtime only by sampling RNA API. */
PointDensity pd;
int cached_resolution;
- char _pad2[4];
+ /** Vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME. */
+ char vertex_attribute_name[68];
} NodeShaderTexPointDensity;
typedef struct NodeShaderPrincipled {
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index c4f11905e10..75410716e22 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -359,12 +359,13 @@ typedef struct ParticleSystem {
char _pad1[6];
/** Billboard uv name, MAX_CUSTOMDATA_LAYER_NAME. */
- char bb_uvname[3][64] DNA_DEPRECATED;
+ char bb_uvname[3][68] DNA_DEPRECATED;
+ char _pad2[4];
/* if you change these remember to update array lengths to PSYS_TOT_VG! */
/** Vertex groups, 0==disable, 1==starting index. */
short vgroup[13], vg_neg, rt3;
- char _pad[6];
+ char _pad3[6];
/* point cache */
struct PointCache *pointcache;
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index c7d49db130e..4b3daf92d8b 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -31,7 +31,8 @@ typedef struct MTex {
struct Object *object;
struct Tex *tex;
/** MAX_CUSTOMDATA_LAYER_NAME. */
- char uvname[64];
+ char uvname[68];
+ char _pad1[4];
char projx, projy, projz, mapping;
char brush_map_mode, brush_angle_mode;
@@ -122,7 +123,8 @@ typedef struct PointDensity {
/** cache points in world-space, object space, ... ? */
short ob_cache_space;
/** vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */
- char vertex_attribute_name[64];
+ char vertex_attribute_name[68];
+ char _pad1[4];
/** The acceleration tree containing points. */
void *point_tree;
@@ -133,11 +135,11 @@ typedef struct PointDensity {
short noise_depth;
short noise_influence;
short noise_basis;
- char _pad1[6];
+ char _pad2[6];
float noise_fac;
float speed_scale, falloff_speed_scale;
- char _pad2[4];
+ char _pad3[4];
/** For time -> color */
struct ColorBand *coba;
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index f13132b5b7c..298baeb8eb2 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -955,12 +955,15 @@ static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, bool value)
/* uv_layers */
-DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_MLOOPUV)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, active, MeshUVLoopLayer)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, clone, MeshUVLoopLayer)
+DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_PROP_FLOAT2)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
- uv_layer, ldata, CD_MLOOPUV, stencil, MeshUVLoopLayer)
-DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, render, MeshUVLoopLayer)
+ uv_layer, ldata, CD_PROP_FLOAT2, active, MeshUVLoopLayer)
+DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
+ uv_layer, ldata, CD_PROP_FLOAT2, clone, MeshUVLoopLayer)
+DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
+ uv_layer, ldata, CD_PROP_FLOAT2, stencil, MeshUVLoopLayer)
+DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
+ uv_layer, ldata, CD_PROP_FLOAT2, render, MeshUVLoopLayer)
/* MeshUVLoopLayer */
@@ -977,7 +980,7 @@ static void rna_MeshUVLoopLayer_data_begin(CollectionPropertyIterator *iter, Poi
Mesh *me = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
rna_iterator_array_begin(
- iter, layer->data, sizeof(MLoopUV), (me->edit_mesh) ? 0 : me->totloop, 0, NULL);
+ iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL);
}
static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr)
@@ -988,32 +991,32 @@ static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr)
static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr)
{
- return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 1);
+ return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 1);
}
static bool rna_MeshUVLoopLayer_active_get(PointerRNA *ptr)
{
- return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 0);
+ return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 0);
}
static bool rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr)
{
- return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV);
+ return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2);
}
static void rna_MeshUVLoopLayer_active_render_set(PointerRNA *ptr, bool value)
{
- rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 1);
+ rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 1);
}
static void rna_MeshUVLoopLayer_active_set(PointerRNA *ptr, bool value)
{
- rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 0);
+ rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 0);
}
static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value)
{
- rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV);
+ rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2);
}
/* vertex_color_layers */
@@ -1779,7 +1782,101 @@ int rna_Mesh_poly_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_p
static char *rna_MeshUVLoop_path(const PointerRNA *ptr)
{
- return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV);
+ return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_PROP_FLOAT2);
+}
+
+static void get_uv_index_and_layer(const PointerRNA *ptr,
+ int *r_uv_map_index,
+ int *r_index_in_attribute)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ const float(*uv_coord)[2] = (const float(*)[2])ptr->data;
+
+ /* We don't know from which attribute the RNA pointer is from, so we need to scan them all. */
+ const int uv_layers_num = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2);
+ for (int layer_i = 0; layer_i < uv_layers_num; layer_i++) {
+ const float(*layer_data)[2] = (float(*)[2])CustomData_get_layer_n(
+ &mesh->ldata, CD_PROP_FLOAT2, layer_i);
+ const ptrdiff_t index = uv_coord - layer_data;
+ if (index >= 0 && index < mesh->totloop) {
+ *r_uv_map_index = layer_i;
+ *r_index_in_attribute = index;
+ return;
+ }
+ }
+
+ BLI_assert_unreachable();
+ return;
+}
+
+static bool rna_MeshUVLoop_select_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ const bool *select = ED_mesh_uv_map_get_vert_selection(mesh, uv_index);
+ return select ? select[corner_index] : false;
+}
+
+static void rna_MeshUVLoop_select_set(PointerRNA *ptr, const bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ bool *select = ED_mesh_uv_map_ensure_vert_selection(mesh, uv_index);
+ select[corner_index] = value;
+}
+
+static bool rna_MeshUVLoop_select_edge_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ const bool *select_edge = ED_mesh_uv_map_get_edge_selection(mesh, uv_index);
+ return select_edge ? select_edge[corner_index] : false;
+}
+
+static void rna_MeshUVLoop_select_edge_set(PointerRNA *ptr, const bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ bool *select_edge = ED_mesh_uv_map_ensure_edge_selection(mesh, uv_index);
+ select_edge[corner_index] = value;
+}
+
+static bool rna_MeshUVLoop_pin_uv_get(PointerRNA *ptr)
+{
+ const Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ const bool *pin_uv = ED_mesh_uv_map_get_pin(mesh, uv_index);
+ return pin_uv ? pin_uv[corner_index] : false;
+}
+
+static void rna_MeshUVLoop_pin_uv_set(PointerRNA *ptr, const bool value)
+{
+ Mesh *mesh = rna_mesh(ptr);
+ int uv_index;
+ int corner_index;
+ get_uv_index_and_layer(ptr, &uv_index, &corner_index);
+ bool *pin_uv = ED_mesh_uv_map_ensure_pin(mesh, uv_index);
+ pin_uv[corner_index] = value;
+}
+
+static void rna_MeshUVLoop_uv_get(PointerRNA *ptr, float *value)
+{
+ copy_v2_v2(value, ptr->data);
+}
+
+static void rna_MeshUVLoop_uv_set(PointerRNA *ptr, const float *value)
+{
+ copy_v2_v2(ptr->data, value);
}
static char *rna_MeshLoopColorLayer_path(const PointerRNA *ptr)
@@ -2101,7 +2198,7 @@ static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me,
if (index != -1) {
ldata = rna_mesh_ldata_helper(me);
- cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_MLOOPUV, index)];
+ cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, index)];
}
RNA_pointer_create(&me->id, &RNA_MeshUVLoopLayer, cdl, &ptr);
@@ -2110,9 +2207,7 @@ static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me,
static void rna_Mesh_uv_layers_remove(struct Mesh *me, ReportList *reports, CustomDataLayer *layer)
{
- if (ED_mesh_uv_remove_named(me, layer->name) == false) {
- BKE_reportf(reports, RPT_ERROR, "Texture layer '%s' not found", layer->name);
- }
+ BKE_id_attribute_remove(&me->id, layer->name, reports);
}
static bool rna_Mesh_is_editmode_get(PointerRNA *ptr)
@@ -2634,23 +2729,25 @@ static void rna_def_mloopuv(BlenderRNA *brna)
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
srna = RNA_def_struct(brna, "MeshUVLoop", NULL);
- RNA_def_struct_sdna(srna, "MLoopUV");
RNA_def_struct_ui_text(srna, "Mesh UV Layer", "Layer of UV coordinates in a Mesh data-block");
RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path");
prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_array(prop, 2);
+ RNA_def_property_float_funcs(prop, "rna_MeshUVLoop_uv_get", "rna_MeshUVLoop_uv_set", NULL);
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "pin_uv", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_PINNED);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_pin_uv_get", "rna_MeshUVLoop_pin_uv_set");
RNA_def_property_ui_text(prop, "UV Pinned", "");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_VERTSEL);
+ RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_select_get", "rna_MeshUVLoop_select_set");
RNA_def_property_ui_text(prop, "UV Select", "");
prop = RNA_def_property(srna, "select_edge", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_EDGESEL);
+ RNA_def_property_boolean_funcs(
+ prop, "rna_MeshUVLoop_select_edge_get", "rna_MeshUVLoop_select_edge_set");
RNA_def_property_ui_text(prop, "UV Edge Select", "");
}
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index c5da15003e1..def1f2958fd 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -1355,16 +1355,16 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(
Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
- cddata_masks.lmask |= CD_MASK_MLOOPUV;
+ cddata_masks.lmask |= CD_MASK_PROP_FLOAT2;
me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
- num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
+ num_data = CustomData_number_of_layers(&me_eval->ldata, CD_PROP_FLOAT2);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
- &me_eval->ldata, CD_MLOOPUV, i);
+ &me_eval->ldata, CD_PROP_FLOAT2, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
@@ -1473,13 +1473,14 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf(
me_dst = ob_dst->data;
ldata = &me_dst->ldata;
- num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV);
+ num_data = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2);
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0; i < num_data; i++) {
tmp_item.value = i;
- tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i);
+ tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
+ ldata, CD_PROP_FLOAT2, i);
RNA_enum_item_add(&item, &totitem, &tmp_item);
}
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 1d6b3d5d69e..d93dbca13f8 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1054,7 +1054,7 @@ void rna_object_uvlayer_name_set(PointerRNA *ptr, const char *value, char *resul
for (a = 0; a < me->ldata.totlayer; a++) {
layer = &me->ldata.layers[a];
- if (layer->type == CD_MLOOPUV && STREQ(layer->name, value)) {
+ if (layer->type == CD_PROP_FLOAT2 && STREQ(layer->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index a56e7d28ef7..fd4acb99c4d 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -385,7 +385,7 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle,
int num = particle->num_dmcache;
int from = modifier->psys->part->from;
- if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_PROP_FLOAT2)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
return;
}
@@ -644,7 +644,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem,
zero_v2(r_uv);
return;
}
- if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_PROP_FLOAT2)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
zero_v2(r_uv);
return;
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 2d725af7fe4..8d828bb45b5 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -670,9 +670,9 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
/* handle UVs */
if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) {
- const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV);
+ const int totuv = CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2);
for (i = 0; i < totuv; i++) {
- MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i);
+ float(*dmloopuv)[2] = CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, i);
dmloopuv += chunk_nloops;
for (c = 1; c < count; c++) {
const float uv_offset[2] = {
@@ -681,8 +681,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
};
int l_index = chunk_nloops;
for (; l_index-- != 0; dmloopuv++) {
- dmloopuv->uv[0] += uv_offset[0];
- dmloopuv->uv[1] += uv_offset[1];
+ (*dmloopuv)[0] += uv_offset[0];
+ (*dmloopuv)[1] += uv_offset[1];
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index c19c231d44c..98b0f623843 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -81,10 +81,10 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma
if (pmd->canvas) {
DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
for (; surface; surface = surface->next) {
- /* UV's: #CD_MLOOPUV. */
+ /* UV's: #CD_PROP_FLOAT2. */
if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ ||
surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
+ r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2;
}
/* Vertex Colors: #CD_PROP_BYTE_COLOR. */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT ||
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index bee1bd7795a..6da94bd4f90 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -157,7 +157,7 @@ typedef struct GenerateOceanGeometryData {
MVert *mverts;
MPoly *mpolys;
MLoop *mloops;
- MLoopUV *mloopuvs;
+ float (*mloopuvs)[2];
int res_x, res_y;
int rx, ry;
@@ -220,22 +220,22 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata,
for (x = 0; x < gogd->res_x; x++) {
const int i = y * gogd->res_x + x;
- MLoopUV *luv = &gogd->mloopuvs[i * 4];
+ float(*luv)[2] = &gogd->mloopuvs[i * 4];
- luv->uv[0] = x * gogd->ix;
- luv->uv[1] = y * gogd->iy;
+ (*luv)[0] = x * gogd->ix;
+ (*luv)[1] = y * gogd->iy;
luv++;
- luv->uv[0] = (x + 1) * gogd->ix;
- luv->uv[1] = y * gogd->iy;
+ (*luv)[0] = (x + 1) * gogd->ix;
+ (*luv)[1] = y * gogd->iy;
luv++;
- luv->uv[0] = (x + 1) * gogd->ix;
- luv->uv[1] = (y + 1) * gogd->iy;
+ (*luv)[0] = (x + 1) * gogd->ix;
+ (*luv)[1] = (y + 1) * gogd->iy;
luv++;
- luv->uv[0] = x * gogd->ix;
- luv->uv[1] = (y + 1) * gogd->iy;
+ (*luv)[0] = x * gogd->ix;
+ (*luv)[1] = (y + 1) * gogd->iy;
luv++;
}
}
@@ -287,9 +287,9 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co
BKE_mesh_calc_edges(result, false, false);
/* add uvs */
- if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) {
+ if (CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2) < MAX_MTFACE) {
gogd.mloopuvs = CustomData_add_layer(
- &result->ldata, CD_MLOOPUV, CD_SET_DEFAULT, NULL, polys_num * 4);
+ &result->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, NULL, polys_num * 4);
if (gogd.mloopuvs) { /* unlikely to fail */
gogd.ix = 1.0 / gogd.rx;
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 4ba274dbd8a..b84188303e3 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -214,8 +214,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
uint *vert_loop_map = NULL; /* orig vert to orig loop */
/* UV Coords */
- const uint mloopuv_layers_tot = (uint)CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV);
- MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot);
+ const uint mloopuv_layers_tot = (uint)CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2);
+ float(**mloopuv_layers)[2] = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot);
float uv_u_scale;
float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX};
float uv_v_range_inv;
@@ -409,7 +409,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
if (mloopuv_layers_tot) {
uint uv_lay;
for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay);
+ mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, (int)uv_lay);
}
if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) {
@@ -922,12 +922,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const float uv_u_offset_a = (float)(step)*uv_u_scale;
const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
+ float(*mluv)[2] = &mloopuv_layers[uv_lay][l_index];
- mluv[quad_ord[0]].uv[0] += uv_u_offset_a;
- mluv[quad_ord[1]].uv[0] += uv_u_offset_a;
- mluv[quad_ord[2]].uv[0] += uv_u_offset_b;
- mluv[quad_ord[3]].uv[0] += uv_u_offset_b;
+ mluv[quad_ord[0]][0] += uv_u_offset_a;
+ mluv[quad_ord[1]][0] += uv_u_offset_a;
+ mluv[quad_ord[2]][0] += uv_u_offset_b;
+ mluv[quad_ord[3]][0] += uv_u_offset_b;
}
}
}
@@ -939,12 +939,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const float uv_u_offset_a = (float)(step)*uv_u_scale;
const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
- MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
+ float(*mluv)[2] = &mloopuv_layers[uv_lay][l_index];
- copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a);
- copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b);
- copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b);
- copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a);
+ copy_v2_fl2(mluv[quad_ord[0]], uv_u_offset_a, uv_v_offset_a);
+ copy_v2_fl2(mluv[quad_ord[1]], uv_u_offset_a, uv_v_offset_b);
+ copy_v2_fl2(mluv[quad_ord[2]], uv_u_offset_b, uv_v_offset_b);
+ copy_v2_fl2(mluv[quad_ord[3]], uv_u_offset_b, uv_v_offset_a);
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc
index a94fc6732a0..c4c103d6fbb 100644
--- a/source/blender/modifiers/intern/MOD_util.cc
+++ b/source/blender/modifiers/intern/MOD_util.cc
@@ -93,17 +93,16 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
/* UVs need special handling, since they come from faces */
if (texmapping == MOD_DISP_MAP_UV) {
- if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
+ if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MPoly *mp;
const MLoop *mloop = BKE_mesh_loops(mesh);
BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__);
const int polys_num = mesh->totpoly;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
-
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname);
- const MLoopUV *mloop_uv = static_cast<const MLoopUV *>(
- CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname));
+ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, dmd->uvlayer_name, uvname);
+ const float(*mloop_uv)[2] = static_cast<const float(*)[2]>(
+ CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname));
/* verts are given the UV from the first face that uses them */
for (i = 0, mp = mpoly; i < polys_num; i++, mp++) {
@@ -115,8 +114,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
if (!BLI_BITMAP_TEST(done, vidx)) {
/* remap UVs from [0, 1] to [-1, 1] */
- r_texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f;
- r_texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f;
+ r_texco[vidx][0] = (mloop_uv[lidx][0] * 2.0f) - 1.0f;
+ r_texco[vidx][1] = (mloop_uv[lidx][1] * 2.0f) - 1.0f;
BLI_BITMAP_ENABLE(done, vidx);
}
diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc
index 895572d9477..5e3ce61ab23 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.cc
+++ b/source/blender/modifiers/intern/MOD_uvproject.cc
@@ -55,7 +55,7 @@ static void initData(ModifierData *md)
static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks)
{
/* ask for UV coordinates */
- r_cddata_masks->lmask |= CD_MASK_MLOOPUV;
+ r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2;
}
static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData)
@@ -118,13 +118,13 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
/* Create a new layer if no UV Maps are available
* (e.g. if a preceding modifier could not preserve it). */
- if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
CustomData_add_layer_named(
- &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, umd->uvlayer_name);
+ &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, umd->uvlayer_name);
}
/* make sure we're using an existing layer */
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
+ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, umd->uvlayer_name, uvname);
/* calculate a projection matrix and normal for each projector */
for (i = 0; i < projectors_num; i++) {
@@ -185,8 +185,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
loops_num = mesh->totloop;
/* make sure we are not modifying the original UV map */
- MLoopUV *mloop_uv = static_cast<MLoopUV *>(
- CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num));
+ float(*mloop_uv)[2] = static_cast<float(*)[2]>(CustomData_duplicate_referenced_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num));
coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num);
@@ -214,7 +214,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
BLI_uvproject_from_camera(
- mloop_uv[lidx].uv, coords[vidx], static_cast<ProjCameraInfo *>(projectors[0].uci));
+ mloop_uv[lidx], coords[vidx], static_cast<ProjCameraInfo *>(projectors[0].uci));
} while (fidx--);
}
else {
@@ -223,7 +223,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
do {
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
- copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]);
+ copy_v2_v2(mloop_uv[lidx], coords[vidx]);
} while (fidx--);
}
}
@@ -258,7 +258,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
BLI_uvproject_from_camera(
- mloop_uv[lidx].uv, coords[vidx], static_cast<ProjCameraInfo *>(best_projector->uci));
+ mloop_uv[lidx], coords[vidx], static_cast<ProjCameraInfo *>(best_projector->uci));
} while (fidx--);
}
else {
@@ -266,7 +266,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
do {
uint lidx = mp->loopstart + fidx;
uint vidx = loops[lidx].v;
- mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]);
+ mul_v2_project_m4_v3(mloop_uv[lidx], best_projector->projmat, coords[vidx]);
} while (fidx--);
}
}
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc
index a96b28b4e2e..48cb725f7bc 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.cc
+++ b/source/blender/modifiers/intern/MOD_uvwarp.cc
@@ -82,7 +82,7 @@ static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonen
struct UVWarpData {
const MPoly *mpoly;
const MLoop *mloop;
- MLoopUV *mloopuv;
+ float (*mloopuv)[2];
const MDeformVert *dvert;
int defgrp_index;
@@ -99,7 +99,7 @@ static void uv_warp_compute(void *__restrict userdata,
const MPoly *mp = &data->mpoly[i];
const MLoop *ml = &data->mloop[mp->loopstart];
- MLoopUV *mluv = &data->mloopuv[mp->loopstart];
+ float(*mluv)[2] = &data->mloopuv[mp->loopstart];
const MDeformVert *dvert = data->dvert;
const int defgrp_index = data->defgrp_index;
@@ -115,13 +115,13 @@ static void uv_warp_compute(void *__restrict userdata,
1.0f - BKE_defvert_find_weight(&dvert[ml->v], defgrp_index) :
BKE_defvert_find_weight(&dvert[ml->v], defgrp_index);
- uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat);
- interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight);
+ uv_warp_from_mat4_pair(uv, (*mluv), warp_mat);
+ interp_v2_v2v2((*mluv), (*mluv), uv, weight);
}
}
else {
for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
- uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat);
+ uv_warp_from_mat4_pair((*mluv), (*mluv), warp_mat);
}
}
}
@@ -139,7 +139,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const bool invert_vgroup = (umd->flag & MOD_UVWARP_INVERT_VGROUP) != 0;
/* make sure there are UV Maps available */
- if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
+ if (!CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
return mesh;
}
@@ -190,7 +190,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
translate_m4(warp_mat, -umd->center[0], -umd->center[1], 0.0f);
/* make sure we're using an existing layer */
- CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname);
+ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, umd->uvlayer_name, uvname);
const MPoly *polys = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
@@ -198,8 +198,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
loops_num = mesh->totloop;
/* make sure we are not modifying the original UV map */
- MLoopUV *mloopuv = static_cast<MLoopUV *>(
- CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num));
+ float(*mloopuv)[2] = static_cast<float(*)[2]>(CustomData_duplicate_referenced_layer_named(
+ &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num));
MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
UVWarpData data{};
diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
index 8287c6a6714..5a7e4f174ba 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
@@ -35,7 +35,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius)
bmesh_create_params.use_toolflags = true;
const BMAllocTemplate allocsize = {0, 0, 0, 0};
BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params);
- BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, nullptr);
+ BM_data_layer_add_named(bm, &bm->ldata, CD_PROP_FLOAT2, nullptr);
BMO_op_callf(bm,
BMO_FLAG_DEFAULTS,
diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c
index 1288083f8e7..239e21b6ffb 100644
--- a/source/blender/python/bmesh/bmesh_py_types_customdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c
@@ -360,7 +360,7 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = {
(getter)bpy_bmlayeraccess_collection_get,
(setter)NULL,
bpy_bmlayeraccess_collection__uv_doc,
- (void *)CD_MLOOPUV},
+ (void *)CD_PROP_FLOAT2},
{"color",
(getter)bpy_bmlayeraccess_collection_get,
(setter)NULL,
@@ -461,6 +461,15 @@ static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self)
if (index == -1) {
BM_data_layer_add(self->bm, data, self->type);
index = 0;
+ /* Because addingCustomData layers to a bmesh will invalidate any existing pointers
+ * in Py objects we can't lazily add the associated bool layers. So add htem right now.
+ */
+ if (self->type == CD_PROP_FLOAT2 && self->htype == BM_LOOP) {
+ const char *active_uv_name = CustomData_get_active_layer_name(&self->bm->ldata, CD_PROP_FLOAT2);
+ BM_uv_map_ensure_vert_selection_attribute(self->bm, active_uv_name);
+ BM_uv_map_ensure_edge_selection_attribute(self->bm, active_uv_name);
+ BM_uv_map_ensure_pin_attribute(self->bm, active_uv_name);
+ }
}
BLI_assert(index >= 0);
@@ -1131,8 +1140,12 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len);
break;
}
- case CD_MLOOPUV: {
- ret = BPy_BMLoopUV_CreatePyObject(value);
+ case CD_PROP_FLOAT2: {
+ if (UNLIKELY(py_ele->bm != py_layer->bm)) {
+ PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh");
+ return NULL;
+ }
+ ret = BPy_BMLoopUV_CreatePyObject(py_ele->bm, py_layer->index);
break;
}
case CD_PROP_BYTE_COLOR: {
@@ -1234,7 +1247,13 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
break;
}
case CD_MLOOPUV: {
- ret = BPy_BMLoopUV_AssignPyObject(value, py_value);
+ if (UNLIKELY(py_ele->bm != py_layer->bm)) {
+ PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh");
+ ret = -1;
+ }
+ else {
+ ret = BPy_BMLoopUV_AssignPyObject(py_ele->bm, py_layer->index, py_value);
+ }
break;
}
case CD_PROP_BYTE_COLOR: {
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
index 9bd98f2df53..af66d531d82 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c
@@ -5,7 +5,7 @@
* \ingroup pybmesh
*
* This file defines custom-data types which can't be accessed as primitive
- * python types such as #MDeformVert, #MLoopUV.
+ * python types such as #MDeformVert and the legacy #MLoopUV type.
*/
#include <Python.h>
@@ -15,12 +15,15 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "BKE_customdata.h"
+
#include "BLI_math_base.h"
#include "BLI_math_vector.h"
#include "BLI_utildefines.h"
#include "BKE_deform.h"
+#include "bmesh.h"
#include "bmesh_py_types_meshdata.h"
#include "../generic/py_capi_utils.h"
@@ -33,72 +36,93 @@
typedef struct BPy_BMLoopUV {
PyObject_VAR_HEAD
- MLoopUV *data;
+ float *uv;
+ bool *vertsel;
+ bool *edgesel;
+ bool *pinned;
} BPy_BMLoopUV;
PyDoc_STRVAR(bpy_bmloopuv_uv_doc,
"Loops UV (as a 2D Vector).\n\n:type: :class:`mathutils.Vector`");
static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
- return Vector_CreatePyObject_wrap(self->data->uv, 2, NULL);
+ return Vector_CreatePyObject_wrap(self->uv, 2, NULL);
}
static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure))
{
float tvec[2];
if (mathutils_array_parse(tvec, 2, 2, value, "BMLoopUV.uv") != -1) {
- copy_v2_v2(self->data->uv, tvec);
+ copy_v2_v2(self->uv, tvec);
return 0;
}
return -1;
}
-PyDoc_STRVAR(bpy_bmloopuv_flag__pin_uv_doc, "UV pin state.\n\n:type: boolean");
-PyDoc_STRVAR(bpy_bmloopuv_flag__select_doc, "UV select state.\n\n:type: boolean");
-PyDoc_STRVAR(bpy_bmloopuv_flag__select_edge_doc, "UV edge select state.\n\n:type: boolean");
+PyDoc_STRVAR(bpy_bmloopuv_pin_uv_doc, "UV pin state.\n\n:type: boolean");
+PyDoc_STRVAR(bpy_bmloopuv_select_doc, "UV select state.\n\n:type: boolean");
+PyDoc_STRVAR(bpy_bmloopuv_select_edge_doc, "UV edge select state.\n\n:type: boolean");
-static PyObject *bpy_bmloopuv_flag_get(BPy_BMLoopUV *self, void *flag_p)
+static PyObject *bpy_bmloopuv_pin_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
- const int flag = POINTER_AS_INT(flag_p);
- return PyBool_FromLong(self->data->flag & flag);
+ return self->pinned ? PyBool_FromLong(*self->pinned) : false;
+}
+static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure))
+{
+ if (self->pinned) {
+ *self->pinned = PyC_Long_AsBool(value);
+ }
+ /* TODO(martijn) if (!self->pinned) that means the layed does not exist , or at least didn't exist
+ * when the PY object was created. We *should* create it here instead of just bailing, but we can't
+ * because that would invalidate all existing BPy_BMLoopUV objects' interal pointers.
+ * the same goes for vertsel and edgesel below.
+ */
+ return 0;
}
-static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag_p)
+static PyObject *bpy_bmloopuv_select_get(BPy_BMLoopUV *self, void *UNUSED(closure))
{
- const int flag = POINTER_AS_INT(flag_p);
+ return self->vertsel ? PyBool_FromLong(*self->vertsel) : false;
+}
+static int bpy_bmloopuv_select_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure))
+{
+ if (self->vertsel) {
+ *self->vertsel = PyC_Long_AsBool(value);
+ }
+ return 0;
+}
- switch (PyC_Long_AsBool(value)) {
- case true:
- self->data->flag |= flag;
- return 0;
- case false:
- self->data->flag &= ~flag;
- return 0;
- default:
- /* error is set */
- return -1;
+static PyObject *bpy_bmloopuv_select_edge_get(BPy_BMLoopUV *self, void *UNUSED(closure))
+{
+ return self->edgesel ? PyBool_FromLong(*self->edgesel) : false;
+}
+static int bpy_bmloopuv_select_edge_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure))
+{
+ if (self->edgesel) {
+ *self->edgesel = PyC_Long_AsBool(value);
}
+ return 0;
}
static PyGetSetDef bpy_bmloopuv_getseters[] = {
/* attributes match rna_def_mloopuv. */
{"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, bpy_bmloopuv_uv_doc, NULL},
{"pin_uv",
- (getter)bpy_bmloopuv_flag_get,
- (setter)bpy_bmloopuv_flag_set,
- bpy_bmloopuv_flag__pin_uv_doc,
- (void *)MLOOPUV_PINNED},
+ (getter)bpy_bmloopuv_pin_uv_get,
+ (setter)bpy_bmloopuv_pin_uv_set,
+ bpy_bmloopuv_pin_uv_doc,
+ NULL},
{"select",
- (getter)bpy_bmloopuv_flag_get,
- (setter)bpy_bmloopuv_flag_set,
- bpy_bmloopuv_flag__select_doc,
- (void *)MLOOPUV_VERTSEL},
+ (getter)bpy_bmloopuv_select_get,
+ (setter)bpy_bmloopuv_select_set,
+ bpy_bmloopuv_select_doc,
+ NULL},
{"select_edge",
- (getter)bpy_bmloopuv_flag_get,
- (setter)bpy_bmloopuv_flag_set,
- bpy_bmloopuv_flag__select_edge_doc,
- (void *)MLOOPUV_EDGESEL},
+ (getter)bpy_bmloopuv_select_edge_get,
+ (setter)bpy_bmloopuv_select_edge_set,
+ bpy_bmloopuv_select_edge_doc,
+ NULL},
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
};
@@ -120,21 +144,39 @@ static void bm_init_types_bmloopuv(void)
PyType_Ready(&BPy_BMLoopUV_Type);
}
-int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value)
+int BPy_BMLoopUV_AssignPyObject(struct BMesh *bm, const int loop_index, PyObject *value)
{
if (UNLIKELY(!BPy_BMLoopUV_Check(value))) {
PyErr_Format(PyExc_TypeError, "expected BMLoopUV, not a %.200s", Py_TYPE(value)->tp_name);
return -1;
}
- *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data);
+ BPy_BMLoopUV *src = (BPy_BMLoopUV *)value;
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
+ BMLoop *l = BM_loop_at_index_find(bm, loop_index);
+ float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ copy_v2_v2(luv, src->uv);
+
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, *src->vertsel);
+ BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, *src->edgesel);
+ BM_ELEM_CD_SET_BOOL(l, offsets.pin, *src->pinned);
+
return 0;
}
-PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv)
+PyObject *BPy_BMLoopUV_CreatePyObject(struct BMesh *bm, const int loop_index)
{
BPy_BMLoopUV *self = PyObject_New(BPy_BMLoopUV, &BPy_BMLoopUV_Type);
- self->data = mloopuv;
+
+ const BMUVOffsets offsets = BM_uv_map_get_offsets(bm);
+
+ BMLoop *l = BM_loop_at_index_find(bm, loop_index);
+ self->uv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv);
+ self->vertsel = BM_ELEM_CD_GET_OPT_BOOL_P(l, offsets.select_vert);
+ self->edgesel = BM_ELEM_CD_GET_OPT_BOOL_P(l, offsets.select_edge);
+ self->pinned = BM_ELEM_CD_GET_OPT_BOOL_P(l, offsets.pin);
+
return (PyObject *)self;
}
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index c349f7a9962..7d0e902961e 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -19,11 +19,11 @@ typedef struct BPy_BMGenericMeshData {
struct MDeformVert;
struct MLoopCol;
-struct MLoopUV;
struct MVertSkin;
+struct BMesh;
-int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value);
-PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv);
+int BPy_BMLoopUV_AssignPyObject(struct BMesh *bm, int loop_index, PyObject *value);
+PyObject *BPy_BMLoopUV_CreatePyObject(struct BMesh *bm, int loop_index);
int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value);
PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin);
diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h
index ebfc7509504..717c5053a38 100644
--- a/source/blender/render/RE_bake.h
+++ b/source/blender/render/RE_bake.h
@@ -11,7 +11,6 @@
struct Depsgraph;
struct ImBuf;
-struct MLoopUV;
struct Mesh;
struct Render;
diff --git a/source/blender/render/RE_texture_margin.h b/source/blender/render/RE_texture_margin.h
index 023615cea87..fd8e41adb3a 100644
--- a/source/blender/render/RE_texture_margin.h
+++ b/source/blender/render/RE_texture_margin.h
@@ -13,7 +13,6 @@ extern "C" {
struct DerivedMesh;
struct IMBuf;
struct ImBuf;
-struct MLoopUV;
struct Mesh;
/**
diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c
index d9f7f9fa0af..b72b99a425f 100644
--- a/source/blender/render/intern/bake.c
+++ b/source/blender/render/intern/bake.c
@@ -711,13 +711,13 @@ void RE_bake_pixels_populate(Mesh *me,
const BakeTargets *targets,
const char *uv_layer)
{
- const MLoopUV *mloopuv;
+ const float(*mloopuv)[2];
if ((uv_layer == NULL) || (uv_layer[0] == '\0')) {
- mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
+ mloopuv = CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2);
}
else {
- int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer);
- mloopuv = CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id);
+ int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer);
+ mloopuv = CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id);
}
if (mloopuv == NULL) {
@@ -768,7 +768,7 @@ void RE_bake_pixels_populate(Mesh *me,
/* Compute triangle vertex UV coordinates. */
float vec[3][2];
for (int a = 0; a < 3; a++) {
- const float *uv = mloopuv[lt->tri[a]].uv;
+ const float *uv = mloopuv[lt->tri[a]];
/* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw
* up our intersection tests where a pixel gets in between 2 faces or the middle of a quad,
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index cfb91e86ad9..cb2b7675a5c 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -65,7 +65,7 @@ typedef struct {
MPoly *mpoly;
const int *material_indices;
MLoop *mloop;
- MLoopUV *mloopuv;
+ float (*mloopuv)[2];
float uv_offset[2];
const MLoopTri *mlooptri;
float *pvtangent;
@@ -159,9 +159,9 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
float u, v, w, sign;
int r;
- st0 = data->mloopuv[data->mlooptri[data->tri_index].tri[0]].uv;
- st1 = data->mloopuv[data->mlooptri[data->tri_index].tri[1]].uv;
- st2 = data->mloopuv[data->mlooptri[data->tri_index].tri[2]].uv;
+ st0 = data->mloopuv[data->mlooptri[data->tri_index].tri[0]];
+ st1 = data->mloopuv[data->mlooptri[data->tri_index].tri[1]];
+ st2 = data->mloopuv[data->mlooptri[data->tri_index].tri[2]];
multiresbake_get_normal(data, data->tri_index, 0, no0); /* can optimize these 3 into one call */
multiresbake_get_normal(data, data->tri_index, 1, no1);
@@ -384,7 +384,7 @@ static void *do_multires_bake_thread(void *data_v)
while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) {
const MLoopTri *lt = &data->mlooptri[tri_index];
const short mat_nr = data->material_indices == NULL ? 0 : data->material_indices[lt->poly];
- const MLoopUV *mloopuv = data->mloopuv;
+ const float(*mloopuv)[2] = data->mloopuv;
if (multiresbake_test_break(bkr)) {
break;
@@ -398,9 +398,9 @@ static void *do_multires_bake_thread(void *data_v)
data->tri_index = tri_index;
float uv[3][2];
- sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset);
- sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]].uv, data->uv_offset);
- sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]].uv, data->uv_offset);
+ sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]], data->uv_offset);
+ sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]], data->uv_offset);
+ sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]], data->uv_offset);
bake_rasterize(bake_rast, uv[0], uv[1], uv[2]);
@@ -475,7 +475,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
MVert *mvert = dm->getVertArray(dm);
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
- MLoopUV *mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
+ float(*mloopuv)[2] = dm->getLoopDataArray(dm, CD_PROP_FLOAT2);
float *pvtangent = NULL;
ListBase threads;
@@ -844,7 +844,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
MLoop *mloop = lores_dm->getLoopArray(lores_dm);
MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly;
- MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV);
+ float(*mloopuv)[2] = lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2);
MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v;
float uv[2], *st0, *st1, *st2, *st3;
@@ -854,16 +854,16 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
- st0 = mloopuv[mpoly->loopstart].uv;
- st1 = mloopuv[mpoly->loopstart + 1].uv;
- st2 = mloopuv[mpoly->loopstart + 2].uv;
- st3 = mloopuv[mpoly->loopstart + 3].uv;
+ st0 = mloopuv[mpoly->loopstart];
+ st1 = mloopuv[mpoly->loopstart + 1];
+ st2 = mloopuv[mpoly->loopstart + 2];
+ st3 = mloopuv[mpoly->loopstart + 3];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
- st0 = mloopuv[lt->tri[0]].uv;
- st1 = mloopuv[lt->tri[1]].uv;
- st2 = mloopuv[lt->tri[2]].uv;
+ st0 = mloopuv[lt->tri[0]];
+ st1 = mloopuv[lt->tri[1]];
+ st2 = mloopuv[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
@@ -957,7 +957,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
{
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly;
- MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV);
+ float(*mloopuv)[2] = lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2);
MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
float uv[2], *st0, *st1, *st2, *st3;
int pixel = ibuf->x * y + x;
@@ -966,16 +966,16 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
- st0 = mloopuv[mpoly->loopstart].uv;
- st1 = mloopuv[mpoly->loopstart + 1].uv;
- st2 = mloopuv[mpoly->loopstart + 2].uv;
- st3 = mloopuv[mpoly->loopstart + 3].uv;
+ st0 = mloopuv[mpoly->loopstart];
+ st1 = mloopuv[mpoly->loopstart + 1];
+ st2 = mloopuv[mpoly->loopstart + 2];
+ st3 = mloopuv[mpoly->loopstart + 3];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
- st0 = mloopuv[lt->tri[0]].uv;
- st1 = mloopuv[lt->tri[1]].uv;
- st2 = mloopuv[lt->tri[2]].uv;
+ st0 = mloopuv[lt->tri[0]];
+ st1 = mloopuv[lt->tri[1]];
+ st2 = mloopuv[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
@@ -1218,7 +1218,7 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
{
const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index;
MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly;
- MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV);
+ float (*mloopuv)[2] = lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2);
MAOBakeData *ao_data = (MAOBakeData *)bake_data;
int i, k, perm_ofs;
@@ -1233,16 +1233,16 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
/* ideally we would work on triangles only, however, we rely on quads to get orthogonal
* coordinates for use in grid space (triangle barycentric is not orthogonal) */
if (mpoly->totloop == 4) {
- st0 = mloopuv[mpoly->loopstart].uv;
- st1 = mloopuv[mpoly->loopstart + 1].uv;
- st2 = mloopuv[mpoly->loopstart + 2].uv;
- st3 = mloopuv[mpoly->loopstart + 3].uv;
+ st0 = mloopuv[mpoly->loopstart];
+ st1 = mloopuv[mpoly->loopstart + 1];
+ st2 = mloopuv[mpoly->loopstart + 2];
+ st3 = mloopuv[mpoly->loopstart + 3];
resolve_quad_uv_v2(uv, st, st0, st1, st2, st3);
}
else {
- st0 = mloopuv[lt->tri[0]].uv;
- st1 = mloopuv[lt->tri[1]].uv;
- st2 = mloopuv[lt->tri[2]].uv;
+ st0 = mloopuv[lt->tri[0]];
+ st1 = mloopuv[lt->tri[1]];
+ st2 = mloopuv[lt->tri[2]];
resolve_tri_uv_v2(uv, st, st0, st1, st2);
}
diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc
index 3366111ed33..f5719959658 100644
--- a/source/blender/render/intern/texture_margin.cc
+++ b/source/blender/render/intern/texture_margin.cc
@@ -56,7 +56,7 @@ class TextureMarginMap {
MPoly const *mpoly_;
MLoop const *mloop_;
- MLoopUV const *mloopuv_;
+ float2 const *mloopuv_;
int totpoly_;
int totloop_;
int totedge_;
@@ -67,7 +67,7 @@ class TextureMarginMap {
const float uv_offset[2],
MPoly const *mpoly,
MLoop const *mloop,
- MLoopUV const *mloopuv,
+ float2 const *mloopuv,
int totpoly,
int totloop,
int totedge)
@@ -280,11 +280,11 @@ class TextureMarginMap {
}
private:
- float2 uv_to_xy(MLoopUV const &mloopuv) const
+ float2 uv_to_xy(const float2 &mloopuv) const
{
float2 ret;
- ret.x = (((mloopuv.uv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f));
- ret.y = (((mloopuv.uv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f));
+ ret.x = (((mloopuv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f));
+ ret.y = (((mloopuv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f));
return ret;
}
@@ -489,7 +489,7 @@ static void generate_margin(ImBuf *ibuf,
const MPoly *mpoly;
const MLoop *mloop;
- const MLoopUV *mloopuv;
+ const float2 *mloopuv;
int totpoly, totloop, totedge;
int tottri;
@@ -505,12 +505,12 @@ static void generate_margin(ImBuf *ibuf,
mloop = me->loops().data();
if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) {
- mloopuv = static_cast<const MLoopUV *>(CustomData_get_layer(&me->ldata, CD_MLOOPUV));
+ mloopuv = static_cast<const float2 *>(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2));
}
else {
- int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer);
- mloopuv = static_cast<const MLoopUV *>(
- CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id));
+ int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer);
+ mloopuv = static_cast<const float2 *>(
+ CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id));
}
tottri = poly_to_tri_count(me->totpoly, me->totloop);
@@ -527,7 +527,7 @@ static void generate_margin(ImBuf *ibuf,
totloop = dm->getNumLoops(dm);
mpoly = dm->getPolyArray(dm);
mloop = dm->getLoopArray(dm);
- mloopuv = (MLoopUV const *)dm->getLoopDataArray(dm, CD_MLOOPUV);
+ mloopuv = static_cast<const float2 *>(dm->getLoopDataArray(dm, CD_PROP_FLOAT2));
looptri = dm->getLoopTriArray(dm);
tottri = dm->getNumLoopTri(dm);
@@ -552,7 +552,7 @@ static void generate_margin(ImBuf *ibuf,
float vec[3][2];
for (int a = 0; a < 3; a++) {
- const float *uv = mloopuv[lt->tri[a]].uv;
+ const float *uv = mloopuv[lt->tri[a]];
/* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw up
* our intersection tests where a pixel gets in between 2 faces or the middle of a quad,