Merge branch 'blender-v3.2-release'

This commit is contained in:
Joseph Eagar
2022-05-31 16:35:22 -07:00
6 changed files with 121 additions and 16 deletions

View File

@@ -42,6 +42,8 @@ typedef enum AttributeDomainMask {
ATTR_DOMAIN_MASK_ALL = (1 << 5) - 1
} AttributeDomainMask;
#define ATTR_DOMAIN_AS_MASK(domain) ((AttributeDomainMask)((1 << (int)(domain))))
/* All domains that support color attributes. */
#define ATTR_DOMAIN_MASK_COLOR \
((AttributeDomainMask)((ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER)))
@@ -62,8 +64,13 @@ bool BKE_id_attribute_remove(struct ID *id,
struct CustomDataLayer *BKE_id_attribute_find(const struct ID *id,
const char *name,
int type,
AttributeDomain domain);
const int type,
const AttributeDomain domain);
struct CustomDataLayer *BKE_id_attribute_search(const struct ID *id,
const char *name,
const CustomDataMask type,
const AttributeDomainMask domain_mask);
AttributeDomain BKE_id_attribute_domain(const struct ID *id, const struct CustomDataLayer *layer);
int BKE_id_attribute_data_length(struct ID *id, struct CustomDataLayer *layer);

View File

@@ -284,6 +284,35 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id,
return nullptr;
}
CustomDataLayer *BKE_id_attribute_search(const ID *id,
const char *name,
const CustomDataMask type_mask,
const AttributeDomainMask domain_mask)
{
DomainInfo info[ATTR_DOMAIN_NUM];
get_domains(id, info);
for (AttributeDomain domain = ATTR_DOMAIN_POINT; domain < ATTR_DOMAIN_NUM; domain++) {
if (!(domain_mask & ATTR_DOMAIN_AS_MASK(domain))) {
continue;
}
CustomData *customdata = info[domain].customdata;
if (customdata == NULL) {
return NULL;
}
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if ((CD_TYPE_AS_MASK(layer->type) & type_mask) && STREQ(layer->name, name)) {
return layer;
}
}
}
return NULL;
}
int BKE_id_attributes_length(const ID *id, AttributeDomainMask domain_mask, CustomDataMask mask)
{
DomainInfo info[ATTR_DOMAIN_NUM];
@@ -651,6 +680,7 @@ CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name)
if (layer == nullptr) {
layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER);
}
return layer;
}

View File

@@ -111,7 +111,7 @@ static GPUVertFormat *get_coarse_vcol_format()
{
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
GPU_vertformat_attr_add(&format, "cCol", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_vertformat_alias_add(&format, "c");
GPU_vertformat_alias_add(&format, "ac");
}
@@ -245,6 +245,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
&coarse_mesh->vdata;
const CustomData *cd_ldata = extract_bmesh ? &coarse_mesh->edit_mesh->bm->ldata :
&coarse_mesh->ldata;
const int totloop = extract_bmesh ? coarse_mesh->edit_mesh->bm->totloop : coarse_mesh->totloop;
Mesh me_query = blender::dna::shallow_copy(*coarse_mesh);
BKE_id_attribute_copy_domains_temp(
@@ -263,7 +264,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
/* Dynamic as we upload and interpolate layers one at a time. */
GPU_vertbuf_init_with_format_ex(src_data, get_coarse_vcol_format(), GPU_USAGE_DYNAMIC);
GPU_vertbuf_data_alloc(src_data, coarse_mesh->totloop);
GPU_vertbuf_data_alloc(src_data, totloop);
gpuMeshVcol *mesh_vcol = (gpuMeshVcol *)GPU_vertbuf_get_data(src_data);
@@ -279,8 +280,6 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
const int dst_offset = (int)subdiv_cache->num_subdiv_loops * 2 * pack_layer_index++;
const CustomData *cdata = ref.domain == ATTR_DOMAIN_POINT ? cd_vdata : cd_ldata;
const MLoop *ml = coarse_mesh->mloop;
int layer_i = CustomData_get_named_layer_index(cdata, ref.layer->type, ref.layer->name);
if (layer_i == -1) {
@@ -289,15 +288,6 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
}
gpuMeshVcol *vcol = mesh_vcol;
MLoopCol *mcol = nullptr;
MPropCol *pcol = nullptr;
if (ref.layer->type == CD_PROP_COLOR) {
pcol = static_cast<MPropCol *>(cdata->layers[layer_i].data);
}
else {
mcol = static_cast<MLoopCol *>(cdata->layers[layer_i].data);
}
const bool is_vert = ref.domain == ATTR_DOMAIN_POINT;
@@ -331,10 +321,23 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache,
vcol->b = unit_float_to_ushort_clamp(pcol2->color[2]);
vcol->a = unit_float_to_ushort_clamp(pcol2->color[3]);
}
vcol++;
} while ((l_iter = l_iter->next) != f->l_first);
}
}
else {
const MLoop *ml = coarse_mesh->mloop;
MLoopCol *mcol = nullptr;
MPropCol *pcol = nullptr;
if (ref.layer->type == CD_PROP_COLOR) {
pcol = static_cast<MPropCol *>(cdata->layers[layer_i].data);
}
else {
mcol = static_cast<MLoopCol *>(cdata->layers[layer_i].data);
}
for (int ml_index = 0; ml_index < coarse_mesh->totloop; ml_index++, vcol++, ml++) {
int idx = is_vert ? ml->v : ml_index;

View File

@@ -33,6 +33,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
#include "ED_geometry.h"
#include "ED_object.h"
#include "geometry_intern.hh"
@@ -572,3 +573,38 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot)
}
} // namespace blender::ed::geometry
using blender::CPPType;
using blender::GVArray;
bool ED_geometry_attribute_convert(Mesh *mesh,
const char *layer_name,
CustomDataType old_type,
AttributeDomain old_domain,
CustomDataType new_type,
AttributeDomain new_domain)
{
CustomDataLayer *layer = BKE_id_attribute_find(&mesh->id, layer_name, old_type, old_domain);
const std::string name = layer->name;
if (!layer) {
return false;
}
MeshComponent mesh_component;
mesh_component.replace(mesh, GeometryOwnershipType::Editable);
GVArray src_varray = mesh_component.attribute_get_for_read(name, new_domain, new_type);
const CPPType &cpp_type = src_varray.type();
void *new_data = MEM_malloc_arrayN(src_varray.size(), cpp_type.size(), __func__);
src_varray.materialize_to_uninitialized(new_data);
mesh_component.attribute_try_delete(name);
mesh_component.attribute_try_create(name, new_domain, new_type, AttributeInitMove(new_data));
int *active_index = BKE_id_attributes_active_index_p(&mesh->id);
if (*active_index > 0) {
*active_index -= 1;
}
return true;
}

View File

@@ -7,12 +7,22 @@
#pragma once
#include "BKE_attribute.h"
#include "DNA_customdata_types.h"
#ifdef __cplusplus
extern "C" {
#endif
void ED_operatortypes_geometry(void);
struct Mesh;
void ED_operatortypes_geometry(void);
bool ED_geometry_attribute_convert(struct Mesh *mesh,
const char *layer_name,
CustomDataType old_type,
AttributeDomain old_domain,
CustomDataType new_type,
AttributeDomain new_domain);
#ifdef __cplusplus
}
#endif

View File

@@ -50,6 +50,7 @@
#include "WM_api.h"
#include "WM_types.h"
#include "ED_geometry.h"
#include "ED_object.h"
#include "ED_sculpt.h"
#include "ED_undo.h"
@@ -1565,6 +1566,24 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr
CustomDataLayer *layer;
layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
/* Temporary fix for T97408. This is a fundamental
* bug in the undo stack; the operator code needs to push
* an extra undo step before running an operator if a
* non-memfile undo system is active.
*
* For now, detect if the layer does exist but with a different
* domain and just unconvert it.
*/
if (!layer) {
layer = BKE_id_attribute_search(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
AttributeDomain domain = layer ? BKE_id_attribute_domain(&me->id, layer) : ATTR_DOMAIN_NUM;
if (layer && ED_geometry_attribute_convert(
me, attr->name, layer->type, domain, attr->type, attr->domain)) {
layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain);
}
}
if (!layer) {
/* Memfile undo killed the layer; re-create it. */
CustomData *cdata = attr->domain == ATTR_DOMAIN_POINT ? &me->vdata : &me->ldata;