[Bf-blender-cvs] [6c774feba2c] master: Mesh: Move UV layers to generic attributes

Martijn Versteegh noreply at git.blender.org
Tue Jan 10 07:02:35 CET 2023


Commit: 6c774feba2c9a1eb5834646f597a0f2c63177914
Author: Martijn Versteegh
Date:   Tue Jan 10 00:47:04 2023 -0500
Branches: master
https://developer.blender.org/rB6c774feba2c9a1eb5834646f597a0f2c63177914

Mesh: Move UV layers to generic attributes

Currently the `MLoopUV` struct stores UV coordinates and flags related
to editing UV maps in the UV editor. This patch changes the coordinates
to use the generic 2D vector type, and moves the flags into three
separate boolean attributes. This follows the design in T95965, with
the ultimate intention of simplifying code and improving performance.

Importantly, the change allows exporters and renderers to use UVs
"touched" by geometry nodes, which only creates generic attributes.
It also allows geometry nodes to create "proper" UV maps from scratch,
though only with the Store Named Attribute node for now.

The new design considers any 2D vector attribute on the corner domain
to be a UV map. In the future, they might be distinguished from regular
2D vectors with attribute metadata, which may be helpful because they
are often interpolated differently.

Most of the code changes deal with passing around UV BMesh custom data
offsets and tracking the boolean "sublayers". The boolean layers are
use the following prefixes for attribute names: vert selection: `.vs.`,
edge selection: `.es.`, pinning: `.pn.`. Currently these are short to
avoid using up the maximum length of attribute names. To accommodate
for these 4 extra characters, the name length limit is enlarged to 68
bytes, while the maximum user settable name length is still 64 bytes.

Unfortunately Python/RNA API access to the UV flag data becomes slower.
Accessing the boolean layers directly is be better for performance in
general.

Like the other mesh SoA refactors, backward and forward compatibility
aren't affected, and won't be changed until 4.0. We pay for that by
making mesh reading and writing more expensive with conversions.

Resolves T85962

Differential Revision: https://developer.blender.org/D14365

===================================================================

M	release/scripts/startup/bl_ui/properties_data_mesh.py
M	source/blender/blenkernel/BKE_attribute.h
M	source/blender/blenkernel/BKE_customdata.h
M	source/blender/blenkernel/BKE_editmesh_tangent.h
M	source/blender/blenkernel/BKE_mesh.h
M	source/blender/blenkernel/BKE_mesh_legacy_convert.h
M	source/blender/blenkernel/BKE_mesh_mapping.h
M	source/blender/blenkernel/BKE_mesh_tangent.h
M	source/blender/blenkernel/intern/DerivedMesh.cc
M	source/blender/blenkernel/intern/attribute.cc
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/attribute_access_intern.hh
M	source/blender/blenkernel/intern/customdata.cc
M	source/blender/blenkernel/intern/data_transfer.cc
M	source/blender/blenkernel/intern/dynamicpaint.c
M	source/blender/blenkernel/intern/editmesh_tangent.cc
M	source/blender/blenkernel/intern/fluid.c
M	source/blender/blenkernel/intern/geometry_component_mesh.cc
M	source/blender/blenkernel/intern/layer_utils.c
M	source/blender/blenkernel/intern/mesh.cc
M	source/blender/blenkernel/intern/mesh_convert.cc
M	source/blender/blenkernel/intern/mesh_evaluate.cc
M	source/blender/blenkernel/intern/mesh_legacy_convert.cc
M	source/blender/blenkernel/intern/mesh_mapping.cc
M	source/blender/blenkernel/intern/mesh_merge_customdata.cc
M	source/blender/blenkernel/intern/mesh_mirror.cc
M	source/blender/blenkernel/intern/mesh_tangent.cc
M	source/blender/blenkernel/intern/mesh_validate.cc
M	source/blender/blenkernel/intern/object_dupli.cc
M	source/blender/blenkernel/intern/object_update.cc
M	source/blender/blenkernel/intern/paint_canvas.cc
M	source/blender/blenkernel/intern/pbvh_pixels.cc
M	source/blender/blenkernel/intern/pbvh_uv_islands.cc
M	source/blender/blenkernel/intern/pbvh_uv_islands.hh
M	source/blender/blenkernel/intern/subdiv_converter_mesh.c
M	source/blender/blenkernel/intern/subdiv_eval.c
M	source/blender/blenkernel/intern/subdiv_mesh.cc
M	source/blender/blenkernel/intern/subsurf_ccg.c
M	source/blender/blenloader/intern/versioning_280.c
M	source/blender/blenloader/intern/versioning_400.cc
M	source/blender/blenloader/intern/versioning_defaults.cc
M	source/blender/bmesh/bmesh.h
M	source/blender/bmesh/bmesh_class.h
M	source/blender/bmesh/intern/bmesh_interp.c
M	source/blender/bmesh/intern/bmesh_interp.h
M	source/blender/bmesh/intern/bmesh_mesh_convert.cc
M	source/blender/bmesh/intern/bmesh_polygon.c
M	source/blender/bmesh/intern/bmesh_query_uv.cc
M	source/blender/bmesh/intern/bmesh_query_uv.h
M	source/blender/bmesh/operators/bmo_join_triangles.c
M	source/blender/bmesh/operators/bmo_mirror.c
M	source/blender/bmesh/operators/bmo_primitive.c
M	source/blender/bmesh/operators/bmo_utils.c
M	source/blender/bmesh/tools/bmesh_bevel.c
M	source/blender/bmesh/tools/bmesh_decimate_dissolve.c
M	source/blender/bmesh/tools/bmesh_path_uv.c
M	source/blender/draw/engines/overlay/overlay_edit_uv.cc
M	source/blender/draw/engines/workbench/workbench_engine.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache_impl_mesh.cc
M	source/blender/draw/intern/draw_cache_impl_particles.c
M	source/blender/draw/intern/draw_manager_data.cc
M	source/blender/draw/intern/draw_pbvh.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh.hh
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc
M	source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc
M	source/blender/editors/curves/intern/curves_ops.cc
M	source/blender/editors/geometry/geometry_attributes.cc
M	source/blender/editors/include/ED_mesh.h
M	source/blender/editors/include/ED_uvedit.h
M	source/blender/editors/mesh/editface.cc
M	source/blender/editors/mesh/editmesh_select.cc
M	source/blender/editors/mesh/editmesh_utils.c
M	source/blender/editors/mesh/mesh_data.cc
M	source/blender/editors/mesh/meshtools.cc
M	source/blender/editors/object/object_add.cc
M	source/blender/editors/object/object_bake.c
M	source/blender/editors/object/object_bake_api.c
M	source/blender/editors/object/object_data_transfer.c
M	source/blender/editors/sculpt_paint/paint_image_proj.cc
M	source/blender/editors/sculpt_paint/paint_utils.c
M	source/blender/editors/sculpt_paint/sculpt_uv.c
M	source/blender/editors/space_view3d/view3d_draw.cc
M	source/blender/editors/transform/transform_convert_mesh_uv.c
M	source/blender/editors/uvedit/uvedit_buttons.c
M	source/blender/editors/uvedit/uvedit_clipboard.cc
M	source/blender/editors/uvedit/uvedit_intern.h
M	source/blender/editors/uvedit/uvedit_islands.cc
M	source/blender/editors/uvedit/uvedit_ops.c
M	source/blender/editors/uvedit/uvedit_path.c
M	source/blender/editors/uvedit/uvedit_rip.c
M	source/blender/editors/uvedit/uvedit_select.c
M	source/blender/editors/uvedit/uvedit_smart_stitch.c
M	source/blender/editors/uvedit/uvedit_unwrap_ops.c
M	source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
M	source/blender/gpu/GPU_material.h
M	source/blender/gpu/intern/gpu_vertex_format.cc
M	source/blender/io/alembic/exporter/abc_writer_mesh.cc
M	source/blender/io/alembic/intern/abc_customdata.cc
M	source/blender/io/alembic/intern/abc_customdata.h
M	source/blender/io/alembic/intern/abc_reader_mesh.cc
M	source/blender/io/collada/EffectExporter.cpp
M	source/blender/io/collada/GeometryExporter.cpp
M	source/blender/io/collada/InstanceWriter.cpp
M	source/blender/io/collada/MeshImporter.cpp
M	source/blender/io/collada/MeshImporter.h
M	source/blender/io/collada/collada_utils.cpp
M	source/blender/io/usd/intern/usd_reader_mesh.cc
M	source/blender/io/usd/intern/usd_writer_abstract.cc
M	source/blender/io/usd/intern/usd_writer_mesh.cc
M	source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc
M	source/blender/io/wavefront_obj/importer/obj_import_mesh.cc
M	source/blender/io/wavefront_obj/tests/obj_importer_tests.cc
M	source/blender/makesdna/DNA_customdata_types.h
M	source/blender/makesdna/DNA_dynamicpaint_types.h
M	source/blender/makesdna/DNA_fluid_types.h
M	source/blender/makesdna/DNA_meshdata_types.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesdna/DNA_particle_types.h
M	source/blender/makesdna/DNA_texture_types.h
M	source/blender/makesrna/intern/rna_attribute.c
M	source/blender/makesrna/intern/rna_mesh.c
M	source/blender/makesrna/intern/rna_mesh_api.c
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_particle.c
M	source/blender/modifiers/intern/MOD_array.cc
M	source/blender/modifiers/intern/MOD_dynamicpaint.c
M	source/blender/modifiers/intern/MOD_ocean.c
M	source/blender/modifiers/intern/MOD_screw.cc
M	source/blender/modifiers/intern/MOD_util.cc
M	source/blender/modifiers/intern/MOD_uvproject.cc
M	source/blender/modifiers/intern/MOD_uvwarp.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc
M	source/blender/python/bmesh/bmesh_py_types_customdata.c
M	source/blender/python/bmesh/bmesh_py_types_meshdata.c
M	source/blender/python/bmesh/bmesh_py_types_meshdata.h
M	source/blender/render/RE_bake.h
M	source/blender/render/RE_texture_margin.h
M	source/blender/render/intern/bake.cc
M	source/blender/render/intern/multires_bake.cc
M	source/blender/render/intern/texture_margin.cc

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py
index b7f7d925c2b..61027f68f19 100644
--- a/release/scripts/startup/bl_ui/properties_data_mesh.py
+++ b/release/scripts/startup/bl_ui/properties_data_mesh.py
@@ -607,7 +607,6 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel):
                 # Built-in names.
                 {"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 eef1459be81..7c01a9205fc 100644
--- a/source/blender/blenkernel/BKE_attribute.h
+++ b/source/blender/blenkernel/BKE_attribute.h
@@ -131,6 +131,10 @@ 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);
 
+const char *BKE_uv_map_vert_select_name_get(const char *uv_map_name, char *buffer);
+const char *BKE_uv_map_edge_select_name_get(const char *uv_map_name, char *buffer);
+const char *BKE_uv_map_pin_name_get(const char *uv_map_name, char *buffer);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 582dd1b5a29..b97ac9cc9b9 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -31,6 +31,28 @@ struct CustomData_MeshMasks;
 struct ID;
 typedef uint64_t eCustomDataMask;
 
+/* These names are used as prefixes for UV layer names to find the associated boolean
+ * layers. They should never be longer than 2 chars, as MAX_CUSTOMDATA_LAYER_NAME
+ * has 4 extra bytes above what can be used for the base layer name, and these
+ * prefixes are placed between 2 '.'s at the start of the layer name.
+ * For example The uv vert selection layer of a layer named 'UVMap.001'
+ * will be called '.vs.UVMap.001' . */
+#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.
+ * An offset of -1 means that the corresponding layer does not exist.
+ */
+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];
@@ -125,7 +147,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);
@@ -422,6 +444,7 @@ int CustomData_get_n_offset(const struct CustomData *data, int type, int n);
 int CustomData_get_layer_index(const struct CustomData *data, int type);
 int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
 int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name);
+int CustomData_get_named_layer_index_notype(const struct CustomData *data, const char *name);
 int CustomData_get_active_layer_index(const struct CustomData *data, int type);
 int CustomData_get_render_layer_index(const struct CustomData *data, int type);
 int CustomData_get_clone_layer_index(const struct CustomData *data, int type);
@@ -531,6 +554,13 @@ bool CustomData_layertype_is_dynamic(int type);
  */
 int CustomData_layertype_layers_max(int type);
 
+#ifdef __cplusplus
+
+/** \return The maximum length for a layer name with the given prefix. */
+int CustomData_name_max_length_calc(blender::StringRef name);
+
+#endif
+
 /**
  * Make sure the name of layer at index is unique.
  */
@@ -604,8 +634,9 @@ 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_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..c2697ec38b0 100644
--- a/source/blender/blenkernel/BKE_editmesh_tangent.h
+++ b/source/blender/blenkernel/BKE_editmesh_tangent.h
@@ -9,6 +9,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+#include "DNA_customdata_types.h"
 
 /**
  * \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data.
@@ -19,7 +20,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)[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 cd291d4a42d..ffca4cff347 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 Main;
 struct MemArena;
@@ -693,7 +692,6 @@ float BKE_mesh_calc_poly_area(const struct MPoly *mpoly,
                               const struct MLoop *loopstart,
                               const float (*vert_positions)[3]);
 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 float (*vert_positions)[3],
diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
index a561cf9e8fd..3b1b94e516a 100644
--- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h
+++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h
@@ -26,6 +26,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 b70e05ed14f..36ac0708629 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;
 
 /* UvVertMap */
@@ -105,7 +104,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],
@@ -288,7 +287,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3],
 /**
  * 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,
@@ -306,7 +305,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
                                            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 cec98da5ef6..b30ce13da8d 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 float (*vert_positions)[3],
                                           const struct MLoop *mloops,
                                           float (*r_looptangent)[4],
                                           const float (*loop_normals)[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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list