WIP: Mesh: Store active and default UV map with strings #105779

Closed
Hans Goudey wants to merge 12 commits from HooglyBoogly:mesh-uv-active-string into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
60 changed files with 821 additions and 434 deletions

View File

@ -114,6 +114,9 @@ const char *BKE_id_attributes_default_color_name(const struct ID *id);
void BKE_id_attributes_active_color_set(struct ID *id, const char *name);
void BKE_id_attributes_default_color_set(struct ID *id, const char *name);
void BKE_id_attributes_active_uv_set(struct ID *id, const char *name);
void BKE_id_attributes_default_uv_set(struct ID *id, const char *name);
struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const char *name);
bool BKE_id_attribute_calc_unique_name(struct ID *id, const char *name, char *outname);

View File

@ -19,6 +19,8 @@ extern "C" {
* This is done because #CD_TANGENT is cache data used only for drawing.
*/
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,

View File

@ -747,6 +747,9 @@ char *BKE_mesh_debug_info(const struct Mesh *me)
void BKE_mesh_debug_print(const struct Mesh *me) ATTR_NONNULL(1);
#endif
const float (*BKE_mesh_get_uv_map_or_active(const struct Mesh *mesh, const char *name))[2];
float (*BKE_mesh_get_uv_map_or_active_for_write(struct Mesh *mesh, const char *name))[2];
/* -------------------------------------------------------------------- */
/** \name Inline Mesh Data Access
* \{ */

View File

@ -51,6 +51,8 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const bool *sharp_faces,
struct CustomData *loopdata,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
@ -82,6 +84,8 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(struct CustomData *uv_data,
* If tangent_mask has changed, then recalculate tangents.
*/
void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_count,
@ -89,8 +93,6 @@ void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData,
bool *rcalc_ren,
int *ract_uv_n,
int *rren_uv_n,
char *ract_uv_name,
char *rren_uv_name,
short *rtangent_mask);
#ifdef __cplusplus

View File

@ -191,30 +191,48 @@ 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 (GS(id->name) == ID_ME) {
Mesh &mesh = reinterpret_cast<Mesh &>(*id);
if (layer->type == CD_PROP_FLOAT2) {
/* Rename UV sub-attributes. */
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
if (layer->type == CD_PROP_FLOAT2 && GS(id->name) == ID_ME) {
/* Rename UV sub-attributes. */
char buffer_src[MAX_CUSTOMDATA_LAYER_NAME];
char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME];
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_vert_select_name_get(layer->name, buffer_src),
BKE_uv_map_vert_select_name_get(result_name, buffer_dst),
reports);
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_edge_select_name_get(layer->name, buffer_src),
BKE_uv_map_edge_select_name_get(result_name, buffer_dst),
reports);
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_pin_name_get(layer->name, buffer_src),
BKE_uv_map_pin_name_get(result_name, buffer_dst),
reports);
}
if (StringRef(old_name) == BKE_id_attributes_active_color_name(id)) {
BKE_id_attributes_active_color_set(id, result_name);
}
if (StringRef(old_name) == BKE_id_attributes_default_color_name(id)) {
BKE_id_attributes_default_color_set(id, result_name);
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_vert_select_name_get(layer->name, buffer_src),
BKE_uv_map_vert_select_name_get(result_name, buffer_dst),
reports);
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_edge_select_name_get(layer->name, buffer_src),
BKE_uv_map_edge_select_name_get(result_name, buffer_dst),
reports);
bke_id_attribute_rename_if_exists(id,
BKE_uv_map_pin_name_get(layer->name, buffer_src),
BKE_uv_map_pin_name_get(result_name, buffer_dst),
reports);
if (const char *name = mesh.active_uv_attribute) {
if (StringRef(old_name) == name) {
BKE_id_attributes_active_uv_set(id, result_name);
}
}
if (const char *name = mesh.default_uv_attribute) {
if (StringRef(old_name) == name) {
BKE_id_attributes_default_uv_set(id, result_name);
}
}
}
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_COLOR_ALL) {
if (const char *name = mesh.active_color_attribute) {
if (StringRef(old_name) == name) {
BKE_id_attributes_active_color_set(id, result_name);
}
}
if (const char *name = mesh.default_color_attribute) {
if (StringRef(old_name) == name) {
BKE_id_attributes_default_color_set(id, result_name);
}
}
}
}
BLI_strncpy_utf8(layer->name, result_name, sizeof(layer->name));
@ -393,6 +411,26 @@ static const char *color_name_from_index(ID *id, int index)
return layer ? layer->name : nullptr;
}
static int uv_name_to_index(ID *id, const char *name)
{
const CustomDataLayer *layer = BKE_id_attribute_search(
id, name, CD_MASK_PROP_FLOAT2, ATTR_DOMAIN_MASK_CORNER);
return BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_CORNER, CD_MASK_PROP_FLOAT2);
}
static int uv_clamp_index(ID *id, int index)
{
const int length = BKE_id_attributes_length(id, ATTR_DOMAIN_MASK_CORNER, CD_MASK_PROP_FLOAT2);
return min_ii(index, length - 1);
}
static const char *uv_name_from_index(ID *id, int index)
{
const CustomDataLayer *layer = BKE_id_attribute_from_index(
id, index, ATTR_DOMAIN_MASK_CORNER, CD_MASK_PROP_FLOAT2);
return layer ? layer->name : nullptr;
}
bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
{
using namespace blender;
@ -427,6 +465,10 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
StringRef(mesh->default_color_attribute);
const int active_color_index = color_name_to_index(id, mesh->active_color_attribute);
const int default_color_index = color_name_to_index(id, mesh->default_color_attribute);
const bool is_active_uv = name_copy.c_str() == StringRef(mesh->active_uv_attribute);
const bool is_default_uv = name_copy.c_str() == StringRef(mesh->default_uv_attribute);
const int active_uv_index = uv_name_to_index(id, mesh->active_uv_attribute);
const int default_uv_index = uv_name_to_index(id, mesh->default_uv_attribute);
if (!BM_data_layer_free_named(em->bm, data, name_copy.c_str())) {
BLI_assert_unreachable();
@ -449,6 +491,14 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
em->bm, data, BKE_uv_map_edge_select_name_get(name_copy.c_str(), buffer));
BM_data_layer_free_named(
em->bm, data, BKE_uv_map_pin_name_get(name_copy.c_str(), buffer));
if (is_active_uv) {
BKE_id_attributes_active_uv_set(
id, uv_name_from_index(id, uv_clamp_index(id, active_uv_index)));
}
if (is_default_uv) {
BKE_id_attributes_default_uv_set(
id, uv_name_from_index(id, uv_clamp_index(id, default_uv_index)));
}
}
return true;
}
@ -475,6 +525,10 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
const bool is_default_color_attribute = name_copy == StringRef(mesh->default_color_attribute);
const int active_color_index = color_name_to_index(id, mesh->active_color_attribute);
const int default_color_index = color_name_to_index(id, mesh->default_color_attribute);
const bool is_active_uv = name_copy.c_str() == StringRef(mesh->active_uv_attribute);
const bool is_default_uv = name_copy.c_str() == StringRef(mesh->default_uv_attribute);
const int active_uv_index = uv_name_to_index(id, mesh->active_uv_attribute);
const int default_uv_index = uv_name_to_index(id, mesh->default_uv_attribute);
if (!attributes->remove(name_copy)) {
BLI_assert_unreachable();
@ -494,6 +548,14 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports)
attributes->remove(BKE_uv_map_vert_select_name_get(name_copy.c_str(), buffer));
attributes->remove(BKE_uv_map_edge_select_name_get(name_copy.c_str(), buffer));
attributes->remove(BKE_uv_map_pin_name_get(name_copy.c_str(), buffer));
if (is_active_uv) {
BKE_id_attributes_active_uv_set(
id, uv_name_from_index(id, uv_clamp_index(id, active_uv_index)));
}
if (is_default_uv) {
BKE_id_attributes_default_uv_set(
id, uv_name_from_index(id, uv_clamp_index(id, default_uv_index)));
}
}
return true;
}
@ -868,6 +930,38 @@ void BKE_id_attributes_default_color_set(ID *id, const char *name)
}
}
void BKE_id_attributes_active_uv_set(ID *id, const char *name)
{
switch (GS(id->name)) {
case ID_ME: {
Mesh *mesh = reinterpret_cast<Mesh *>(id);
MEM_SAFE_FREE(mesh->active_uv_attribute);
if (name) {
mesh->active_uv_attribute = BLI_strdup(name);
}
break;
}
default:
break;
}
}
void BKE_id_attributes_default_uv_set(ID *id, const char *name)
{
switch (GS(id->name)) {
case ID_ME: {
Mesh *mesh = reinterpret_cast<Mesh *>(id);
MEM_SAFE_FREE(mesh->default_uv_attribute);
if (name) {
mesh->default_uv_attribute = BLI_strdup(name);
}
break;
}
default:
break;
}
}
CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name)
{
if (CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT)) {

View File

@ -345,6 +345,46 @@ static void data_transfer_mesh_attributes_transfer_default_color_string(
}
}
static void data_transfer_mesh_attributes_transfer_active_uv_string(Mesh *mesh_dst,
const Mesh *mesh_src)
{
if (mesh_dst->active_uv_attribute) {
return;
}
const char *name = mesh_src->active_uv_attribute;
if (!BKE_id_attribute_find(&mesh_src->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER)) {
return;
}
if (BKE_id_attribute_find(&mesh_dst->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER)) {
BKE_id_attributes_active_uv_set(&mesh_dst->id, name);
}
else {
if (const char *name = CustomData_get_layer_name(&mesh_dst->ldata, CD_PROP_FLOAT2, 0)) {
BKE_id_attributes_active_uv_set(&mesh_dst->id, name);
}
}
}
static void data_transfer_mesh_attributes_transfer_default_uv_string(Mesh *mesh_dst,
const Mesh *mesh_src)
{
if (mesh_dst->default_uv_attribute) {
return;
}
const char *name = mesh_src->default_uv_attribute;
if (!BKE_id_attribute_find(&mesh_src->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER)) {
return;
}
if (BKE_id_attribute_find(&mesh_dst->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER)) {
BKE_id_attributes_default_uv_set(&mesh_dst->id, name);
}
else {
if (const char *name = CustomData_get_layer_name(&mesh_dst->ldata, CD_PROP_FLOAT2, 0)) {
BKE_id_attributes_default_uv_set(&mesh_dst->id, name);
}
}
}
/* ********** */
/* Generic pre/post processing, only used by custom loop normals currently. */
@ -1033,7 +1073,24 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
}
else if (elem_type == ME_LOOP) {
if (cddata_type == CD_FAKE_UV) {
cddata_type = CD_PROP_FLOAT2;
if (const char *name = me_src->active_uv_attribute) {
if (!CustomData_get_layer_named(&me_dst->ldata, CD_PROP_FLOAT2, name)) {
CustomData_add_layer_named(
&me_dst->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, me_dst->totpoly, name);
}
data_transfer_layersmapping_add_item_cd(
r_map,
CD_PROP_FLOAT2,
mix_mode,
mix_factor,
mix_weights,
CustomData_get_layer_named(&me_src->ldata, CD_PROP_FLOAT2, name),
CustomData_get_layer_named_for_write(
&me_dst->ldata, CD_PROP_FLOAT2, name, num_elem_dst),
interp,
interp_data);
}
return true;
}
else if (cddata_type == CD_FAKE_LNOR) {
/* Pre-process should have generated it,
@ -1246,6 +1303,10 @@ void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph,
data_transfer_mesh_attributes_transfer_default_color_string(
me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
}
else if (cddata_type == CD_PROP_FLOAT2) {
data_transfer_mesh_attributes_transfer_active_uv_string(me_dst, me_src);
data_transfer_mesh_attributes_transfer_default_uv_string(me_dst, me_src);
}
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
const int num_elem_dst = me_dst->totpoly;

View File

@ -1621,17 +1621,11 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
const blender::Span<int> corner_verts = mesh->corner_verts();
const blender::Span<MLoopTri> looptris = mesh->looptris();
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
if (!tex) {
return;
}
/* get uv map */
CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->init_layername, uvname);
const float(*mloopuv)[2] = static_cast<const float(*)[2]>(
CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname));
const float(*mloopuv)[2] = BKE_mesh_get_uv_map_or_active(mesh, surface->init_layername);
if (!mloopuv) {
return;
}
@ -2803,7 +2797,6 @@ int dynamicPaint_createUVSurface(Scene *scene,
{
/* Anti-alias jitter point relative coords. */
const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
uint32_t active_points = 0;
bool error = false;
@ -2813,7 +2806,6 @@ int dynamicPaint_createUVSurface(Scene *scene,
PaintUVPoint *tempPoints = nullptr;
Vec3f *tempWeights = nullptr;
const float(*mloopuv)[2] = nullptr;
Bounds2D *faceBB = nullptr;
int *final_index;
@ -2831,12 +2823,12 @@ int dynamicPaint_createUVSurface(Scene *scene,
const blender::Span<int> corner_verts = mesh->corner_verts();
const blender::Span<MLoopTri> looptris = mesh->looptris();
/* get uv map */
if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname);
mloopuv = static_cast<const float(*)[2]>(
CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname));
const char *uvname = mesh->active_uv_attribute;
if (!uvname) {
return setError(canvas, N_("No UV data on canvas"));
}
const float(*mloopuv)[2] = static_cast<const float(*)[2]>(
CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname));
/* Check for validity */
if (!mloopuv) {

View File

@ -150,6 +150,8 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void *
}
void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
@ -167,12 +169,12 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
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];
short tangent_mask = 0;
short tangent_mask_curr = *tangent_mask_curr_p;
BKE_mesh_calc_loop_tangent_step_0(&bm->ldata,
active_uv_name,
default_uv_name,
calc_active_tangent,
tangent_names,
tangent_names_len,
@ -180,8 +182,6 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
&calc_ren,
&act_uv_n,
&ren_uv_n,
act_uv_name,
ren_uv_name,
&tangent_mask);
if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
@ -196,13 +196,13 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em,
CustomData_add_layer_named(
loopdata_out, CD_TANGENT, CD_SET_DEFAULT, int(loopdata_out_len), "");
}
if (calc_act && act_uv_name[0]) {
if (calc_act && active_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
&bm->ldata, loopdata_out, int(loopdata_out_len), act_uv_name);
&bm->ldata, loopdata_out, int(loopdata_out_len), active_uv_name);
}
if (calc_ren && ren_uv_name[0]) {
if (calc_ren && default_uv_name[0]) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
&bm->ldata, loopdata_out, int(loopdata_out_len), ren_uv_name);
&bm->ldata, loopdata_out, int(loopdata_out_len), default_uv_name);
}
int totface = em->tottri;
#ifdef USE_LOOPTRI_DETECT_QUADS

View File

@ -150,6 +150,10 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
MEM_dupallocN(mesh_src->active_color_attribute));
mesh_dst->default_color_attribute = static_cast<char *>(
MEM_dupallocN(mesh_src->default_color_attribute));
mesh_dst->active_uv_attribute = static_cast<char *>(
MEM_dupallocN(mesh_src->active_uv_attribute));
mesh_dst->default_uv_attribute = static_cast<char *>(
MEM_dupallocN(mesh_src->default_uv_attribute));
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert);
@ -284,6 +288,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
BKE_mesh_legacy_attribute_strings_to_flags(mesh);
mesh->active_color_attribute = nullptr;
mesh->default_color_attribute = nullptr;
mesh->active_uv_attribute = nullptr;
mesh->default_uv_attribute = nullptr;
BKE_mesh_legacy_convert_loose_edges_to_flag(mesh);
/* Set deprecated mesh data pointers for forward compatibility. */
@ -316,6 +322,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
BKE_defbase_blend_write(writer, &mesh->vertex_group_names);
BLO_write_string(writer, mesh->active_color_attribute);
BLO_write_string(writer, mesh->default_color_attribute);
BLO_write_string(writer, mesh->active_uv_attribute);
BLO_write_string(writer, mesh->default_uv_attribute);
BLO_write_pointer_array(writer, mesh->totcol, mesh->mat);
BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
@ -367,6 +375,8 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
}
BLO_read_data_address(reader, &mesh->active_color_attribute);
BLO_read_data_address(reader, &mesh->default_color_attribute);
BLO_read_data_address(reader, &mesh->active_uv_attribute);
BLO_read_data_address(reader, &mesh->default_uv_attribute);
mesh->texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO_EVALUATED;
mesh->edit_mesh = nullptr;
@ -917,6 +927,8 @@ static void mesh_clear_geometry(Mesh *mesh)
BLI_freelistN(&mesh->vertex_group_names);
MEM_SAFE_FREE(mesh->active_color_attribute);
MEM_SAFE_FREE(mesh->default_color_attribute);
MEM_SAFE_FREE(mesh->active_uv_attribute);
MEM_SAFE_FREE(mesh->default_uv_attribute);
}
void BKE_mesh_clear_geometry(Mesh *mesh)
@ -992,13 +1004,17 @@ Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int loops_len, int polys
static void copy_attribute_names(const Mesh &mesh_src, Mesh &mesh_dst)
{
if (mesh_src.active_color_attribute) {
MEM_SAFE_FREE(mesh_dst.active_color_attribute);
mesh_dst.active_color_attribute = BLI_strdup(mesh_src.active_color_attribute);
if (const char *name = mesh_src.active_color_attribute) {
BKE_id_attributes_active_color_set(&mesh_dst.id, name);
}
if (mesh_src.default_color_attribute) {
MEM_SAFE_FREE(mesh_dst.default_color_attribute);
mesh_dst.default_color_attribute = BLI_strdup(mesh_src.default_color_attribute);
if (const char *name = mesh_src.default_color_attribute) {
BKE_id_attributes_default_color_set(&mesh_dst.id, name);
}
if (const char *name = mesh_src.active_uv_attribute) {
BKE_id_attributes_active_uv_set(&mesh_dst.id, name);
}
if (const char *name = mesh_src.default_uv_attribute) {
BKE_id_attributes_default_uv_set(&mesh_dst.id, name);
}
}
@ -1855,6 +1871,38 @@ void BKE_mesh_calc_normals_split(Mesh *mesh)
BKE_mesh_calc_normals_split_ex(mesh, nullptr, ensure_corner_normal_layer(*mesh));
}
const float (*BKE_mesh_get_uv_map_or_active(const Mesh *mesh, const char *name))[2]
{
if (name) {
if (const void *uvs = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, name)) {
return reinterpret_cast<const float(*)[2]>(uvs);
}
}
if (const char *name = mesh->active_uv_attribute) {
if (const void *uvs = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, name)) {
return reinterpret_cast<const float(*)[2]>(uvs);
}
}
return nullptr;
}
float (*BKE_mesh_get_uv_map_or_active_for_write(Mesh *mesh, const char *name))[2]
{
if (name) {
if (void *uvs = CustomData_get_layer_named_for_write(
&mesh->ldata, CD_PROP_FLOAT2, name, mesh->totloop)) {
return reinterpret_cast<float(*)[2]>(uvs);
}
}
if (const char *name = mesh->active_uv_attribute) {
if (void *uvs = CustomData_get_layer_named_for_write(
&mesh->ldata, CD_PROP_FLOAT2, name, mesh->totloop)) {
return reinterpret_cast<float(*)[2]>(uvs);
}
}
return nullptr;
}
/* **** Depsgraph evaluation **** */
void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh)

View File

@ -1141,13 +1141,17 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop);
/* Make sure active/default color attribute (names) are brought over. */
if (mesh_src->active_color_attribute) {
MEM_SAFE_FREE(mesh_dst->active_color_attribute);
mesh_dst->active_color_attribute = BLI_strdup(mesh_src->active_color_attribute);
if (const char *name = mesh_src->active_color_attribute) {
BKE_id_attributes_active_color_set(&mesh_dst->id, name);
}
if (mesh_src->default_color_attribute) {
MEM_SAFE_FREE(mesh_dst->default_color_attribute);
mesh_dst->default_color_attribute = BLI_strdup(mesh_src->default_color_attribute);
if (const char *name = mesh_src->default_color_attribute) {
BKE_id_attributes_default_color_set(&mesh_dst->id, name);
}
if (const char *name = mesh_src->active_uv_attribute) {
BKE_id_attributes_active_uv_set(&mesh_dst->id, name);
}
if (const char *name = mesh_src->default_uv_attribute) {
BKE_id_attributes_default_uv_set(&mesh_dst->id, name);
}
BLI_freelistN(&mesh_dst->vertex_group_names);

View File

@ -543,11 +543,15 @@ static void update_active_fdata_layers(Mesh &mesh, CustomData *fdata, CustomData
int act;
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);
if (const char *name = mesh.active_uv_attribute) {
act = CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name);
CustomData_set_layer_active(fdata, CD_MTFACE, act);
}
act = CustomData_get_render_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_render(fdata, CD_MTFACE, act);
if (const char *name = mesh.active_uv_attribute) {
act = CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name);
CustomData_set_layer_render(fdata, CD_MTFACE, act);
}
act = CustomData_get_clone_layer(ldata, CD_PROP_FLOAT2);
CustomData_set_layer_clone(fdata, CD_MTFACE, act);
@ -2085,6 +2089,19 @@ void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh)
default_from_flags(mesh->ldata);
default_from_indices(mesh->vdata);
default_from_indices(mesh->ldata);
if (!mesh->active_uv_attribute) {
const int i = CustomData_get_active_layer_index(&mesh->ldata, CD_PROP_FLOAT2);
if (i != -1) {
mesh->active_uv_attribute = BLI_strdup(mesh->ldata.layers[i].name);
}
}
if (!mesh->default_uv_attribute) {
const int i = CustomData_get_render_layer_index(&mesh->ldata, CD_PROP_FLOAT2);
if (i != -1) {
mesh->default_uv_attribute = BLI_strdup(mesh->ldata.layers[i].name);
}
}
}
void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
@ -2097,8 +2114,8 @@ void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER);
int i;
if (const char *name = mesh->active_color_attribute) {
int i;
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_active_index(vdata, CD_PROP_BYTE_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE;
@ -2117,7 +2134,6 @@ void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
}
}
if (const char *name = mesh->default_color_attribute) {
int i;
if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) {
CustomData_set_layer_render_index(vdata, CD_PROP_BYTE_COLOR, i);
vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
@ -2135,6 +2151,16 @@ void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh)
ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER;
}
}
if (const char *name = mesh->active_uv_attribute) {
if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_FLOAT2, name)) != -1) {
CustomData_set_layer_active_index(ldata, CD_PROP_FLOAT2, i);
}
}
if (const char *name = mesh->default_uv_attribute) {
if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_FLOAT2, name)) != -1) {
CustomData_set_layer_render_index(ldata, CD_PROP_FLOAT2, i);
}
}
}
/** \} */

View File

@ -479,13 +479,11 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
}
/* Make sure active/default color attribute (names) are brought over. */
if (source->active_color_attribute) {
MEM_SAFE_FREE(target->active_color_attribute);
target->active_color_attribute = BLI_strdup(source->active_color_attribute);
if (const char *name = source->active_color_attribute) {
BKE_id_attributes_active_color_set(&target->id, name);
}
if (source->default_color_attribute) {
MEM_SAFE_FREE(target->default_color_attribute);
target->default_color_attribute = BLI_strdup(source->default_color_attribute);
if (const char *name = source->default_color_attribute) {
BKE_id_attributes_default_color_set(&target->id, name);
}
MEM_SAFE_FREE(source_lmap);

View File

@ -123,7 +123,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
using namespace blender::bke;
if (!uvmap) {
uvmap = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
uvmap = mesh->active_uv_attribute;
}
const AttributeAccessor attributes = mesh->attributes();
@ -316,6 +316,8 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data,
}
void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_count,
@ -323,23 +325,16 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
bool *rcalc_ren,
int *ract_uv_n,
int *rren_uv_n,
char *ract_uv_name,
char *rren_uv_name,
short *rtangent_mask)
{
/* Active uv in viewport */
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);
if (active_uv_name) {
*ract_uv_n = CustomData_get_named_layer(loopData, CD_PROP_FLOAT2, active_uv_name);
}
/* Active tangent in render */
*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);
if (default_uv_name) {
*rren_uv_n = CustomData_get_named_layer(loopData, CD_PROP_FLOAT2, default_uv_name);
}
/* If active tangent not in tangent_names we take it into account */
@ -354,10 +349,10 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
*rcalc_act = true;
*rcalc_ren = true;
for (int i = 0; i < tangent_names_count; i++) {
if (STREQ(ract_uv_name, tangent_names[i])) {
if (STREQ(active_uv_name, tangent_names[i])) {
*rcalc_act = false;
}
if (STREQ(rren_uv_name, tangent_names[i])) {
if (STREQ(default_uv_name, tangent_names[i])) {
*rcalc_ren = false;
}
}
@ -374,8 +369,8 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData,
break;
}
}
if (!add && ((*rcalc_act && ract_uv_name[0] && STREQ(ract_uv_name, name)) ||
(*rcalc_ren && rren_uv_name[0] && STREQ(rren_uv_name, name)))) {
if (!add && ((*rcalc_act && active_uv_name[0] && STREQ(active_uv_name, name)) ||
(*rcalc_ren && default_uv_name[0] && STREQ(default_uv_name, name)))) {
add = true;
}
if (add) {
@ -397,6 +392,8 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
const bool *sharp_faces,
CustomData *loopdata,
const char *active_uv_name,
const char *default_uv_name,
bool calc_active_tangent,
const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME],
int tangent_names_len,
@ -413,12 +410,12 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
int ren_uv_n = -1;
bool calc_act = false;
bool calc_ren = false;
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;
BKE_mesh_calc_loop_tangent_step_0(loopdata,
active_uv_name,
default_uv_name,
calc_active_tangent,
tangent_names,
tangent_names_len,
@ -426,8 +423,6 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
&calc_ren,
&act_uv_n,
&ren_uv_n,
act_uv_name,
ren_uv_name,
&tangent_mask);
if ((tangent_mask_curr | tangent_mask) != tangent_mask_curr) {
/* Check we have all the needed layers */
@ -443,13 +438,13 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3],
CustomData_add_layer_named(
loopdata_out, CD_TANGENT, CD_SET_DEFAULT, int(loopdata_out_len), "");
}
if (calc_act && act_uv_name[0]) {
if (calc_act && active_uv_name) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
loopdata, loopdata_out, int(loopdata_out_len), act_uv_name);
loopdata, loopdata_out, int(loopdata_out_len), active_uv_name);
}
if (calc_ren && ren_uv_name[0]) {
if (calc_ren && default_uv_name) {
BKE_mesh_add_loop_tangent_named_layer_for_uv(
loopdata, loopdata_out, int(loopdata_out_len), ren_uv_name);
loopdata, loopdata_out, int(loopdata_out_len), default_uv_name);
}
#ifdef USE_LOOPTRI_DETECT_QUADS
@ -588,6 +583,8 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
static_cast<const bool *>(
CustomData_get_layer_named(&me_eval->pdata, CD_PROP_BOOL, "sharp_face")),
&me_eval->ldata,
me_eval->active_uv_attribute,
me_eval->default_uv_attribute,
calc_active_tangent,
tangent_names,
tangent_names_len,

View File

@ -1301,7 +1301,10 @@ 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_PROP_FLOAT2);
const int uv_idx = me_eval->default_uv_attribute ?
CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, me_eval->default_uv_attribute) :
-1;
FaceDupliData_EditMesh fdd{};
fdd.params = fdd_params;
fdd.em = em;
@ -1314,7 +1317,10 @@ static void make_duplis_faces(const DupliContext *ctx)
make_child_duplis(ctx, &fdd, make_child_duplis_faces_from_editmesh);
}
else {
const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_PROP_FLOAT2);
const int uv_idx = me_eval->default_uv_attribute ?
CustomData_get_named_layer(
&me_eval->ldata, CD_PROP_FLOAT2, me_eval->default_uv_attribute) :
-1;
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;

View File

@ -80,7 +80,11 @@ 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_PROP_FLOAT2);
if (!mesh->active_uv_attribute) {
return -1;
}
return CustomData_get_named_layer_index(
&mesh->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
case PAINT_CANVAS_SOURCE_MATERIAL: {
/* Use uv map of the canvas. */

View File

@ -662,7 +662,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
return false;
}
const StringRef active_uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
const StringRef active_uv_name = mesh->active_uv_attribute;
if (active_uv_name.is_empty()) {
return false;
}

View File

@ -1477,6 +1477,7 @@ static BMOpDefine bmo_rotate_uvs_def = {
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to adjust */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@ -1493,6 +1494,7 @@ static BMOpDefine bmo_reverse_uvs_def = {
"reverse_uvs",
/* slots_in */
{{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to adjust */
{{'\0'}},
},
{{{'\0'}}}, /* no output */
@ -1571,7 +1573,7 @@ static BMOpDefine bmo_create_grid_def = {
{"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */
{"size", BMO_OP_SLOT_FLT}, /* size of the grid */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1595,7 +1597,7 @@ static BMOpDefine bmo_create_uvsphere_def = {
{"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */
{"radius", BMO_OP_SLOT_FLT}, /* radius */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1618,7 +1620,7 @@ static BMOpDefine bmo_create_icosphere_def = {
{{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
{"radius", BMO_OP_SLOT_FLT}, /* radius */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1639,7 +1641,7 @@ static BMOpDefine bmo_create_monkey_def = {
"create_monkey",
/* slots_in */
{{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1666,7 +1668,7 @@ static BMOpDefine bmo_create_cone_def = {
{"radius2", BMO_OP_SLOT_FLT}, /* radius of the opposite */
{"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1689,7 +1691,7 @@ static BMOpDefine bmo_create_circle_def = {
{"segments", BMO_OP_SLOT_INT}, /* number of vertices in the circle */
{"radius", BMO_OP_SLOT_FLT}, /* Radius of the circle. */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */
@ -1711,7 +1713,7 @@ static BMOpDefine bmo_create_cube_def = {
/* slots_in */
{{"size", BMO_OP_SLOT_FLT}, /* size of the cube */
{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
{"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
{"uv_index", BMO_OP_SLOT_INT}, /* Index of UV map to fill with default UVs */
{{'\0'}},
},
/* slots_out */

View File

@ -216,7 +216,7 @@ void BM_mesh_calc_uvs_cone(BMesh *bm,
* \param bm: The BMesh to operate on.
* \param oflag: The flag to check faces with.
*/
void BM_mesh_calc_uvs_cube(BMesh *bm, short oflag);
void BM_mesh_calc_uvs_cube(BMesh *bm, short oflag, const int cd_loop_uv_offset);
#include "intern/bmesh_operator_api_inline.h"

View File

@ -719,8 +719,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
BMVert **varr;
BMVert *vquad[4];
@ -760,7 +762,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
vquad[3] = varr[XY(x - 1, y)];
f = BM_face_create_verts(bm, vquad, 4, NULL, BM_CREATE_NOP, true);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
}
@ -768,7 +770,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
#undef XY
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BM_mesh_calc_uvs_grid(bm, xtot, ytot, FACE_MARK, cd_loop_uv_offset);
}
}
@ -836,8 +838,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
BMOperator bmop, prevop;
BMVert *eve, *preveve;
@ -914,7 +918,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
bm, op->flag, "remove_doubles verts=%fv dist=%f", VERT_MARK, min_ff(len, len2) / 3.0f);
}
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMFace *f;
BMLoop *l;
BMIter fiter, liter;
@ -955,8 +959,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
BMVert *eva[12];
BMVert *v;
@ -997,7 +1003,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
/* Set the UVs here, the iteration order of the faces is not guaranteed,
* so it's best to set the UVs right after the face is created. */
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
int loop_index;
BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) {
float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
@ -1159,8 +1165,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
for (i = 0; i < monkeynv; i++) {
float v[3];
@ -1209,7 +1217,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
/* Set the UVs here, the iteration order of the faces is not guaranteed,
* so it's best to set the UVs right after the face is created. */
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMLoop *l;
BMIter liter;
BM_ITER_ELEM (l, &liter, f_new_a, BM_LOOPS_OF_FACE) {
@ -1239,8 +1247,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
float vec[3], mat[4][4];
@ -1301,7 +1311,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, BM_CREATE_NOP);
BMO_face_flag_enable(bm, f, FACE_NEW);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BM_mesh_calc_uvs_circle(bm, mat, radius, FACE_NEW, cd_loop_uv_offset);
}
}
@ -1361,8 +1371,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
if (!segs) {
return;
@ -1413,20 +1425,20 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (i) {
if (cap_ends) {
f = BM_face_create_quad_tri(bm, cent1, lastv1, v1, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
BMO_face_flag_enable(bm, f, FACE_NEW);
f = BM_face_create_quad_tri(bm, cent2, v2, lastv2, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
BMO_face_flag_enable(bm, f, FACE_NEW);
}
f = BM_face_create_quad_tri(bm, lastv1, lastv2, v2, v1, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
side_faces[i - 1] = f;
@ -1442,24 +1454,24 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
if (cap_ends) {
f = BM_face_create_quad_tri(bm, cent1, v1, firstv1, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
BMO_face_flag_enable(bm, f, FACE_NEW);
f = BM_face_create_quad_tri(bm, cent2, firstv2, v2, NULL, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
BMO_face_flag_enable(bm, f, FACE_NEW);
}
f = BM_face_create_quad_tri(bm, v1, v2, firstv2, firstv1, NULL, BM_CREATE_NOP);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BM_mesh_calc_uvs_cone(bm, mat, rad2, rad1, segs, cap_ends, FACE_MARK, cd_loop_uv_offset);
}
@ -1609,8 +1621,10 @@ 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_PROP_FLOAT2);
const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
const int uv_index = BMO_slot_bool_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = uv_index != -1 ?
CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, uv_index) :
-1;
/* rotation order set to match 'BM_mesh_calc_uvs_cube' */
const char faces[6][4] = {
@ -1651,27 +1665,25 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
};
f = BM_face_create_verts(bm, quad, 4, NULL, BM_CREATE_NOP, true);
if (calc_uvs) {
if (cd_loop_uv_offset != -1) {
BMO_face_flag_enable(bm, f, FACE_MARK);
}
}
if (calc_uvs) {
BM_mesh_calc_uvs_cube(bm, FACE_MARK);
if (cd_loop_uv_offset != -1) {
BM_mesh_calc_uvs_cube(bm, FACE_MARK, cd_loop_uv_offset);
}
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "verts.out", BM_VERT, VERT_MARK);
}
void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag)
void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag, const int cd_loop_uv_offset)
{
BMFace *f;
BMLoop *l;
BMIter fiter, liter;
const float width = 0.25f;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
float x = 0.375f;
float y = 0.0f;

View File

@ -478,7 +478,8 @@ 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_PROP_FLOAT2);
const int uv_index = BMO_slot_int_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = CustomData_get_offset_n(&bm->ldata, CD_PROP_FLOAT2, uv_index);
if (cd_loop_uv_offset != -1) {
BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
@ -561,7 +562,8 @@ 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_PROP_FLOAT2);
const int uv_index = BMO_slot_int_get(op->slots_in, "uv_index");
const int cd_loop_uv_offset = CustomData_get_offset_n(&bm->ldata, CD_PROP_FLOAT2, uv_index);
if (cd_loop_uv_offset != -1) {
BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {

View File

@ -442,11 +442,14 @@ 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_PROP_FLOAT2) !=
-1;
const bool has_active_edit_uvmap = is_edit_object &&
(CustomData_get_active_layer(&me->edit_mesh->bm->ldata,
CD_PROP_FLOAT2) != -1);
const bool has_active_object_uvmap = me->active_uv_attribute &&
CustomData_get_named_layer(&me->ldata,
CD_PROP_FLOAT2,
me->active_uv_attribute) != -1;
const bool has_active_edit_uvmap = me->active_uv_attribute && is_edit_object &&
(CustomData_get_named_layer(&me->edit_mesh->bm->ldata,
CD_PROP_FLOAT2,
me->active_uv_attribute) != -1);
const bool draw_shadows = (draw_ctx->object_mode != OB_MODE_OBJECT) &&
(ob->mode == draw_ctx->object_mode);

View File

@ -413,6 +413,8 @@ static void retrieve_active_attribute_names(MeshRenderData &mr,
const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh);
mr.active_color_name = mesh_final->active_color_attribute;
mr.default_color_name = mesh_final->default_color_attribute;
mr.active_uv_name = mesh_final->active_uv_attribute;
mr.default_uv_name = mesh_final->default_uv_attribute;
}
MeshRenderData *mesh_render_data_create(Object *object,

View File

@ -251,8 +251,11 @@ static void mesh_cd_calc_active_uv_layer(const Object *object,
DRW_MeshCDMask *cd_used)
{
const Mesh *me_final = editmesh_final_or_this(object, me);
if (!me_final->active_uv_attribute) {
return;
}
const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final);
int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
int layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, me_final->active_uv_attribute);
if (layer != -1) {
cd_used->uv |= (1 << layer);
}
@ -289,6 +292,9 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
const StringRefNull default_color_name = me_final->default_color_attribute ?
me_final->default_color_attribute :
"";
const StringRefNull default_uv_name = me_final->default_uv_attribute ?
me_final->default_uv_attribute :
"";
for (int i = 0; i < gpumat_array_len; i++) {
GPUMaterial *gpumat = gpumat_array[i];
@ -356,7 +362,8 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
if (layer == -1) {
layer = (name[0] != '\0') ?
CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) :
CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
CustomData_get_named_layer(
cd_ldata, CD_PROP_FLOAT2, default_uv_name.c_str());
}
if (layer != -1 && !CustomData_layer_is_anonymous(cd_ldata, CD_PROP_FLOAT2, layer)) {
cd_used.uv |= (1 << layer);
@ -367,11 +374,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object,
if (layer == -1) {
layer = (name[0] != '\0') ?
CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) :
CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
CustomData_get_named_layer(
cd_ldata, CD_PROP_FLOAT2, default_uv_name.c_str());
/* Only fallback to orco (below) when we have no UV layers, see: #56545 */
if (layer == -1 && name[0] != '\0') {
layer = CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2);
layer = CustomData_get_named_layer(
cd_ldata, CD_PROP_FLOAT2, default_uv_name.c_str());
}
}
if (layer != -1) {

View File

@ -836,8 +836,14 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit
if (psmd != NULL && psmd->mesh_final != NULL) {
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 (psmd->mesh_final->active_uv_attribute != NULL) {
active_uv = CustomData_get_named_layer(
&psmd->mesh_final->ldata, CD_PROP_FLOAT2, psmd->mesh_final->active_uv_attribute);
}
if (psmd->mesh_final->default_uv_attribute != NULL) {
render_uv = CustomData_get_named_layer(
&psmd->mesh_final->ldata, CD_PROP_FLOAT2, psmd->mesh_final->default_uv_attribute);
}
}
if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) {
cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata,
@ -1173,7 +1179,10 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit,
if (psmd != NULL) {
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);
const char *name = psmd->mesh_final->active_uv_attribute;
if (name) {
active_uv = CustomData_get_named_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2, name);
}
}
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);

View File

@ -104,6 +104,8 @@ struct MeshRenderData {
const char *active_color_name;
const char *default_color_name;
const char *active_uv_name;
const char *default_uv_name;
};
BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh *me)

View File

@ -247,7 +247,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi
uint32_t uv_layers = cache->cd_used.uv;
/* HACK to fix #68857 */
if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) {
int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
int layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, mr->active_uv_name);
if (layer != -1 && !CustomData_layer_is_anonymous(cd_ldata, CD_PROP_FLOAT2, layer)) {
uv_layers |= (1 << layer);
}
@ -256,7 +256,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_PROP_FLOAT2)) {
if (i == CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, mr->active_uv_name)) {
break;
}

View File

@ -63,11 +63,11 @@ static void extract_tan_init_common(const MeshRenderData *mr,
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_PROP_FLOAT2)) {
if (mr->default_uv_name && STREQ(layer_name, mr->default_uv_name)) {
GPU_vertformat_alias_add(format, "t");
}
/* Active display layer name. */
if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
if (mr->active_uv_name && STREQ(layer_name, mr->active_uv_name)) {
GPU_vertformat_alias_add(format, "at");
}
@ -103,6 +103,8 @@ static void extract_tan_init_common(const MeshRenderData *mr,
bool calc_active_tangent = false;
if (mr->extract_type == MR_EXTRACT_BMESH) {
BKE_editmesh_loop_tangent_calc(mr->edit_bmesh,
mr->me->active_uv_attribute,
mr->me->default_uv_attribute,
calc_active_tangent,
r_tangent_names,
tan_len,
@ -122,6 +124,8 @@ static void extract_tan_init_common(const MeshRenderData *mr,
mr->tri_len,
mr->sharp_faces,
cd_ldata,
mr->me->active_uv_attribute,
mr->me->default_uv_attribute,
calc_active_tangent,
r_tangent_names,
tan_len,

View File

@ -23,6 +23,8 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
MeshBatchCache *cache,
CustomData *cd_ldata,
eMRExtractType extract_type,
const char *active_uv_name,
const char *default_uv_name,
uint32_t &r_uv_layers)
{
GPU_vertformat_deinterleave(format);
@ -30,7 +32,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
uint32_t uv_layers = cache->cd_used.uv;
/* HACK to fix #68857 */
if (extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) {
int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2);
int layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, active_uv_name);
if (layer != -1 && !CustomData_layer_is_anonymous(cd_ldata, CD_PROP_FLOAT2, layer)) {
uv_layers |= (1 << layer);
}
@ -48,11 +50,11 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format,
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_PROP_FLOAT2)) {
if (default_uv_name && STREQ(layer_name, default_uv_name)) {
GPU_vertformat_alias_add(format, "a");
}
/* Active display layer name. */
if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) {
if (active_uv_name && STREQ(layer_name, active_uv_name)) {
GPU_vertformat_alias_add(format, "au");
/* Alias to `pos` for edit uvs. */
GPU_vertformat_alias_add(format, "pos");
@ -83,7 +85,13 @@ static void extract_uv_init(const MeshRenderData *mr,
CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata;
int v_len = mr->loop_len;
uint32_t uv_layers = cache->cd_used.uv;
if (!mesh_extract_uv_format_init(&format, cache, cd_ldata, mr->extract_type, uv_layers)) {
if (!mesh_extract_uv_format_init(&format,
cache,
cd_ldata,
mr->extract_type,
mr->active_uv_name,
mr->default_uv_name,
uv_layers)) {
/* VBO will not be used, only allocate minimum of memory. */
v_len = 1;
}
@ -121,7 +129,7 @@ static void extract_uv_init(const MeshRenderData *mr,
}
static void extract_uv_init_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData * /*mr*/,
const MeshRenderData *mr,
MeshBatchCache *cache,
void *buffer,
void * /*data*/)
@ -132,8 +140,13 @@ static void extract_uv_init_subdiv(const DRWSubdivCache *subdiv_cache,
uint v_len = subdiv_cache->num_subdiv_loops;
uint uv_layers;
if (!mesh_extract_uv_format_init(
&format, cache, &coarse_mesh->ldata, MR_EXTRACT_MESH, uv_layers)) {
if (!mesh_extract_uv_format_init(&format,
cache,
&coarse_mesh->ldata,
MR_EXTRACT_MESH,
mr->active_uv_name,
mr->default_uv_name,
uv_layers)) {
/* TODO(kevindietrich): handle this more gracefully. */
v_len = 1;
}

View File

@ -167,7 +167,7 @@ struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v
/**
* Return a new #UvVertMap from the edit-mesh.
*/
struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select);
struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, int cd_loop_uv_offset, bool use_select);
void EDBM_flag_enable_all(struct BMEditMesh *em, char hflag);
void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag);
@ -575,7 +575,7 @@ void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me);
/**
* Without a #bContext, called when UV-editing.
*/
void ED_mesh_uv_loop_reset_ex(struct Mesh *me, int layernum);
void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const char *name);
bool ED_mesh_color_ensure(struct Mesh *me, const char *name);
int ED_mesh_color_add(
struct Mesh *me, const char *name, bool active_set, bool do_init, struct ReportList *reports);

View File

@ -8,6 +8,7 @@
#include "BLI_math.h"
#include "BLI_sys_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -112,8 +113,12 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(
@ -121,12 +126,12 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op)
op,
"verts.out",
false,
"create_grid x_segments=%i y_segments=%i size=%f matrix=%m4 calc_uvs=%b",
"create_grid x_segments=%i y_segments=%i size=%f matrix=%m4 uv_index=%i",
0,
0,
RNA_float_get(op->ptr, "size") / 2.0f,
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -177,18 +182,22 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(em,
op,
"verts.out",
false,
"create_cube matrix=%m4 size=%f calc_uvs=%b",
"create_cube matrix=%m4 size=%f uv_index=%i",
creation_data.mat,
RNA_float_get(op->ptr, "size"),
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -251,8 +260,12 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(
@ -260,13 +273,13 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op)
op,
"verts.out",
false,
"create_circle segments=%i radius=%f cap_ends=%b cap_tris=%b matrix=%m4 calc_uvs=%b",
"create_circle segments=%i radius=%f cap_ends=%b cap_tris=%b matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius"),
cap_end,
cap_tri,
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -323,8 +336,12 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
&creation_data);
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(em,
@ -332,7 +349,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
"verts.out",
false,
"create_cone segments=%i radius1=%f radius2=%f cap_ends=%b "
"cap_tris=%b depth=%f matrix=%m4 calc_uvs=%b",
"cap_tris=%b depth=%f matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius"),
RNA_float_get(op->ptr, "radius"),
@ -340,7 +357,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
cap_tri,
RNA_float_get(op->ptr, "depth"),
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -399,8 +416,12 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
&creation_data);
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(em,
@ -408,7 +429,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
"verts.out",
false,
"create_cone segments=%i radius1=%f radius2=%f cap_ends=%b "
"cap_tris=%b depth=%f matrix=%m4 calc_uvs=%b",
"cap_tris=%b depth=%f matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "vertices"),
RNA_float_get(op->ptr, "radius1"),
RNA_float_get(op->ptr, "radius2"),
@ -416,7 +437,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op)
cap_tri,
RNA_float_get(op->ptr, "depth"),
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -475,8 +496,12 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
&creation_data);
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(
@ -484,12 +509,12 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op)
op,
"verts.out",
false,
"create_grid x_segments=%i y_segments=%i size=%f matrix=%m4 calc_uvs=%b",
"create_grid x_segments=%i y_segments=%i size=%f matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "x_subdivisions"),
RNA_int_get(op->ptr, "y_subdivisions"),
RNA_float_get(op->ptr, "size") / 2.0f,
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -552,17 +577,21 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(em,
op,
"verts.out",
false,
"create_monkey matrix=%m4 calc_uvs=%b",
"create_monkey matrix=%m4 uv_index=%i",
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -613,8 +642,12 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
&creation_data);
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(
@ -622,12 +655,12 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op)
op,
"verts.out",
false,
"create_uvsphere u_segments=%i v_segments=%i radius=%f matrix=%m4 calc_uvs=%b",
"create_uvsphere u_segments=%i v_segments=%i radius=%f matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "segments"),
RNA_int_get(op->ptr, "ring_count"),
RNA_float_get(op->ptr, "radius"),
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}
@ -681,8 +714,12 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
&creation_data);
em = BKE_editmesh_from_object(obedit);
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(
@ -690,11 +727,11 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
op,
"verts.out",
false,
"create_icosphere subdivisions=%i radius=%f matrix=%m4 calc_uvs=%b",
"create_icosphere subdivisions=%i radius=%f matrix=%m4 uv_index=%i",
RNA_int_get(op->ptr, "subdivisions"),
RNA_float_get(op->ptr, "radius"),
creation_data.mat,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}

View File

@ -10,6 +10,7 @@
#include "BLI_math.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -327,18 +328,22 @@ static int add_primitive_cube_gizmo_exec(bContext *C, wmOperator *op)
const bool calc_uvs = RNA_boolean_get(op->ptr, "calc_uvs");
int uv_index = -1;
if (calc_uvs) {
ED_mesh_uv_ensure(obedit->data, NULL);
Mesh *mesh = obedit->data;
ED_mesh_uv_ensure(mesh, NULL);
uv_index = CustomData_get_named_layer(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
}
if (!EDBM_op_call_and_selectf(em,
op,
"verts.out",
false,
"create_cube matrix=%m4 size=%f calc_uvs=%b",
"create_cube matrix=%m4 size=%f uv_index=%b",
matrix,
1.0f,
calc_uvs)) {
uv_index)) {
return OPERATOR_CANCELLED;
}

View File

@ -3043,6 +3043,7 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
scene, view_layer, CTX_wm_view3d(C), &objects_len);
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *obedit = objects[ob_index];
Mesh *mesh = static_cast<Mesh *>(obedit->data);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
if (em->bm->totfacesel == 0) {
@ -3051,7 +3052,16 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op)
BMOperator bmop;
EDBM_op_init(em, &bmop, op, "rotate_uvs faces=%hf use_ccw=%b", BM_ELEM_SELECT, use_ccw);
const int uv_index = CustomData_get_named_layer(
&mesh->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
EDBM_op_init(em,
&bmop,
op,
"rotate_uvs faces=%hf use_ccw=%b uv_index=%i",
BM_ELEM_SELECT,
use_ccw,
uv_index);
BMO_op_exec(em->bm, &bmop);

View File

@ -444,7 +444,7 @@ void EDBM_flag_enable_all(BMEditMesh *em, const char hflag)
/** \name UV Vertex Map API
* \{ */
UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select)
UvVertMap *BM_uv_vert_map_create(BMesh *bm, const int cd_loop_uv_offset, const bool use_select)
{
/* NOTE: delimiting on alternate face-winding was once supported and could be useful
* in some cases. If this is need see: D17137 to restore support. */
@ -453,7 +453,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select)
BMLoop *l;
BMIter iter, liter;
uint a;
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);

View File

@ -180,14 +180,14 @@ static void mesh_uv_reset_mface(const MPoly *poly, float2 *mloopuv)
mesh_uv_reset_array(fuv.data(), poly->totloop);
}
void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
void ED_mesh_uv_loop_reset_ex(Mesh *me, const char *name)
{
BMEditMesh *em = me->edit_mesh;
if (em) {
/* Collect BMesh UVs */
const int cd_loop_uv_offset = CustomData_get_n_offset(
&em->bm->ldata, CD_PROP_FLOAT2, layernum);
const int cd_loop_uv_offset = CustomData_get_offset_named(
&em->bm->ldata, CD_PROP_FLOAT2, name);
BMFace *efa;
BMIter iter;
@ -206,8 +206,10 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
/* Collect Mesh UVs */
BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2));
float2 *mloopuv = static_cast<float2 *>(
CustomData_get_layer_n_for_write(&me->ldata, CD_PROP_FLOAT2, layernum, me->totloop));
CustomData_get_layer_named_for_write(&me->ldata, CD_PROP_FLOAT2, name, me->totloop));
if (!mloopuv) {
return;
}
const blender::Span<MPoly> polys = me->polys();
for (const int i : polys.index_range()) {
mesh_uv_reset_mface(&polys[i], mloopuv);
@ -219,10 +221,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
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_PROP_FLOAT2);
ED_mesh_uv_loop_reset_ex(me, layernum);
if (const char *name = me->active_uv_attribute) {
ED_mesh_uv_loop_reset_ex(me, name);
}
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
@ -256,13 +257,14 @@ int ED_mesh_uv_add(
BM_uv_map_ensure_select_and_pin_attrs(em->bm);
/* copy data from active UV */
if (layernum_dst && do_init) {
const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2);
const char *name = me->active_uv_attribute;
const int layernum_src = CustomData_get_named_layer(&em->bm->ldata, CD_PROP_FLOAT2, name);
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_PROP_FLOAT2, layernum_dst);
BKE_id_attributes_active_uv_set(&me->id, unique_name);
}
}
else {
@ -288,13 +290,13 @@ int ED_mesh_uv_add(
}
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, layernum_dst);
BKE_id_attributes_active_uv_set(&me->id, unique_name);
}
}
/* don't overwrite our copied coords */
if (!is_init && do_init) {
ED_mesh_uv_loop_reset_ex(me, layernum_dst);
ED_mesh_uv_loop_reset_ex(me, unique_name);
}
DEG_id_tag_update(&me->id, 0);
@ -511,16 +513,9 @@ static bool uv_texture_remove_poll(bContext *C)
if (!layers_poll(C)) {
return false;
}
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_PROP_FLOAT2);
if (active != -1) {
return true;
}
return false;
Mesh *mesh = static_cast<Mesh *>(ob->data);
return mesh->active_uv_attribute != nullptr;
}
static int mesh_uv_texture_add_exec(bContext *C, wmOperator *op)
@ -561,9 +556,7 @@ static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *op)
Object *ob = ED_object_context(C);
Mesh *me = static_cast<Mesh *>(ob->data);
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)) {
if (!BKE_id_attribute_remove(&me->id, me->active_uv_attribute, op->reports)) {
return OPERATOR_CANCELLED;
}

View File

@ -932,7 +932,7 @@ static bool meta_data_matches(const std::optional<blender::bke::AttributeMetaDat
static void remove_invalid_attribute_strings(Mesh &mesh)
{
using namespace blender;
bke::AttributeAccessor attributes = mesh.attributes();
const bke::AttributeAccessor attributes = mesh.attributes();
if (!meta_data_matches(attributes.lookup_meta_data(mesh.active_color_attribute),
ATTR_DOMAIN_MASK_COLOR,
CD_MASK_COLOR_ALL)) {
@ -943,6 +943,16 @@ static void remove_invalid_attribute_strings(Mesh &mesh)
CD_MASK_COLOR_ALL)) {
MEM_SAFE_FREE(mesh.default_color_attribute);
}
if (!meta_data_matches(attributes.lookup_meta_data(mesh.active_uv_attribute),
ATTR_DOMAIN_MASK_CORNER,
CD_MASK_PROP_FLOAT2)) {
MEM_SAFE_FREE(mesh.active_uv_attribute);
}
if (!meta_data_matches(attributes.lookup_meta_data(mesh.default_uv_attribute),
ATTR_DOMAIN_MASK_CORNER,
CD_MASK_PROP_FLOAT2)) {
MEM_SAFE_FREE(mesh.default_uv_attribute);
}
}
static bool modifier_apply_obdata(

View File

@ -13,6 +13,7 @@
#include "BLI_utildefines.h"
#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@ -464,6 +465,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
float co[2], radius, radius_root;
Scene *scene = CTX_data_scene(C);
ARegion *region = CTX_wm_region(C);
Mesh *mesh = obedit->data;
BMEditMesh *em = BKE_editmesh_from_object(obedit);
uint tool;
UvSculptData *sculptdata = (UvSculptData *)op->customdata;
@ -490,7 +492,8 @@ static void uv_sculpt_stroke_apply(bContext *C,
radius = radius * radius;
radius_root = sqrtf(radius);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
const int cd_loop_uv_offset = CustomData_get_offset_named(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
/*
* Pinch Tool

View File

@ -1791,7 +1791,7 @@ static void uv_select_linked_multi(Scene *scene,
*
* Better solve this by having a delimit option for select-linked operator,
* keeping island-select working as is. */
UvVertMap *vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select);
UvVertMap *vmap = BM_uv_vert_map_create(em->bm, offsets.uv, !uv_sync_select);
if (vmap == NULL) {
continue;
}
@ -3290,7 +3290,7 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co
uint efa_index;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, offsets.uv, false);
if (vmap == NULL) {
return;
}
@ -3379,7 +3379,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co
uint efa_index;
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, offsets.uv, false);
if (vmap == NULL) {
return;
}
@ -3435,7 +3435,7 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh *
bm_clear_uv_vert_selection(scene, em->bm, offsets);
BM_mesh_elem_table_ensure(em->bm, BM_FACE);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false);
struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, offsets.uv, false);
if (vmap == NULL) {
return;
}

View File

@ -103,6 +103,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
return 1;
}
Mesh *mesh = static_cast<Mesh *>(obedit->data);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
BMIter iter;
@ -116,7 +117,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit)
return 0;
}
const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2);
const char *active_uv_name = mesh->active_uv_attribute;
BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name);
BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name);
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
@ -2049,7 +2050,9 @@ static void shrink_loop_uv_by_aspect_ratio(BMFace *efa,
static void correct_uv_aspect(Object *ob, BMEditMesh *em)
{
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
Mesh *mesh = static_cast<Mesh *>(ob->data);
const int cd_loop_uv_offset = CustomData_get_offset_named(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
const float aspect_y = ED_uvedit_get_aspect_y(ob);
if (aspect_y == 1.0f) {
/* Scaling by 1.0 has no effect. */
@ -2075,7 +2078,9 @@ static void correct_uv_aspect_per_face(Object *ob, BMEditMesh *em)
blender::Array<float, 16> material_aspect_y(materials_num, -1);
/* Lazily initialize aspect ratio for materials. */
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
Mesh *mesh = static_cast<Mesh *>(ob->data);
const int cd_loop_uv_offset = CustomData_get_offset_named(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
BMFace *efa;
BMIter iter;
@ -3005,7 +3010,9 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
continue;
}
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2);
Mesh *mesh = static_cast<Mesh *>(obedit->data);
const int cd_loop_uv_offset = CustomData_get_offset_named(
&em->bm->ldata, CD_PROP_FLOAT2, mesh->active_uv_attribute);
if (use_orthographic) {
uv_map_rotation_matrix_ex(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f, objects_pos_offset);

View File

@ -596,15 +596,11 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex)
blender::float2 *loopsuv[2] = {nullptr};
if (hasTex) {
// First UV layer
loopsuv[0] = static_cast<blender::float2 *>(CustomData_add_layer_named(
&mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->totloop, uvNames[0]));
CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 0);
// Second UV layer
loopsuv[1] = static_cast<blender::float2 *>(CustomData_add_layer_named(
&mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->totloop, uvNames[1]));
CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 1);
BKE_id_attributes_active_uv_set(&mesh->id, uvNames[1]);
}
// colors and transparency (the latter represented by grayscale colors)

View File

@ -228,7 +228,7 @@ void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
UVSample uvs_and_indices;
if (args_.export_params->uvs) {
const char *name = get_uv_sample(uvs_and_indices, m_custom_data_config, &mesh->ldata);
const char *name = get_uv_sample(uvs_and_indices, m_custom_data_config, *mesh);
if (!uvs_and_indices.indices.empty() && !uvs_and_indices.uvs.empty()) {
OV2fGeomParam::Sample uv_sample;
@ -243,7 +243,8 @@ void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
write_custom_data(abc_poly_mesh_schema_.getArbGeomParams(),
m_custom_data_config,
&mesh->ldata,
CD_PROP_FLOAT2);
CD_PROP_FLOAT2,
name);
}
if (args_.export_params->normals) {
@ -296,7 +297,7 @@ void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *me
UVSample sample;
if (args_.export_params->uvs) {
const char *name = get_uv_sample(sample, m_custom_data_config, &mesh->ldata);
const char *name = get_uv_sample(sample, m_custom_data_config, *mesh);
if (!sample.indices.empty() && !sample.uvs.empty()) {
OV2fGeomParam::Sample uv_sample;
@ -308,8 +309,11 @@ void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *me
subdiv_sample.setUVs(uv_sample);
}
write_custom_data(
abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_PROP_FLOAT2);
write_custom_data(abc_subdiv_schema_.getArbGeomParams(),
m_custom_data_config,
&mesh->ldata,
CD_PROP_FLOAT2,
name);
}
if (args_.export_params->orcos) {
@ -362,7 +366,8 @@ void ABCGenericMeshWriter::write_arb_geo_params(struct Mesh *me)
else {
arb_geom_params = abc_poly_mesh_.getSchema().getArbGeomParams();
}
write_custom_data(arb_geom_params, m_custom_data_config, &me->ldata, CD_PROP_BYTE_COLOR);
write_custom_data(
arb_geom_params, m_custom_data_config, &me->ldata, CD_PROP_BYTE_COLOR, nullptr);
}
bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels)

View File

@ -117,19 +117,15 @@ static void get_uvs(const CDStreamConfig &config,
}
}
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data)
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, Mesh &mesh)
{
const int active_uvlayer = CustomData_get_active_layer(data, CD_PROP_FLOAT2);
if (active_uvlayer < 0) {
const char *name = mesh.active_uv_attribute;
if (!name) {
return "";
}
const void *cd_data = CustomData_get_layer_n(data, CD_PROP_FLOAT2, active_uvlayer);
const void *cd_data = CustomData_get_layer_named(&mesh.ldata, CD_PROP_FLOAT2, name);
get_uvs(config, sample.uvs, sample.indices, cd_data);
return CustomData_get_layer_name(data, CD_PROP_FLOAT2, active_uvlayer);
return name;
}
/* Convention to write UVs:
@ -268,7 +264,8 @@ void write_generated_coordinates(const OCompoundProperty &prop, CDStreamConfig &
void write_custom_data(const OCompoundProperty &prop,
CDStreamConfig &config,
CustomData *data,
int data_type)
int data_type,
const char *active_name)
{
eCustomDataType cd_data_type = static_cast<eCustomDataType>(data_type);
@ -276,7 +273,6 @@ void write_custom_data(const OCompoundProperty &prop,
return;
}
const int active_layer = CustomData_get_active_layer(data, cd_data_type);
const int tot_layers = CustomData_number_of_layers(data, cd_data_type);
for (int i = 0; i < tot_layers; i++) {
@ -285,7 +281,7 @@ void write_custom_data(const OCompoundProperty &prop,
if (cd_data_type == CD_PROP_FLOAT2) {
/* Already exported. */
if (i == active_layer) {
if (STREQ(name, active_name)) {
continue;
}

View File

@ -93,7 +93,7 @@ struct CDStreamConfig {
* Returns the name of the UV layer.
*
* For now the active layer is used, maybe needs a better way to choose this. */
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data);
const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, Mesh &mesh);
void write_generated_coordinates(const OCompoundProperty &prop, CDStreamConfig &config);
@ -104,7 +104,8 @@ void read_generated_coordinates(const ICompoundProperty &prop,
void write_custom_data(const OCompoundProperty &prop,
CDStreamConfig &config,
CustomData *data,
int data_type);
int data_type,
const char *active_name);
void read_custom_data(const std::string &iobject_full_name,
const ICompoundProperty &prop,

View File

@ -121,17 +121,6 @@ const char *bc_CustomData_get_layer_name(const struct CustomData *data,
return data->layers[layer_index + n].name;
}
const char *bc_CustomData_get_active_layer_name(const CustomData *data, const eCustomDataType type)
{
/* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
if (layer_index < 0) {
return nullptr;
}
return data->layers[layer_index].name;
}
DocumentExporter::DocumentExporter(BlenderContext &blender_context,
ExportSettings *export_settings)
: blender_context(blender_context),

View File

@ -28,13 +28,7 @@
static std::string getActiveUVLayerName(Object *ob)
{
Mesh *me = (Mesh *)ob->data;
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_PROP_FLOAT2));
}
return "";
return me->active_uv_attribute ? me->active_uv_attribute : "";
}
EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw,

View File

@ -369,20 +369,20 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
/* if mesh has uv coords writes <input> for TEXCOORD */
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);
const blender::StringRef active_uv = me->active_uv_attribute;
for (int i = 0; i < num_layers; 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_PROP_FLOAT2, i);
COLLADASW::Input texcoord_input(
COLLADASW::InputSemantic::TEXCOORD,
makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())),
2, /* this is only until we have optimized UV sets */
(this->export_settings.get_active_uv_only()) ? 0 : layer_index - 1 /* set (0,1,2,...) */
);
til.push_back(texcoord_input);
const char *name = CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, i);
if (this->export_settings.get_active_uv_only() && name == active_uv) {
continue;
}
int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, i);
COLLADASW::Input texcoord_input(
COLLADASW::InputSemantic::TEXCOORD,
makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())),
2, /* this is only until we have optimized UV sets */
(this->export_settings.get_active_uv_only()) ? 0 : layer_index - 1 /* set (0,1,2,...) */
);
til.push_back(texcoord_input);
}
int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
@ -543,37 +543,38 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
/* 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_PROP_FLOAT2);
const blender::StringRef active_uv = me->active_uv_attribute;
for (int a = 0; a < num_layers; 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) {
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(
geom_id, a, this->export_settings.get_active_uv_only());
source.setId(layer_id);
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(totuv);
source.setAccessorStride(2);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("S");
param.push_back("T");
source.prepareToAppendValues();
for (const int i : polys.index_range()) {
const MPoly *poly = &polys[i];
const blender::float2 *mloop = uv_map + poly->loopstart;
for (int j = 0; j < poly->totloop; j++) {
source.appendValues(mloop[j][0], mloop[j][1]);
}
}
source.finish();
const char *name = CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, a);
if (this->export_settings.get_active_uv_only() && name == active_uv) {
continue;
}
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(
geom_id, a, this->export_settings.get_active_uv_only());
source.setId(layer_id);
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
source.setAccessorCount(totuv);
source.setAccessorStride(2);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
param.push_back("S");
param.push_back("T");
source.prepareToAppendValues();
for (const int i : polys.index_range()) {
const MPoly *poly = &polys[i];
const blender::float2 *mloop = uv_map + poly->loopstart;
for (int j = 0; j < poly->totloop; j++) {
source.appendValues(mloop[j][0], mloop[j][1]);
}
}
source.finish();
}
}

View File

@ -472,8 +472,10 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
CustomData_add_layer_named(
&me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, me->totloop, uvname.c_str());
}
/* activate the first uv map */
CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, 0);
BKE_id_attributes_active_uv_set(&me->id,
CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, 0));
BKE_id_attributes_default_uv_set(&me->id,
CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, 0));
}
int totcolset = collada_mesh->getColors().getInputInfosArray().getCount();

View File

@ -319,11 +319,7 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
return !(aBone->parent);
}
int bc_get_active_UVLayer(Object *ob)
{
Mesh *me = (Mesh *)ob->data;
return CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2);
}
std::string bc_url_encode(std::string data)
{
@ -1074,14 +1070,7 @@ 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_PROP_FLOAT2);
if (num_layers) {
const char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2);
if (layer_name) {
return std::string(layer_name);
}
}
return "";
return me->active_uv_attribute ? me->active_uv_attribute : "";
}
/**

View File

@ -139,7 +139,6 @@ extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
* are root bones.
*/
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
extern int bc_get_active_UVLayer(Object *ob);
inline std::string bc_string_after(const std::string &s, const std::string probe)
{

View File

@ -86,10 +86,9 @@ static void generate_vertex_map(const Mesh *mesh,
bool export_uv = false;
VArraySpan<float2> uv_map;
if (export_params.export_uv) {
const StringRef uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
if (!uv_name.is_empty()) {
if (mesh->active_uv_attribute) {
const bke::AttributeAccessor attributes = mesh->attributes();
uv_map = attributes.lookup<float2>(uv_name, ATTR_DOMAIN_CORNER);
uv_map = attributes.lookup<float2>(mesh->active_uv_attribute, ATTR_DOMAIN_CORNER);
export_uv = !uv_map.is_empty();
}
}
@ -239,7 +238,6 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
if (export_params.vertex_colors != PLY_VERTEX_COLOR_NONE) {
const StringRef name = mesh->active_color_attribute;
if (!name.is_empty()) {
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<ColorGeometry4f> color_attribute =
attributes.lookup_or_default<ColorGeometry4f>(
name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f});

View File

@ -32,10 +32,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_PROP_FLOAT2);
return name ? name : "";
return me->active_uv_attribute ? me->active_uv_attribute : "";
}
namespace blender::io::usd {

View File

@ -290,14 +290,9 @@ Span<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const
void OBJMesh::store_uv_coords_and_indices()
{
const StringRef active_uv_name = CustomData_get_active_layer_name(&export_mesh_->ldata,
CD_PROP_FLOAT2);
if (active_uv_name.is_empty()) {
uv_coords_.clear();
return;
}
const bke::AttributeAccessor attributes = export_mesh_->attributes();
const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
const VArraySpan<float2> uv_map = attributes.lookup<float2>(export_mesh_->active_uv_attribute,
ATTR_DOMAIN_CORNER);
if (uv_map.is_empty()) {
uv_coords_.clear();
return;

View File

@ -156,6 +156,11 @@ typedef struct Mesh {
/** The color attribute used by default (i.e. for rendering) if no name is given explicitly. */
char *default_color_attribute;
/** The UV map currently selected in the list and edited by a user. */
char *active_uv_attribute;
/** The UV map used by default (i.e. for rendering) if no name is given explicitly. */
char *default_uv_attribute;
/**
* User-defined symmetry flag (#eMeshSymmetryType) that causes editing operations to maintain
* symmetrical geometry. Supported by operations such as transform and weight-painting.

View File

@ -392,13 +392,24 @@ static PointerRNA rna_AttributeGroup_new(
{
CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, reports);
if ((GS(id->name) == ID_ME) && ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
if (GS(id->name) == ID_ME) {
Mesh *mesh = (Mesh *)id;
if (!mesh->active_color_attribute) {
mesh->active_color_attribute = BLI_strdup(layer->name);
if ((CD_TYPE_AS_MASK(type) & CD_MASK_COLOR_ALL) &&
(ATTR_DOMAIN_AS_MASK(domain) & ATTR_DOMAIN_MASK_COLOR)) {
if (!mesh->active_color_attribute) {
BKE_id_attributes_active_color_set(&mesh->id, layer->name);
}
if (!mesh->default_color_attribute) {
BKE_id_attributes_default_color_set(&mesh->id, layer->name);
}
}
if (!mesh->default_color_attribute) {
mesh->default_color_attribute = BLI_strdup(layer->name);
if (type == CD_PROP_FLOAT2 && domain == ATTR_DOMAIN_CORNER) {
if (!mesh->active_uv_attribute) {
BKE_id_attributes_active_uv_set(&mesh->id, layer->name);
}
if (!mesh->default_uv_attribute) {
BKE_id_attributes_default_uv_set(&mesh->id, layer->name);
}
}
}

View File

@ -914,18 +914,6 @@ static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3])
}
}
static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int type, bool render)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
if (render) {
return (n == CustomData_get_render_layer_index(data, type));
}
else {
return (n == CustomData_get_active_layer_index(data, type));
}
}
static int rna_CustomDataLayer_clone_get(PointerRNA *ptr, CustomData *data, int type)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
@ -933,26 +921,6 @@ static int rna_CustomDataLayer_clone_get(PointerRNA *ptr, CustomData *data, int
return (n == CustomData_get_clone_layer_index(data, type));
}
static void rna_CustomDataLayer_active_set(
PointerRNA *ptr, CustomData *data, int value, int type, int render)
{
Mesh *me = (Mesh *)ptr->owner_id;
int n = (((CustomDataLayer *)ptr->data) - data->layers) - CustomData_get_layer_index(data, type);
if (value == 0) {
return;
}
if (render) {
CustomData_set_layer_render(data, type, n);
}
else {
CustomData_set_layer_active(data, type, n);
}
BKE_mesh_tessface_clear(me);
}
static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int value, int type)
{
int n = ((CustomDataLayer *)ptr->data) - data->layers;
@ -1019,17 +987,91 @@ static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, bool value)
/* uv_layers */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_PROP_FLOAT2)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
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 */
static PointerRNA rna_Mesh_uv_layer_active_get(PointerRNA *ptr)
{
Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->active_uv_attribute;
if (!name) {
return PointerRNA_NULL;
}
CustomDataLayer *layer = BKE_id_attribute_find(
&mesh->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER);
return rna_pointer_inherit_refine(ptr, &RNA_MeshUVLoopLayer, layer);
}
static void rna_Mesh_uv_layer_active_set(PointerRNA *ptr,
PointerRNA value,
ReportList *UNUSED(reports))
{
Mesh *mesh = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)value.data;
BKE_id_attributes_active_uv_set(&mesh->id, layer->name);
BKE_mesh_tessface_clear(mesh);
}
static int rna_Mesh_uv_layer_active_index_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->active_uv_attribute;
if (!name) {
return 0;
}
CustomData *ldata = rna_mesh_ldata(ptr);
return CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name);
}
static void rna_Mesh_uv_layer_active_index_set(PointerRNA *ptr, int value)
{
Mesh *mesh = rna_mesh(ptr);
CustomData *ldata = rna_mesh_ldata(ptr);
const char *name = CustomData_get_layer_name(ldata, CD_PROP_FLOAT2, value);
BKE_id_attributes_active_uv_set(&mesh->id, name);
BKE_mesh_tessface_clear(mesh);
}
static PointerRNA rna_Mesh_uv_layer_render_get(PointerRNA *ptr)
{
Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->default_uv_attribute;
if (!name) {
return PointerRNA_NULL;
}
CustomDataLayer *layer = BKE_id_attribute_find(
&mesh->id, name, CD_PROP_FLOAT2, ATTR_DOMAIN_CORNER);
return rna_pointer_inherit_refine(ptr, &RNA_MeshUVLoopLayer, layer);
}
static void rna_Mesh_uv_layer_render_set(PointerRNA *ptr,
PointerRNA value,
ReportList *UNUSED(reports))
{
Mesh *mesh = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)value.data;
BKE_id_attributes_default_uv_set(&mesh->id, layer->name);
BKE_mesh_tessface_clear(mesh);
}
static int rna_Mesh_uv_layer_render_index_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->default_uv_attribute;
if (!name) {
return 0;
}
CustomData *ldata = rna_mesh_ldata(ptr);
return CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name);
}
static void rna_Mesh_uv_layer_render_index_set(PointerRNA *ptr, int value)
{
Mesh *mesh = rna_mesh(ptr);
CustomData *ldata = rna_mesh_ldata(ptr);
const char *name = CustomData_get_layer_name(ldata, CD_PROP_FLOAT2, value);
BKE_id_attributes_default_uv_set(&mesh->id, name);
BKE_mesh_tessface_clear(mesh);
}
static char *rna_MeshUVLoopLayer_path(const PointerRNA *ptr)
{
const CustomDataLayer *cdl = ptr->data;
@ -1166,12 +1208,24 @@ int rna_MeshUVLoopLayer_uv_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_
static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 1);
const Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->default_uv_attribute;
if (!name) {
return false;
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
return STREQ(layer->name, name);
}
static bool rna_MeshUVLoopLayer_active_get(PointerRNA *ptr)
{
return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 0);
const Mesh *mesh = rna_mesh(ptr);
const char *name = mesh->active_uv_attribute;
if (!name) {
return false;
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
return STREQ(layer->name, name);
}
static bool rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr)
@ -1181,12 +1235,22 @@ static bool rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr)
static void rna_MeshUVLoopLayer_active_render_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 1);
if (!value) {
return;
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
BKE_id_attributes_default_uv_set(ptr->owner_id, layer->name);
BKE_mesh_tessface_clear((Mesh *)ptr->owner_id);
}
static void rna_MeshUVLoopLayer_active_set(PointerRNA *ptr, bool value)
{
rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 0);
if (!value) {
return;
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
BKE_id_attributes_active_uv_set(ptr->owner_id, layer->name);
BKE_mesh_tessface_clear((Mesh *)ptr->owner_id);
}
static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value)
@ -2531,15 +2595,21 @@ static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me,
{
PointerRNA ptr;
CustomData *ldata;
CustomDataLayer *cdl = NULL;
CustomDataLayer *layer = NULL;
int index = ED_mesh_uv_add(me, name, false, do_init, reports);
if (index != -1) {
ldata = rna_mesh_ldata_helper(me);
cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, index)];
layer = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, index)];
if (!me->active_uv_attribute) {
BKE_id_attributes_active_uv_set(&me->id, layer->name);
}
if (!me->default_uv_attribute) {
BKE_id_attributes_default_uv_set(&me->id, layer->name);
}
}
RNA_pointer_create(&me->id, &RNA_MeshUVLoopLayer, cdl, &ptr);
RNA_pointer_create(&me->id, &RNA_MeshUVLoopLayer, layer, &ptr);
return ptr;
}

View File

@ -97,10 +97,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
const blender::Span<MPoly> polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__);
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
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));
const float(*mloop_uv)[2] = BKE_mesh_get_uv_map_or_active(mesh, dmd->uvlayer_name);
/* verts are given the UV from the first face that uses them */
for (const int i : polys.index_range()) {

View File

@ -21,6 +21,7 @@
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "BKE_attribute.h"
#include "BKE_camera.h"
#include "BKE_context.h"
#include "BKE_lib_query.h"
@ -36,6 +37,7 @@
#include "MOD_modifiertypes.h"
#include "MOD_ui_common.h"
#include "MOD_util.h"
#include "MEM_guardedalloc.h"
@ -99,7 +101,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
int i, verts_num;
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
int projectors_num = 0;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
float aspx = umd->aspectx ? umd->aspectx : 1.0f;
float aspy = umd->aspecty ? umd->aspecty : 1.0f;
float scax = umd->scalex ? umd->scalex : 1.0f;
@ -121,11 +122,10 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
if (!CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) {
CustomData_add_layer_named(
&mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, mesh->totloop, umd->uvlayer_name);
BKE_id_attributes_active_uv_set(&mesh->id, umd->uvlayer_name);
BKE_id_attributes_default_uv_set(&mesh->id, umd->uvlayer_name);
}
/* make sure we're using an existing layer */
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++) {
float tmpmat[4][4];
@ -185,8 +185,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
const blender::Span<MPoly> polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
float(*mloop_uv)[2] = static_cast<float(*)[2]>(CustomData_get_layer_named_for_write(
&mesh->ldata, CD_PROP_FLOAT2, uvname, corner_verts.size()));
float(*mloop_uv)[2] = BKE_mesh_get_uv_map_or_active_for_write(mesh, umd->uvlayer_name);
coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num);

View File

@ -132,7 +132,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
UVWarpModifierData *umd = (UVWarpModifierData *)md;
const MDeformVert *dvert;
int defgrp_index;
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
float warp_mat[4][4];
const int axis_u = umd->axis_u;
const int axis_v = umd->axis_v;
@ -189,14 +188,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
translate_m4(warp_mat, umd->offset[0], umd->offset[1], 0.0f);
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_PROP_FLOAT2, umd->uvlayer_name, uvname);
const blender::Span<MPoly> polys = mesh->polys();
const blender::Span<int> corner_verts = mesh->corner_verts();
float(*mloopuv)[2] = static_cast<float(*)[2]>(CustomData_get_layer_named_for_write(
&mesh->ldata, CD_PROP_FLOAT2, uvname, corner_verts.size()));
float(*mloopuv)[2] = BKE_mesh_get_uv_map_or_active_for_write(mesh, umd->uvlayer_name);
MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index);
UVWarpData data{};

View File

@ -720,16 +720,7 @@ void RE_bake_pixels_populate(Mesh *me,
const BakeTargets *targets,
const char *uv_layer)
{
const float(*mloopuv)[2];
if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) {
mloopuv = static_cast<const float(*)[2]>(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2));
}
else {
int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer);
mloopuv = static_cast<const float(*)[2]>(
CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id));
}
const float(*mloopuv)[2] = BKE_mesh_get_uv_map_or_active(me, uv_layer);
if (mloopuv == nullptr) {
return;
}

View File

@ -512,6 +512,8 @@ static void do_multires_bake(MultiresBakeRender *bkr,
static_cast<const bool *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_BOOL, "sharp_face")),
&dm->loopData,
nullptr,
nullptr,
true,
nullptr,
0,

View File

@ -547,15 +547,8 @@ void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf,
char const *uv_layer,
const float uv_offset[2])
{
const blender::float2 *mloopuv;
if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) {
mloopuv = static_cast<const blender::float2 *>(
CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2));
}
else {
mloopuv = static_cast<const blender::float2 *>(
CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uv_layer));
}
const blender::float2 *mloopuv = reinterpret_cast<const blender::float2 *>(
BKE_mesh_get_uv_map_or_active(mesh, uv_layer));
blender::render::texturemargin::generate_margin(ibuf,
mask,