WIP: Mesh: Store active and default UV map with strings #105779
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ¶m = 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 ¶m = 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 : "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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{};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue