diff options
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 ¤t_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 ¤t_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, |