Attributes: Integrate implicit sharing with the attribute API #107059
|
@ -86,6 +86,8 @@ struct AttributeInit {
|
|||
VArray,
|
||||
/** #AttributeInitMoveArray. */
|
||||
MoveArray,
|
||||
/** #AttributeInitShared. */
|
||||
Shared,
|
||||
};
|
||||
Type type;
|
||||
AttributeInit(const Type type) : type(type) {}
|
||||
|
@ -121,9 +123,6 @@ struct AttributeInitVArray : public AttributeInit {
|
|||
* Sometimes data is created before a geometry component is available. In that case, it's
|
||||
* preferable to move data directly to the created attribute to avoid a new allocation and a copy.
|
||||
*
|
||||
* Note that this will only have a benefit for attributes that are stored directly as contiguous
|
||||
* arrays, so not for some built-in attributes.
|
||||
*
|
||||
* The array must be allocated with MEM_*, since `attribute_try_create` will free the array if it
|
||||
* can't be used directly, and that is generally how Blender expects custom data to be allocated.
|
||||
*/
|
||||
|
@ -133,6 +132,20 @@ struct AttributeInitMoveArray : public AttributeInit {
|
|||
AttributeInitMoveArray(void *data) : AttributeInit(Type::MoveArray), data(data) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a shared attribute by adding a user to a shared data array.
|
||||
* The sharing info has ownership of the provided contiguous array.
|
||||
*/
|
||||
struct AttributeInitShared : public AttributeInit {
|
||||
const void *data = nullptr;
|
||||
const ImplicitSharingInfo *sharing_info = nullptr;
|
||||
|
||||
AttributeInitShared(const void *data, const ImplicitSharingInfo &sharing_info)
|
||||
: AttributeInit(Type::Shared), data(data), sharing_info(&sharing_info)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/* Returns false when the iteration should be stopped. */
|
||||
using AttributeForeachCallback =
|
||||
FunctionRef<bool(const AttributeIDRef &attribute_id, const AttributeMetaData &meta_data)>;
|
||||
|
@ -151,6 +164,21 @@ template<typename T> struct AttributeReader {
|
|||
*/
|
||||
eAttrDomain domain;
|
||||
|
||||
/**
|
||||
* Information about shared ownership of the attribute array. This will only be provided
|
||||
* if the virtual array directly references the contiguous original attribute array.
|
||||
*/
|
||||
const ImplicitSharingInfo *sharing_info;
|
||||
|
||||
const VArray<T> &operator*() const
|
||||
{
|
||||
return this->varray;
|
||||
}
|
||||
VArray<T> &operator*()
|
||||
{
|
||||
return this->varray;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return this->varray;
|
||||
|
@ -270,15 +298,25 @@ template<typename T> struct SpanAttributeWriter {
|
|||
struct GAttributeReader {
|
||||
GVArray varray;
|
||||
eAttrDomain domain;
|
||||
const ImplicitSharingInfo *sharing_info;
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return this->varray;
|
||||
}
|
||||
|
||||
const GVArray &operator*() const
|
||||
{
|
||||
return this->varray;
|
||||
}
|
||||
GVArray &operator*()
|
||||
{
|
||||
return this->varray;
|
||||
}
|
||||
|
||||
template<typename T> AttributeReader<T> typed() const
|
||||
{
|
||||
return {varray.typed<T>(), domain};
|
||||
return {varray.typed<T>(), domain, sharing_info};
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -457,15 +495,15 @@ class AttributeAccessor {
|
|||
* Get read-only access to the attribute. If necessary, the attribute is interpolated to the
|
||||
* given domain, and converted to the given type, in that order. The result may be empty.
|
||||
*/
|
||||
GVArray lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain,
|
||||
const std::optional<eCustomDataType> data_type) const;
|
||||
GAttributeReader lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain,
|
||||
const std::optional<eCustomDataType> data_type) const;
|
||||
|
||||
/**
|
||||
* Get read-only access to the attribute whereby the attribute is interpolated to the given
|
||||
* domain. The result may be empty.
|
||||
*/
|
||||
GVArray lookup(const AttributeIDRef &attribute_id, const eAttrDomain domain) const
|
||||
GAttributeReader lookup(const AttributeIDRef &attribute_id, const eAttrDomain domain) const
|
||||
{
|
||||
return this->lookup(attribute_id, domain, std::nullopt);
|
||||
}
|
||||
|
@ -474,7 +512,8 @@ class AttributeAccessor {
|
|||
* Get read-only access to the attribute whereby the attribute is converted to the given type.
|
||||
* The result may be empty.
|
||||
*/
|
||||
GVArray lookup(const AttributeIDRef &attribute_id, const eCustomDataType data_type) const
|
||||
GAttributeReader lookup(const AttributeIDRef &attribute_id,
|
||||
const eCustomDataType data_type) const
|
||||
{
|
||||
return this->lookup(attribute_id, std::nullopt, data_type);
|
||||
}
|
||||
|
@ -484,8 +523,8 @@ class AttributeAccessor {
|
|||
* given domain and then converted to the given type, in that order. The result may be empty.
|
||||
*/
|
||||
template<typename T>
|
||||
VArray<T> lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain = std::nullopt) const
|
||||
AttributeReader<T> lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain = std::nullopt) const
|
||||
{
|
||||
const CPPType &cpp_type = CPPType::get<T>();
|
||||
const eCustomDataType data_type = cpp_type_to_custom_data_type(cpp_type);
|
||||
|
@ -498,23 +537,23 @@ class AttributeAccessor {
|
|||
* If the attribute does not exist, a virtual array with the given default value is returned.
|
||||
* If the passed in default value is null, the default value of the type is used (generally 0).
|
||||
*/
|
||||
GVArray lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const eCustomDataType data_type,
|
||||
const void *default_value = nullptr) const;
|
||||
GAttributeReader lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const eCustomDataType data_type,
|
||||
const void *default_value = nullptr) const;
|
||||
|
||||
/**
|
||||
* Same as the generic version above, but should be used when the type is known at compile time.
|
||||
*/
|
||||
template<typename T>
|
||||
VArray<T> lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const T &default_value) const
|
||||
AttributeReader<T> lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const T &default_value) const
|
||||
{
|
||||
if (VArray<T> varray = this->lookup<T>(attribute_id, domain)) {
|
||||
if (AttributeReader<T> varray = this->lookup<T>(attribute_id, domain)) {
|
||||
return varray;
|
||||
}
|
||||
return VArray<T>::ForSingle(default_value, this->domain_size(domain));
|
||||
return {VArray<T>::ForSingle(default_value, this->domain_size(domain)), domain};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -626,6 +665,15 @@ class MutableAttributeAccessor : public AttributeAccessor {
|
|||
{
|
||||
return fn_->add(owner_, attribute_id, domain, data_type, initializer);
|
||||
}
|
||||
template<typename T>
|
||||
bool add(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const AttributeInit &initializer)
|
||||
{
|
||||
const CPPType &cpp_type = CPPType::get<T>();
|
||||
const eCustomDataType data_type = cpp_type_to_custom_data_type(cpp_type);
|
||||
return this->add(attribute_id, domain, data_type, initializer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an attribute with the given id, domain and data type. If it does not exist, create a new
|
||||
|
|
|
@ -658,11 +658,18 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
ASSERT_IS_VALID_MESH(mesh_final);
|
||||
}
|
||||
MutableAttributeAccessor attributes = mesh_final->attributes_for_write();
|
||||
SpanAttributeWriter<float3> rest_positions =
|
||||
attributes.lookup_or_add_for_write_only_span<float3>("rest_position", ATTR_DOMAIN_POINT);
|
||||
if (rest_positions && attributes.domain_size(ATTR_DOMAIN_POINT) > 0) {
|
||||
attributes.lookup<float3>("position").materialize(rest_positions.span);
|
||||
rest_positions.finish();
|
||||
const AttributeReader positions = attributes.lookup<float3>("position");
|
||||
if (positions) {
|
||||
if (positions.sharing_info && positions.varray.is_span()) {
|
||||
attributes.add<float3>("rest_position",
|
||||
ATTR_DOMAIN_POINT,
|
||||
AttributeInitShared(positions.varray.get_internal_span().data(),
|
||||
|
||||
*positions.sharing_info));
|
||||
}
|
||||
else {
|
||||
attributes.add<float3>(
|
||||
"rest_position", ATTR_DOMAIN_POINT, AttributeInitVArray(positions.varray));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,12 @@ static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case AttributeInit::Type::Shared: {
|
||||
const AttributeInitShared &init = static_cast<const AttributeInitShared &>(initializer);
|
||||
const void *stored_data = CustomData_add_layer_with_data(
|
||||
&custom_data, data_type, const_cast<void *>(init.data), domain_num, init.sharing_info);
|
||||
return stored_data != nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
|
@ -293,6 +299,16 @@ static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attr
|
|||
custom_data, data_type, attribute_id, domain_num, data, nullptr);
|
||||
break;
|
||||
}
|
||||
case AttributeInit::Type::Shared: {
|
||||
const AttributeInitShared &init = static_cast<const AttributeInitShared &>(initializer);
|
||||
add_generic_custom_data_layer_with_existing_data(custom_data,
|
||||
data_type,
|
||||
attribute_id,
|
||||
domain_num,
|
||||
const_cast<void *>(init.data),
|
||||
init.sharing_info);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return old_layer_num < custom_data.totlayer;
|
||||
}
|
||||
|
@ -314,7 +330,7 @@ bool BuiltinCustomDataLayerProvider::layer_exists(const CustomData &custom_data)
|
|||
return CustomData_has_layer(&custom_data, stored_type_);
|
||||
}
|
||||
|
||||
GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) const
|
||||
GAttributeReader BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) const
|
||||
{
|
||||
const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
|
||||
if (custom_data == nullptr) {
|
||||
|
@ -326,22 +342,23 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons
|
|||
const int element_num = custom_data_access_.get_element_num(owner);
|
||||
if (element_num == 0) {
|
||||
if (this->layer_exists(*custom_data)) {
|
||||
return GVArray::ForSpan({type, nullptr, 0});
|
||||
return {GVArray::ForSpan({type, nullptr, 0}), domain_, nullptr};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
const void *data = nullptr;
|
||||
int index;
|
||||
if (stored_as_named_attribute_) {
|
||||
data = CustomData_get_layer_named(custom_data, stored_type_, name_.c_str());
|
||||
index = CustomData_get_named_layer_index(custom_data, stored_type_, name_.c_str());
|
||||
}
|
||||
else {
|
||||
data = CustomData_get_layer(custom_data, stored_type_);
|
||||
index = CustomData_get_layer_index(custom_data, stored_type_);
|
||||
}
|
||||
if (data == nullptr) {
|
||||
if (index == -1) {
|
||||
return {};
|
||||
}
|
||||
return GVArray::ForSpan({type, data, element_num});
|
||||
const CustomDataLayer &layer = custom_data->layers[index];
|
||||
return {GVArray::ForSpan({type, layer.data, element_num}), domain_, layer.sharing_info};
|
||||
}
|
||||
|
||||
GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) const
|
||||
|
@ -472,7 +489,7 @@ GAttributeReader CustomDataAttributeProvider::try_get_for_read(
|
|||
continue;
|
||||
}
|
||||
GSpan data{*type, layer.data, element_num};
|
||||
return {GVArray::ForSpan(data), domain_};
|
||||
return {GVArray::ForSpan(data), domain_, layer.sharing_info};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -729,50 +746,52 @@ static blender::GVArray try_adapt_data_type(blender::GVArray varray,
|
|||
return conversions.try_convert(std::move(varray), to_type);
|
||||
}
|
||||
|
||||
GVArray AttributeAccessor::lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain,
|
||||
const std::optional<eCustomDataType> data_type) const
|
||||
GAttributeReader AttributeAccessor::lookup(const AttributeIDRef &attribute_id,
|
||||
const std::optional<eAttrDomain> domain,
|
||||
const std::optional<eCustomDataType> data_type) const
|
||||
{
|
||||
GAttributeReader attribute = this->lookup(attribute_id);
|
||||
if (!attribute) {
|
||||
return {};
|
||||
}
|
||||
GVArray varray = std::move(attribute.varray);
|
||||
if (domain.has_value()) {
|
||||
if (attribute.domain != domain) {
|
||||
varray = this->adapt_domain(varray, attribute.domain, *domain);
|
||||
if (!varray) {
|
||||
attribute.varray = this->adapt_domain(attribute.varray, attribute.domain, *domain);
|
||||
attribute.domain = *domain;
|
||||
attribute.sharing_info = nullptr;
|
||||
if (!attribute.varray) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data_type.has_value()) {
|
||||
const CPPType &type = *custom_data_type_to_cpp_type(*data_type);
|
||||
if (varray.type() != type) {
|
||||
varray = try_adapt_data_type(std::move(varray), type);
|
||||
if (!varray) {
|
||||
if (attribute.varray.type() != type) {
|
||||
attribute.varray = try_adapt_data_type(std::move(attribute.varray), type);
|
||||
attribute.sharing_info = nullptr;
|
||||
if (!attribute.varray) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
return varray;
|
||||
return attribute;
|
||||
}
|
||||
|
||||
GVArray AttributeAccessor::lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const eCustomDataType data_type,
|
||||
const void *default_value) const
|
||||
GAttributeReader AttributeAccessor::lookup_or_default(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
const eCustomDataType data_type,
|
||||
const void *default_value) const
|
||||
{
|
||||
GVArray varray = this->lookup(attribute_id, domain, data_type);
|
||||
if (varray) {
|
||||
return varray;
|
||||
GAttributeReader attribute = this->lookup(attribute_id, domain, data_type);
|
||||
if (attribute) {
|
||||
return attribute;
|
||||
}
|
||||
const CPPType &type = *custom_data_type_to_cpp_type(data_type);
|
||||
const int64_t domain_size = this->domain_size(domain);
|
||||
if (default_value == nullptr) {
|
||||
return GVArray::ForSingleRef(type, domain_size, type.default_value());
|
||||
return {GVArray::ForSingleRef(type, domain_size, type.default_value()), domain, nullptr};
|
||||
}
|
||||
return GVArray::ForSingle(type, domain_size, default_value);
|
||||
return {GVArray::ForSingle(type, domain_size, default_value), domain, nullptr};
|
||||
}
|
||||
|
||||
Set<AttributeIDRef> AttributeAccessor::all_ids() const
|
||||
|
@ -921,7 +940,7 @@ Vector<AttributeTransferData> retrieve_attributes_for_transfer(
|
|||
return true;
|
||||
}
|
||||
|
||||
GVArray src = src_attributes.lookup(id, meta_data.domain);
|
||||
GVArray src = *src_attributes.lookup(id, meta_data.domain);
|
||||
BLI_assert(src);
|
||||
bke::GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, meta_data.domain, meta_data.data_type);
|
||||
|
|
|
@ -66,7 +66,7 @@ class BuiltinAttributeProvider {
|
|||
{
|
||||
}
|
||||
|
||||
virtual GVArray try_get_for_read(const void *owner) const = 0;
|
||||
virtual GAttributeReader try_get_for_read(const void *owner) const = 0;
|
||||
virtual GAttributeWriter try_get_for_write(void *owner) const = 0;
|
||||
virtual bool try_delete(void *owner) const = 0;
|
||||
virtual bool try_create(void *onwer, const AttributeInit &initializer) const = 0;
|
||||
|
@ -196,7 +196,7 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
|
|||
{
|
||||
}
|
||||
|
||||
GVArray try_get_for_read(const void *owner) const final;
|
||||
GAttributeReader try_get_for_read(const void *owner) const final;
|
||||
GAttributeWriter try_get_for_write(void *owner) const final;
|
||||
bool try_delete(void *owner) const final;
|
||||
bool try_create(void *owner, const AttributeInit &initializer) const final;
|
||||
|
@ -279,7 +279,7 @@ inline GAttributeReader lookup(const void *owner, const AttributeIDRef &attribut
|
|||
const StringRef name = attribute_id.name();
|
||||
if (const BuiltinAttributeProvider *provider =
|
||||
providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) {
|
||||
return {provider->try_get_for_read(owner), provider->domain()};
|
||||
return provider->try_get_for_read(owner);
|
||||
}
|
||||
}
|
||||
for (const DynamicAttributesProvider *provider : providers.dynamic_attribute_providers()) {
|
||||
|
|
|
@ -1280,7 +1280,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
|
|||
blender::bke::AttributeAccessor attributes = mesh->attributes();
|
||||
mask = looptri_no_hidden_map_get(
|
||||
mesh->polys(),
|
||||
attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
|
||||
*attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
|
||||
looptris.size(),
|
||||
&mask_bits_act_len);
|
||||
ATTR_FALLTHROUGH;
|
||||
|
|
|
@ -747,7 +747,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
|
|||
Span<float> radii = {};
|
||||
if (main_attributes.contains("radius")) {
|
||||
radii = evaluated_attribute_if_necessary(
|
||||
main_attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f),
|
||||
*main_attributes.lookup_or_default<float>("radius", ATTR_DOMAIN_POINT, 1.0f),
|
||||
main,
|
||||
main.curve_type_counts(),
|
||||
eval_buffer)
|
||||
|
@ -805,7 +805,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
|
|||
|
||||
const eAttrDomain src_domain = meta_data.domain;
|
||||
const eCustomDataType type = meta_data.data_type;
|
||||
GVArray src = main_attributes.lookup(id, src_domain, type);
|
||||
const GVArray src = *main_attributes.lookup(id, src_domain, type);
|
||||
|
||||
const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_attributes, id);
|
||||
GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span(
|
||||
|
@ -841,7 +841,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
|
|||
}
|
||||
const eAttrDomain src_domain = meta_data.domain;
|
||||
const eCustomDataType type = meta_data.data_type;
|
||||
GVArray src = profile_attributes.lookup(id, src_domain, type);
|
||||
const GVArray src = *profile_attributes.lookup(id, src_domain, type);
|
||||
|
||||
const eAttrDomain dst_domain = get_attribute_domain_for_mesh(mesh_attributes, id);
|
||||
GSpanAttributeWriter dst = mesh_attributes.lookup_or_add_for_write_only_span(
|
||||
|
|
|
@ -3237,8 +3237,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
|
|||
blender::MutableSpan<int> poly_offsets = me->poly_offsets_for_write();
|
||||
blender::MutableSpan<int> corner_verts = me->corner_verts_for_write();
|
||||
|
||||
const bool is_sharp = orgmesh->attributes().lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false)[0];
|
||||
const bool is_sharp = orgmesh->attributes()
|
||||
.lookup_or_default<bool>("sharp_face", ATTR_DOMAIN_FACE, false)
|
||||
.varray[0];
|
||||
BKE_mesh_smooth_flag_set(me, !is_sharp);
|
||||
|
||||
/* Get size (dimension) but considering scaling. */
|
||||
|
|
|
@ -131,14 +131,16 @@ class InstancePositionAttributeProvider final : public BuiltinAttributeProvider
|
|||
{
|
||||
}
|
||||
|
||||
GVArray try_get_for_read(const void *owner) const final
|
||||
GAttributeReader try_get_for_read(const void *owner) const final
|
||||
{
|
||||
const Instances *instances = static_cast<const Instances *>(owner);
|
||||
if (instances == nullptr) {
|
||||
return {};
|
||||
}
|
||||
Span<float4x4> transforms = instances->transforms();
|
||||
return VArray<float3>::ForDerivedSpan<float4x4, get_transform_position>(transforms);
|
||||
return {VArray<float3>::ForDerivedSpan<float4x4, get_transform_position>(transforms),
|
||||
domain_,
|
||||
nullptr};
|
||||
}
|
||||
|
||||
GAttributeWriter try_get_for_write(void *owner) const final
|
||||
|
|
|
@ -1114,7 +1114,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh()
|
|||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
CD_PROP_FLOAT3,
|
||||
BuiltinAttributeProvider::NonCreatable,
|
||||
BuiltinAttributeProvider::Creatable,
|
||||
BuiltinAttributeProvider::NonDeletable,
|
||||
point_access,
|
||||
tag_component_positions_changed);
|
||||
|
|
|
@ -139,7 +139,7 @@ static ComponentAttributeProviders create_attribute_providers_for_point_cloud()
|
|||
ATTR_DOMAIN_POINT,
|
||||
CD_PROP_FLOAT3,
|
||||
CD_PROP_FLOAT3,
|
||||
BuiltinAttributeProvider::NonCreatable,
|
||||
BuiltinAttributeProvider::Creatable,
|
||||
BuiltinAttributeProvider::NonDeletable,
|
||||
point_access,
|
||||
tag_component_positions_changed);
|
||||
|
|
|
@ -248,7 +248,7 @@ GVArray AttributeFieldInput::get_varray_for_context(const GeometryFieldContext &
|
|||
{
|
||||
const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
||||
if (auto attributes = context.attributes()) {
|
||||
return attributes->lookup(name_, context.domain(), data_type);
|
||||
return *attributes->lookup(name_, context.domain(), data_type);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ GVArray IDAttributeFieldInput::get_varray_for_context(const GeometryFieldContext
|
|||
|
||||
const StringRef name = get_random_id_attribute_name(context.domain());
|
||||
if (auto attributes = context.attributes()) {
|
||||
if (GVArray attribute = attributes->lookup(name, context.domain(), CD_PROP_INT32)) {
|
||||
if (GVArray attribute = *attributes->lookup(name, context.domain(), CD_PROP_INT32)) {
|
||||
return attribute;
|
||||
}
|
||||
}
|
||||
|
@ -334,7 +334,7 @@ GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryField
|
|||
const IndexMask /*mask*/) const
|
||||
{
|
||||
const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_);
|
||||
return context.attributes()->lookup(*anonymous_id_, context.domain(), data_type);
|
||||
return *context.attributes()->lookup(*anonymous_id_, context.domain(), data_type);
|
||||
}
|
||||
|
||||
std::string AnonymousAttributeFieldInput::socket_inspection_name() const
|
||||
|
@ -474,7 +474,7 @@ bool try_capture_field_on_geometry(GeometryComponent &component,
|
|||
}
|
||||
|
||||
attributes.remove(attribute_id);
|
||||
if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray{buffer})) {
|
||||
if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray(buffer))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2507,7 +2507,7 @@ static void gpencil_generate_edgeloops(Object *ob,
|
|||
const Span<MDeformVert> dverts = me->deform_verts();
|
||||
const blender::Span<blender::float3> vert_normals = me->vert_normals();
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> uv_seams = *attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
|
||||
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
|
||||
|
@ -2753,7 +2753,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
|
|||
gpl_fill, scene->r.cfra + frame_offset, GP_GETFRAME_ADD_NEW);
|
||||
int i;
|
||||
|
||||
const VArray<int> mesh_material_indices = me_eval->attributes().lookup_or_default<int>(
|
||||
const VArray<int> mesh_material_indices = *me_eval->attributes().lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
for (i = 0; i < polys_len; i++) {
|
||||
const IndexRange poly = polys[i];
|
||||
|
|
|
@ -1486,7 +1486,7 @@ bool BKE_mesh_material_index_used(Mesh *me, short index)
|
|||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor attributes = me->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
if (material_indices.is_single()) {
|
||||
return material_indices.get_internal_single() == index;
|
||||
|
@ -1718,11 +1718,11 @@ void BKE_mesh_mselect_validate(Mesh *me)
|
|||
(me->totselect), sizeof(MSelect), "Mesh selection history");
|
||||
|
||||
const AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const VArray<bool> select_edge = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
|
||||
".select_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) {
|
||||
|
@ -1830,7 +1830,7 @@ void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
|
|||
void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3])
|
||||
{
|
||||
blender::bke::AttributeAccessor attributes = mesh->attributes();
|
||||
VArray<float3> positions = attributes.lookup_or_default(
|
||||
VArray<float3> positions = *attributes.lookup_or_default(
|
||||
"position", ATTR_DOMAIN_POINT, float3(0));
|
||||
positions.materialize({(float3 *)vert_coords, mesh->totvert});
|
||||
}
|
||||
|
|
|
@ -411,7 +411,7 @@ static void copy_poly_attributes(Mesh *dest_mesh,
|
|||
}
|
||||
|
||||
/* Fix material indices after they have been transferred as a generic attribute. */
|
||||
const VArray<int> src_material_indices = orig_me->attributes().lookup_or_default<int>(
|
||||
const VArray<int> src_material_indices = *orig_me->attributes().lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
const int src_index = src_material_indices[index_in_orig_me];
|
||||
if (material_remap.index_range().contains(src_index)) {
|
||||
|
|
|
@ -1087,7 +1087,7 @@ static void move_shapekey_layers_to_keyblocks(const Mesh &mesh,
|
|||
if (kb->uid == actshape_uid) {
|
||||
kb->data = MEM_malloc_arrayN(kb->totelem, sizeof(float3), __func__);
|
||||
MutableSpan<float3> kb_coords(static_cast<float3 *>(kb->data), kb->totelem);
|
||||
mesh.attributes().lookup<float3>("position").materialize(kb_coords);
|
||||
mesh.attributes().lookup<float3>("position").varray.materialize(kb_coords);
|
||||
}
|
||||
else {
|
||||
kb->data = layer.data;
|
||||
|
|
|
@ -623,7 +623,7 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
|
|||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
if (hide_vert.is_single() && !hide_vert.get_internal_single()) {
|
||||
attributes.remove(".hide_edge");
|
||||
|
@ -662,7 +662,7 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
|
|||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
|
||||
attributes.remove(".hide_vert");
|
||||
|
@ -705,7 +705,7 @@ void BKE_mesh_flush_select_from_polys(Mesh *me)
|
|||
{
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
if (select_poly.is_single() && !select_poly.get_internal_single()) {
|
||||
attributes.remove(".select_vert");
|
||||
|
@ -720,9 +720,9 @@ void BKE_mesh_flush_select_from_polys(Mesh *me)
|
|||
/* Use generic domain interpolation to read the polygon attribute on the other domains.
|
||||
* Assume selected faces are not hidden and none of their vertices/edges are hidden. */
|
||||
attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_POINT, false)
|
||||
.materialize(select_vert.span);
|
||||
.varray.materialize(select_vert.span);
|
||||
attributes.lookup_or_default<bool>(".select_poly", ATTR_DOMAIN_EDGE, false)
|
||||
.materialize(select_edge.span);
|
||||
.varray.materialize(select_edge.span);
|
||||
|
||||
select_vert.finish();
|
||||
select_edge.finish();
|
||||
|
@ -759,7 +759,7 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
|
|||
{
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
if (select_vert.is_single() && !select_vert.get_internal_single()) {
|
||||
attributes.remove(".select_edge");
|
||||
|
@ -774,8 +774,8 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
|
|||
me->edges(),
|
||||
me->polys(),
|
||||
me->corner_verts(),
|
||||
attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
|
||||
attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
|
||||
*attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
|
||||
*attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
|
||||
select_vert,
|
||||
select_edge.span,
|
||||
select_poly.span);
|
||||
|
|
|
@ -1550,7 +1550,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
|
|||
const AttributeAccessor attributes = mesh->attributes();
|
||||
|
||||
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1559,7 +1559,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
|
|||
});
|
||||
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_edge = *attributes.lookup_or_default<bool>(
|
||||
".hide_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1567,7 +1567,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh,
|
|||
}
|
||||
});
|
||||
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1643,7 +1643,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh,
|
|||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1897,7 +1897,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
|
|||
const AttributeAccessor attributes = mesh->attributes();
|
||||
|
||||
MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1906,7 +1906,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
|
|||
});
|
||||
|
||||
MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
|
||||
const VArray<bool> select_edge = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
|
||||
".select_edge", ATTR_DOMAIN_EDGE, false);
|
||||
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -1914,7 +1914,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh,
|
|||
}
|
||||
});
|
||||
|
||||
const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
threading::parallel_for(legacy_polys.index_range(), 4096, [&](IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
|
|
@ -317,8 +317,8 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source)
|
|||
const OffsetIndices target_polys = target->polys();
|
||||
const Span<int> target_corner_verts = target->corner_verts();
|
||||
|
||||
const VArray<int> src_face_sets = src_attributes.lookup<int>(".sculpt_face_set",
|
||||
ATTR_DOMAIN_FACE);
|
||||
const VArray src_face_sets =
|
||||
* src_attributes.lookup<int>(".sculpt_face_set", ATTR_DOMAIN_FACE);
|
||||
if (!src_face_sets) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
|
|||
}
|
||||
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan<float2> uv_map = attributes.lookup<float2>(uvmap, ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan uv_map = *attributes.lookup<float2>(uvmap, ATTR_DOMAIN_CORNER);
|
||||
if (uv_map.is_empty()) {
|
||||
BKE_reportf(reports,
|
||||
RPT_ERROR,
|
||||
|
|
|
@ -1833,7 +1833,7 @@ static bool find_geonode_attribute_rgba(const DupliObject *dupli,
|
|||
|
||||
/* Attempt to look up the attribute. */
|
||||
std::optional<bke::AttributeAccessor> attributes = component->attributes();
|
||||
const VArray data = attributes->lookup<ColorGeometry4f>(name);
|
||||
const VArray data = *attributes->lookup<ColorGeometry4f>(name);
|
||||
|
||||
/* If the attribute was found and converted to float RGBA successfully, output it. */
|
||||
if (data) {
|
||||
|
|
|
@ -2127,7 +2127,7 @@ void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg)
|
|||
}
|
||||
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
if (hide_poly.is_single() && !hide_poly.get_internal_single()) {
|
||||
/* Nothing is hidden, so we can just remove all visibility bitmaps. */
|
||||
|
|
|
@ -668,7 +668,7 @@ static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
|
|||
}
|
||||
|
||||
const AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan uv_map = *attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
|
||||
|
||||
uv_islands::MeshData mesh_data(
|
||||
{pbvh->looptri, pbvh->totprim},
|
||||
|
|
|
@ -274,9 +274,9 @@ bool PointCloud::bounds_min_max(blender::float3 &min, blender::float3 &max) cons
|
|||
}
|
||||
this->runtime->bounds_cache.ensure([&](Bounds<float3> &r_bounds) {
|
||||
const AttributeAccessor attributes = this->attributes();
|
||||
const VArraySpan<float3> positions = attributes.lookup<float3>(POINTCLOUD_ATTR_POSITION);
|
||||
const Span<float3> positions = this->positions();
|
||||
if (attributes.contains(POINTCLOUD_ATTR_RADIUS)) {
|
||||
const VArraySpan<float> radii = attributes.lookup<float>(POINTCLOUD_ATTR_RADIUS);
|
||||
const VArraySpan radii = *attributes.lookup<float>(POINTCLOUD_ATTR_RADIUS);
|
||||
r_bounds = *bounds::min_max_with_radii(positions, radii);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -52,7 +52,7 @@ static bool everything_selected(const Curves &curves_id)
|
|||
{
|
||||
using namespace blender;
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
return selection.is_single() && selection.get_internal_single();
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ static void populate_cache_for_instance(Object &object,
|
|||
const InstancesComponent &instances =
|
||||
*base_geometry.get_component_for_read<InstancesComponent>();
|
||||
const AttributeAccessor instance_attributes = *instances.attributes();
|
||||
const VArray attribute = instance_attributes.lookup<ColorGeometry4f>(".viewer");
|
||||
const VArray attribute = *instance_attributes.lookup<ColorGeometry4f>(".viewer");
|
||||
if (!attribute) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -495,8 +495,8 @@ static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr)
|
|||
|
||||
const bke::CurvesGeometry &curves = rdata->curve_eval->geometry.wrap();
|
||||
curves.ensure_can_interpolate_to_evaluated();
|
||||
const VArraySpan<ColorGeometry4f> colors = curves.attributes().lookup<ColorGeometry4f>(
|
||||
".viewer", ATTR_DOMAIN_POINT);
|
||||
const VArraySpan colors = *curves.attributes().lookup<ColorGeometry4f>(".viewer",
|
||||
ATTR_DOMAIN_POINT);
|
||||
ColorGeometry4f *vbo_data = static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(vbo_attr));
|
||||
curves.interpolate_to_evaluated(colors, MutableSpan<ColorGeometry4f>{vbo_data, vert_len});
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ static void curves_batch_cache_ensure_edit_points_selection(const bke::CurvesGeo
|
|||
MutableSpan<float> data(static_cast<float *>(GPU_vertbuf_get_data(cache.edit_points_selection)),
|
||||
curves.points_num());
|
||||
|
||||
const VArray<float> attribute = curves.attributes().lookup_or_default<float>(
|
||||
const VArray<float> attribute = *curves.attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
attribute.materialize(data);
|
||||
}
|
||||
|
@ -343,14 +343,14 @@ static void curves_batch_ensure_attribute(const Curves &curves,
|
|||
* the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a
|
||||
* similar texture state swizzle to map the attribute correctly as for volume attributes, so we
|
||||
* can control the conversion ourselves. */
|
||||
VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
bke::AttributeReader<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f});
|
||||
|
||||
MutableSpan<ColorGeometry4f> vbo_span{
|
||||
static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(attr_vbo)),
|
||||
attributes.domain_size(request.domain)};
|
||||
|
||||
attribute.materialize(vbo_span);
|
||||
attribute.varray.materialize(vbo_span);
|
||||
|
||||
/* Existing final data may have been for a different attribute (with a different name or domain),
|
||||
* free the data. */
|
||||
|
|
|
@ -251,7 +251,7 @@ static void pointcloud_extract_position_and_radius(const PointCloud &pointcloud,
|
|||
|
||||
const bke::AttributeAccessor attributes = pointcloud.attributes();
|
||||
const Span<float3> positions = pointcloud.positions();
|
||||
const VArray<float> radii = attributes.lookup<float>("radius", ATTR_DOMAIN_POINT);
|
||||
const VArray<float> radii = *attributes.lookup<float>("radius");
|
||||
static GPUVertFormat format = {0};
|
||||
if (format.attr_len == 0) {
|
||||
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
|
@ -303,7 +303,7 @@ static void pointcloud_extract_attribute(const PointCloud &pointcloud,
|
|||
* the Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a
|
||||
* similar texture state swizzle to map the attribute correctly as for volume attributes, so we
|
||||
* can control the conversion ourselves. */
|
||||
VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
bke::AttributeReader<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
request.attribute_name, request.domain, {0.0f, 0.0f, 0.0f, 1.0f});
|
||||
|
||||
static GPUVertFormat format = {0};
|
||||
|
@ -316,7 +316,7 @@ static void pointcloud_extract_attribute(const PointCloud &pointcloud,
|
|||
|
||||
MutableSpan<ColorGeometry4f> vbo_data{
|
||||
static_cast<ColorGeometry4f *>(GPU_vertbuf_get_data(attr_buf)), pointcloud.totpoint};
|
||||
attribute.materialize(vbo_data);
|
||||
attribute.varray.materialize(vbo_data);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -2040,7 +2040,8 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache,
|
|||
return;
|
||||
}
|
||||
|
||||
const blender::VArraySpan<int> material_indices = mesh_eval->attributes().lookup_or_default<int>(
|
||||
const blender::bke::AttributeAccessor attributes = mesh_eval->attributes();
|
||||
const blender::VArraySpan<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
|
||||
/* Count number of subdivided polygons for each material. */
|
||||
|
|
|
@ -329,7 +329,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object,
|
|||
* use for now because we can't use a per-point radius yet. */
|
||||
const blender::bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (curves.curves_num() >= 1) {
|
||||
blender::VArray<float> radii = curves.attributes().lookup_or_default(
|
||||
blender::VArray<float> radii = *curves.attributes().lookup_or_default(
|
||||
"radius", ATTR_DOMAIN_POINT, 0.005f);
|
||||
const blender::IndexRange first_curve_points = curves.points_by_curve()[0];
|
||||
const float first_radius = radii[first_curve_points.first()];
|
||||
|
|
|
@ -438,9 +438,9 @@ static void extract_mesh_attr_viewer_init(const MeshRenderData *mr,
|
|||
|
||||
const StringRefNull attr_name = ".viewer";
|
||||
const bke::AttributeAccessor attributes = mr->me->attributes();
|
||||
attributes
|
||||
.lookup_or_default<ColorGeometry4f>(attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f})
|
||||
.materialize(attr);
|
||||
const bke::AttributeReader attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
attr_name, ATTR_DOMAIN_CORNER, {1.0f, 0.0f, 1.0f, 1.0f});
|
||||
attribute.varray.materialize(attr);
|
||||
}
|
||||
|
||||
constexpr MeshExtract create_extractor_attr_viewer()
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace blender::ed::curves {
|
|||
bool remove_selection(bke::CurvesGeometry &curves, const eAttrDomain selection_domain)
|
||||
{
|
||||
const bke::AttributeAccessor attributes = curves.attributes();
|
||||
const VArray<bool> selection = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", selection_domain, true);
|
||||
const int domain_size_orig = attributes.domain_size(selection_domain);
|
||||
Vector<int64_t> indices;
|
||||
|
|
|
@ -585,9 +585,8 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
|
|||
VArraySpan<float2> surface_uv_map;
|
||||
if (curves_id.surface_uv_map != nullptr) {
|
||||
const bke::AttributeAccessor surface_attributes = surface_mesh.attributes();
|
||||
surface_uv_map = surface_attributes
|
||||
.lookup(curves_id.surface_uv_map, ATTR_DOMAIN_CORNER, CD_PROP_FLOAT2)
|
||||
.typed<float2>();
|
||||
surface_uv_map = *surface_attributes.lookup<float2>(curves_id.surface_uv_map,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
}
|
||||
|
||||
const OffsetIndices points_by_curve = curves.points_by_curve();
|
||||
|
@ -795,7 +794,7 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (const GVArray src = attributes.lookup(".selection", domain)) {
|
||||
if (const GVArray src = *attributes.lookup(".selection", domain)) {
|
||||
const CPPType &type = src.type();
|
||||
void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__);
|
||||
src.materialize(dst);
|
||||
|
|
|
@ -34,7 +34,7 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves,
|
|||
if (meta_data && meta_data->domain == ATTR_DOMAIN_POINT) {
|
||||
/* Avoid the interpolation from interpolating the attribute to the
|
||||
* curve domain by retrieving the point domain values directly. */
|
||||
const VArray<bool> selection = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
if (selection.is_single()) {
|
||||
return selection.get_internal_single() ? IndexMask(curves_range) : IndexMask();
|
||||
|
@ -49,7 +49,7 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves,
|
|||
return point_selection.as_span().contains(true);
|
||||
});
|
||||
}
|
||||
const VArray<bool> selection = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_CURVE, true);
|
||||
return index_mask_ops::find_indices_from_virtual_array(curves_range, selection, 2048, r_indices);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector<int
|
|||
{
|
||||
return index_mask_ops::find_indices_from_virtual_array(
|
||||
curves.points_range(),
|
||||
curves.attributes().lookup_or_default<bool>(".selection", ATTR_DOMAIN_POINT, true),
|
||||
*curves.attributes().lookup_or_default<bool>(".selection", ATTR_DOMAIN_POINT, true),
|
||||
2048,
|
||||
r_indices);
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ bool has_anything_selected(const VArray<bool> &varray, const IndexRange range_to
|
|||
|
||||
bool has_anything_selected(const bke::CurvesGeometry &curves)
|
||||
{
|
||||
const VArray<bool> selection = curves.attributes().lookup<bool>(".selection");
|
||||
const VArray<bool> selection = *curves.attributes().lookup<bool>(".selection");
|
||||
return !selection || contains(selection, selection.index_range(), true);
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
case ConvertAttributeMode::VertexGroup: {
|
||||
Array<float> src_weights(mesh->totvert);
|
||||
VArray<float> src_varray = attributes.lookup_or_default<float>(
|
||||
VArray<float> src_varray = *attributes.lookup_or_default<float>(
|
||||
name, ATTR_DOMAIN_POINT, 0.0f);
|
||||
src_varray.materialize(src_weights);
|
||||
attributes.remove(name);
|
||||
|
@ -703,13 +703,15 @@ bool ED_geometry_attribute_convert(Mesh *mesh,
|
|||
}
|
||||
|
||||
const std::string name_copy = name;
|
||||
const GVArray varray = attributes.lookup_or_default(name_copy, dst_domain, dst_type);
|
||||
const GVArray varray = *attributes.lookup_or_default(name_copy, dst_domain, dst_type);
|
||||
|
||||
const CPPType &cpp_type = varray.type();
|
||||
void *new_data = MEM_malloc_arrayN(varray.size(), cpp_type.size(), __func__);
|
||||
varray.materialize_to_uninitialized(new_data);
|
||||
attributes.remove(name_copy);
|
||||
attributes.add(name_copy, dst_domain, dst_type, bke::AttributeInitMoveArray(new_data));
|
||||
if (!attributes.add(name_copy, dst_domain, dst_type, bke::AttributeInitMoveArray(new_data))) {
|
||||
MEM_freeN(new_data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ void paintface_flush_flags(bContext *C,
|
|||
if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) {
|
||||
/* Update the COW copy of the mesh. */
|
||||
if (flush_hidden) {
|
||||
const VArray<bool> hide_poly_me = attributes_me.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly_me = *attributes_me.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> hide_poly_orig =
|
||||
attributes_orig.lookup_or_add_for_write_only_span<bool>(".hide_poly", ATTR_DOMAIN_FACE);
|
||||
|
@ -88,7 +88,7 @@ void paintface_flush_flags(bContext *C,
|
|||
hide_poly_orig.finish();
|
||||
}
|
||||
if (flush_selection) {
|
||||
const VArray<bool> select_poly_me = attributes_me.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly_me = *attributes_me.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly_orig =
|
||||
attributes_orig.lookup_or_add_for_write_only_span<bool>(".select_poly",
|
||||
|
@ -100,7 +100,7 @@ void paintface_flush_flags(bContext *C,
|
|||
/* Mesh polys => Final derived polys */
|
||||
if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
|
||||
if (flush_hidden) {
|
||||
const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly_orig = *attributes_orig.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> hide_poly_eval =
|
||||
attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_poly",
|
||||
|
@ -114,7 +114,7 @@ void paintface_flush_flags(bContext *C,
|
|||
hide_poly_eval.finish();
|
||||
}
|
||||
if (flush_selection) {
|
||||
const VArray<bool> select_poly_orig = attributes_orig.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly_orig = *attributes_orig.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly_eval =
|
||||
attributes_eval.lookup_or_add_for_write_only_span<bool>(".select_poly",
|
||||
|
@ -194,7 +194,7 @@ void paintface_reveal(bContext *C, Object *ob, const bool select)
|
|||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
|
||||
if (select) {
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
|
@ -228,9 +228,9 @@ static void build_poly_connections(blender::AtomicDisjointSet &islands,
|
|||
const Span<int> corner_edges = mesh.corner_edges();
|
||||
|
||||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> uv_seams = *attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
/* Polys are connected if they share edges. By connecting all edges of a loop (as long as they
|
||||
|
@ -277,7 +277,7 @@ static void paintface_select_linked_faces(Mesh &mesh,
|
|||
const Span<int> corner_edges = mesh.corner_edges();
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const VArray<bool> uv_seams = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> uv_seams = *attributes.lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
|
@ -380,7 +380,7 @@ void paintface_select_more(Mesh *mesh, const bool face_step)
|
|||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
const OffsetIndices polys = mesh->polys();
|
||||
|
@ -432,7 +432,7 @@ void paintface_select_less(Mesh *mesh, const bool face_step)
|
|||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
const OffsetIndices polys = mesh->polys();
|
||||
|
@ -478,7 +478,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
|
|||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
|
@ -545,9 +545,9 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
|
|||
const OffsetIndices polys = me->polys();
|
||||
const Span<int> corner_verts = me->corner_verts();
|
||||
bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
const VArray<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
for (int i = 0; i < me->totpoly; i++) {
|
||||
|
@ -581,7 +581,7 @@ bool paintface_mouse_select(bContext *C,
|
|||
Mesh *me = BKE_mesh_from_object(ob);
|
||||
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
bke::AttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
|
@ -656,7 +656,7 @@ void paintvert_flush_flags(Object *ob)
|
|||
|
||||
const int *orig_indices = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
|
||||
|
||||
const VArray<bool> hide_vert_orig = attributes_orig.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert_orig = *attributes_orig.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> hide_vert_eval =
|
||||
attributes_eval.lookup_or_add_for_write_only_span<bool>(".hide_vert", ATTR_DOMAIN_POINT);
|
||||
|
@ -672,7 +672,7 @@ void paintvert_flush_flags(Object *ob)
|
|||
}
|
||||
hide_vert_eval.finish();
|
||||
|
||||
const VArray<bool> select_vert_orig = attributes_orig.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert_orig = *attributes_orig.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> select_vert_eval =
|
||||
attributes_eval.lookup_or_add_for_write_only_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
@ -784,9 +784,9 @@ void paintvert_select_more(Mesh *mesh, const bool face_step)
|
|||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_edge = *attributes.lookup_or_default<bool>(
|
||||
".hide_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
const OffsetIndices polys = mesh->polys();
|
||||
|
@ -840,9 +840,9 @@ void paintvert_select_less(Mesh *mesh, const bool face_step)
|
|||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_edge = *attributes.lookup_or_default<bool>(
|
||||
".hide_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
const OffsetIndices polys = mesh->polys();
|
||||
|
@ -911,7 +911,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
|
|||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
@ -987,7 +987,7 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
|
|||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
@ -1051,7 +1051,7 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select)
|
|||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
|
|
@ -1481,7 +1481,7 @@ void ED_mesh_split_faces(Mesh *mesh)
|
|||
const Span<int> corner_edges = mesh->corner_edges();
|
||||
const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI);
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<bool> mesh_sharp_edges = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> mesh_sharp_edges = *attributes.lookup_or_default<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const bool *sharp_faces = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, "sharp_face"));
|
||||
|
|
|
@ -135,7 +135,7 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* Output mesh will be all smooth or all flat shading. */
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
const bool smooth_normals = !sharp_faces[0];
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ bool ED_vgroup_parray_alloc(ID *id,
|
|||
|
||||
if (use_vert_sel) {
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
for (int i = 0; i < me->totvert; i++) {
|
||||
|
@ -671,7 +671,7 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
|
|||
}
|
||||
else {
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
int v_act;
|
||||
|
@ -1063,7 +1063,7 @@ static void vgroup_select_verts(Object *ob, int select)
|
|||
const Span<MDeformVert> dverts = me->deform_verts();
|
||||
if (!dverts.is_empty()) {
|
||||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
bke::SpanAttributeWriter<bool> select_vert =
|
||||
attributes.lookup_or_add_for_write_only_span<bool>(".select_vert", ATTR_DOMAIN_POINT);
|
||||
|
@ -1628,7 +1628,7 @@ static void vgroup_smooth_subset(Object *ob,
|
|||
}
|
||||
else {
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
const blender::Span<int2> edges = me->edges();
|
||||
|
@ -1704,7 +1704,7 @@ static void vgroup_smooth_subset(Object *ob,
|
|||
}
|
||||
else {
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
int j;
|
||||
|
@ -2118,7 +2118,7 @@ void ED_vgroup_mirror(Object *ob,
|
|||
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__);
|
||||
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
for (int vidx = 0; vidx < me->totvert; vidx++) {
|
||||
|
@ -2278,7 +2278,7 @@ static void vgroup_assign_verts(Object *ob, const float weight)
|
|||
}
|
||||
else {
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
|
||||
|
@ -3907,7 +3907,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
|
|||
|
||||
MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
for (i = 0; i < me->totvert; i++) {
|
||||
|
|
|
@ -164,9 +164,9 @@ struct AddOperationExecutor {
|
|||
/* Find UV map. */
|
||||
VArraySpan<float2> surface_uv_map;
|
||||
if (curves_id_orig_->surface_uv_map != nullptr) {
|
||||
surface_uv_map = surface_orig.attributes().lookup<float2>(curves_id_orig_->surface_uv_map,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_eval_ = surface_eval_->attributes().lookup<float2>(
|
||||
surface_uv_map = *surface_orig.attributes().lookup<float2>(curves_id_orig_->surface_uv_map,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_eval_ = *surface_eval_->attributes().lookup<float2>(
|
||||
curves_id_orig_->surface_uv_map, ATTR_DOMAIN_CORNER);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ struct CombOperationExecutor {
|
|||
|
||||
transforms_ = CurvesSurfaceTransforms(*curves_ob_orig_, curves_id_orig_->surface);
|
||||
|
||||
point_factors_ = curves_orig_->attributes().lookup_or_default<float>(
|
||||
point_factors_ = *curves_orig_->attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_);
|
||||
|
||||
|
|
|
@ -134,9 +134,9 @@ struct DensityAddOperationExecutor {
|
|||
/* Find UV map. */
|
||||
VArraySpan<float2> surface_uv_map;
|
||||
if (curves_id_orig_->surface_uv_map != nullptr) {
|
||||
surface_uv_map = surface_orig_->attributes().lookup<float2>(curves_id_orig_->surface_uv_map,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_eval_ = surface_eval_->attributes().lookup<float2>(
|
||||
surface_uv_map = *surface_orig_->attributes().lookup<float2>(curves_id_orig_->surface_uv_map,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_eval_ = *surface_eval_->attributes().lookup<float2>(
|
||||
curves_id_orig_->surface_uv_map, ATTR_DOMAIN_CORNER);
|
||||
}
|
||||
if (surface_uv_map.is_empty()) {
|
||||
|
|
|
@ -277,7 +277,7 @@ struct CurvesEffectOperationExecutor {
|
|||
return;
|
||||
}
|
||||
|
||||
curve_selection_factors_ = curves_->attributes().lookup_or_default(
|
||||
curve_selection_factors_ = *curves_->attributes().lookup_or_default(
|
||||
".selection", ATTR_DOMAIN_CURVE, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ struct PinchOperationExecutor {
|
|||
|
||||
transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface);
|
||||
|
||||
point_factors_ = curves_->attributes().lookup_or_default<float>(
|
||||
point_factors_ = *curves_->attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ struct PuffOperationExecutor {
|
|||
brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension);
|
||||
brush_pos_re_ = stroke_extension.mouse_position;
|
||||
|
||||
point_factors_ = curves_->attributes().lookup_or_default<float>(
|
||||
point_factors_ = *curves_->attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ bke::SpanAttributeWriter<float> float_selection_ensure(Curves &curves_id)
|
|||
|
||||
if (const auto meta_data = attributes.lookup_meta_data(".selection")) {
|
||||
if (meta_data->data_type == CD_PROP_BOOL) {
|
||||
const VArray<float> selection = attributes.lookup<float>(".selection");
|
||||
const VArray<float> selection = *attributes.lookup<float>(".selection");
|
||||
float *dst = static_cast<float *>(
|
||||
MEM_malloc_arrayN(selection.size(), sizeof(float), __func__));
|
||||
selection.materialize({dst, selection.size()});
|
||||
|
|
|
@ -155,7 +155,7 @@ struct SlideOperationExecutor {
|
|||
brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension);
|
||||
brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension);
|
||||
|
||||
curve_factors_ = curves_orig_->attributes().lookup_or_default(
|
||||
curve_factors_ = *curves_orig_->attributes().lookup_or_default(
|
||||
".selection", ATTR_DOMAIN_CURVE, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_);
|
||||
|
||||
|
@ -170,8 +170,8 @@ struct SlideOperationExecutor {
|
|||
return;
|
||||
}
|
||||
surface_looptris_orig_ = surface_orig_->looptris();
|
||||
surface_uv_map_orig_ = surface_orig_->attributes().lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_orig_ = *surface_orig_->attributes().lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
if (surface_uv_map_orig_.is_empty()) {
|
||||
report_missing_uv_map_on_original_surface(stroke_extension.reports);
|
||||
return;
|
||||
|
@ -198,8 +198,8 @@ struct SlideOperationExecutor {
|
|||
surface_looptris_eval_ = surface_eval_->looptris();
|
||||
surface_positions_eval_ = surface_eval_->vert_positions();
|
||||
surface_corner_verts_eval_ = surface_eval_->corner_verts();
|
||||
surface_uv_map_eval_ = surface_eval_->attributes().lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
surface_uv_map_eval_ = *surface_eval_->attributes().lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
if (surface_uv_map_eval_.is_empty()) {
|
||||
report_missing_uv_map_on_evaluated_surface(stroke_extension.reports);
|
||||
return;
|
||||
|
|
|
@ -77,7 +77,7 @@ struct SmoothOperationExecutor {
|
|||
brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension);
|
||||
brush_pos_re_ = stroke_extension.mouse_position;
|
||||
|
||||
point_factors_ = curves_->attributes().lookup_or_default<float>(
|
||||
point_factors_ = *curves_->attributes().lookup_or_default<float>(
|
||||
".selection", ATTR_DOMAIN_POINT, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface);
|
||||
|
|
|
@ -123,7 +123,7 @@ struct SnakeHookOperatorExecutor {
|
|||
|
||||
transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface);
|
||||
|
||||
curve_factors_ = curves_->attributes().lookup_or_default(
|
||||
curve_factors_ = *curves_->attributes().lookup_or_default(
|
||||
".selection", ATTR_DOMAIN_CURVE, 1.0f);
|
||||
curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_);
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ struct NormalAnglePrecalc {
|
|||
/* Returns number of elements. */
|
||||
static int get_vcol_elements(Mesh *me, size_t *r_elem_size)
|
||||
{
|
||||
const std::optional<bke::AttributeMetaData> meta_data = me->attributes().lookup_meta_data(
|
||||
const std::optional<bke::AttributeMetaData> meta_data = *me->attributes().lookup_meta_data(
|
||||
me->active_color_attribute);
|
||||
|
||||
if (r_elem_size) {
|
||||
|
@ -1953,7 +1953,7 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
|
|||
ss, data->brush->falloff_shape);
|
||||
|
||||
const blender::bke::AttributeAccessor attributes = data->me->attributes();
|
||||
const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
/* For each vertex */
|
||||
|
@ -2042,7 +2042,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
|
|||
project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal);
|
||||
|
||||
const blender::bke::AttributeAccessor attributes = data->me->attributes();
|
||||
const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) {
|
||||
|
@ -2157,7 +2157,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
|
|||
ss, data->brush->falloff_shape);
|
||||
|
||||
const blender::bke::AttributeAccessor attributes = data->me->attributes();
|
||||
const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
/* For each vertex */
|
||||
|
@ -2228,7 +2228,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(void *__restrict userdata,
|
|||
ss, data->brush->falloff_shape);
|
||||
|
||||
const blender::bke::AttributeAccessor attributes = data->me->attributes();
|
||||
const blender::VArray<bool> select_vert = attributes.lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
/* For each vertex */
|
||||
|
@ -2859,7 +2859,7 @@ static void *vpaint_init_vpaint(bContext *C,
|
|||
vpd->is_texbrush = !(brush->vertexpaint_tool == VPAINT_TOOL_BLUR) && brush->mtex.tex;
|
||||
|
||||
if (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) {
|
||||
const GVArray attribute = me->attributes().lookup(me->active_color_attribute, domain);
|
||||
const GVArray attribute = *me->attributes().lookup(me->active_color_attribute, domain);
|
||||
vpd->smear.color_prev = MEM_malloc_arrayN(attribute.size(), attribute.type().size(), __func__);
|
||||
attribute.materialize(vpd->smear.color_prev);
|
||||
|
||||
|
@ -2896,7 +2896,7 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
|
|||
|
||||
ED_mesh_color_ensure(me, nullptr);
|
||||
|
||||
const std::optional<bke::AttributeMetaData> meta_data = me->attributes().lookup_meta_data(
|
||||
const std::optional<bke::AttributeMetaData> meta_data = *me->attributes().lookup_meta_data(
|
||||
me->active_color_attribute);
|
||||
|
||||
if (!meta_data) {
|
||||
|
@ -2957,9 +2957,9 @@ static void do_vpaint_brush_blur_loops(bContext *C,
|
|||
|
||||
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
|
||||
|
||||
const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *me->attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_poly = *me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
|
@ -3100,9 +3100,9 @@ static void do_vpaint_brush_blur_verts(bContext *C,
|
|||
|
||||
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
|
||||
|
||||
const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *me->attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_poly = *me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
|
@ -3248,9 +3248,9 @@ static void do_vpaint_brush_smear(bContext *C,
|
|||
Color *color_prev_smear = static_cast<Color *>(vpd->smear.color_prev);
|
||||
Color *color_prev = reinterpret_cast<Color *>(ss->cache->prev_colors_vpaint);
|
||||
|
||||
const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *me->attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_poly = *me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
|
@ -3415,7 +3415,7 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
|
|||
{
|
||||
using Blend = typename Traits::BlendType;
|
||||
|
||||
const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *me->attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
VPaintAverageAccum<Blend> *accum = (VPaintAverageAccum<Blend> *)MEM_mallocN(
|
||||
|
@ -3532,9 +3532,9 @@ static void vpaint_do_draw(bContext *C,
|
|||
|
||||
Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint);
|
||||
|
||||
const blender::VArray<bool> select_vert = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_vert = *me->attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const blender::VArray<bool> select_poly = me->attributes().lookup_or_default<bool>(
|
||||
const blender::VArray<bool> select_poly = *me->attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
blender::threading::parallel_for(nodes.index_range(), 1LL, [&](IndexRange range) {
|
||||
|
@ -4083,9 +4083,9 @@ static void fill_mesh_face_or_corner_attribute(Mesh &mesh,
|
|||
const bool use_vert_sel,
|
||||
const bool use_face_sel)
|
||||
{
|
||||
const VArray<bool> select_vert = mesh.attributes().lookup_or_default<bool>(
|
||||
const VArray<bool> select_vert = *mesh.attributes().lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
const VArray<bool> select_poly = mesh.attributes().lookup_or_default<bool>(
|
||||
const VArray<bool> select_poly = *mesh.attributes().lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
const OffsetIndices polys = mesh.polys();
|
||||
|
|
|
@ -102,7 +102,7 @@ static bool vertex_paint_from_weight(Object *ob)
|
|||
|
||||
/* Retrieve the vertex group with the domain and type of the existing color
|
||||
* attribute, in order to let the attribute API handle both conversions. */
|
||||
const GVArray vertex_group = attributes.lookup(
|
||||
const GVArray vertex_group = *attributes.lookup(
|
||||
deform_group->name,
|
||||
ATTR_DOMAIN_POINT,
|
||||
bke::cpp_type_to_custom_data_type(color_attribute.varray.type()));
|
||||
|
@ -162,13 +162,13 @@ static IndexMask get_selected_indices(const Mesh &mesh,
|
|||
const bke::AttributeAccessor attributes = mesh.attributes();
|
||||
|
||||
if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) {
|
||||
const VArray<bool> selection = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", domain, false);
|
||||
return index_mask_ops::find_indices_from_virtual_array(
|
||||
selection.index_range(), selection, 4096, indices);
|
||||
}
|
||||
if (mesh.editflag & ME_EDIT_PAINT_VERT_SEL) {
|
||||
const VArray<bool> selection = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", domain, false);
|
||||
return index_mask_ops::find_indices_from_virtual_array(
|
||||
selection.index_range(), selection, 4096, indices);
|
||||
|
@ -190,7 +190,7 @@ static void face_corner_color_equalize_verts(Mesh &mesh, const IndexMask selecti
|
|||
return;
|
||||
}
|
||||
|
||||
GVArray color_attribute_point = attributes.lookup(name, ATTR_DOMAIN_POINT);
|
||||
GVArray color_attribute_point = *attributes.lookup(name, ATTR_DOMAIN_POINT);
|
||||
GVArray color_attribute_corner = attributes.adapt_domain(
|
||||
color_attribute_point, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER);
|
||||
color_attribute_corner.materialize(selection, attribute.span.data());
|
||||
|
|
|
@ -417,7 +417,7 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (mode == SCULPT_FACE_SET_SELECTION) {
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan<bool> select_poly = attributes.lookup_or_default<bool>(
|
||||
const VArraySpan<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
threading::parallel_for(select_poly.index_range(), 4096, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
|
@ -605,7 +605,7 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode)
|
|||
|
||||
if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) {
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArraySpan<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
for (const int i : IndexRange(mesh->totpoly)) {
|
||||
ss->face_sets[i] = material_indices[i] + 1;
|
||||
|
@ -656,7 +656,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
|
||||
switch (mode) {
|
||||
case SCULPT_FACE_SETS_FROM_LOOSE_PARTS: {
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
sculpt_face_sets_init_flood_fill(
|
||||
ob, [&](const int from_face, const int /*edge*/, const int to_face) {
|
||||
|
@ -677,7 +677,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
break;
|
||||
}
|
||||
case SCULPT_FACE_SETS_FROM_UV_SEAMS: {
|
||||
const VArraySpan<bool> uv_seams = mesh->attributes().lookup_or_default<bool>(
|
||||
const VArraySpan<bool> uv_seams = *mesh->attributes().lookup_or_default<bool>(
|
||||
".uv_seam", ATTR_DOMAIN_EDGE, false);
|
||||
sculpt_face_sets_init_flood_fill(
|
||||
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
|
||||
|
@ -695,7 +695,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
|
|||
break;
|
||||
}
|
||||
case SCULPT_FACE_SETS_FROM_SHARP_EDGES: {
|
||||
const VArraySpan<bool> sharp_edges = mesh->attributes().lookup_or_default<bool>(
|
||||
const VArraySpan<bool> sharp_edges = *mesh->attributes().lookup_or_default<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE, false);
|
||||
sculpt_face_sets_init_flood_fill(
|
||||
ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool {
|
||||
|
|
|
@ -349,7 +349,7 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me,
|
|||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_vert = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT);
|
||||
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
|
||||
for (int index = 0; index < me->totvert; index++) {
|
||||
|
@ -380,7 +380,7 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me,
|
|||
bke::MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
bke::SpanAttributeWriter<bool> select_poly = attributes.lookup_or_add_for_write_span<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE);
|
||||
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
for (int index = 0; index < me->totpoly; index++) {
|
||||
|
|
|
@ -101,7 +101,7 @@ static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
|||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
if (use_proportional_edit) {
|
||||
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
|
||||
const VArray<bool> selection = curves.attributes().lookup_or_default<bool>(
|
||||
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
|
||||
".selection", ATTR_DOMAIN_POINT, true);
|
||||
threading::parallel_for(curves.curves_range(), 512, [&](const IndexRange range) {
|
||||
Vector<float> closest_distances;
|
||||
|
|
|
@ -513,9 +513,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id)
|
|||
FrsMaterial tmpMat;
|
||||
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
// We parse the vlak nodes again and import meshes while applying the clipping
|
||||
|
|
|
@ -52,7 +52,7 @@ bke::CurvesGeometry create_curve_from_vert_indices(
|
|||
continue;
|
||||
}
|
||||
|
||||
const GVArray mesh_attribute = mesh_attributes.lookup(attribute_id, ATTR_DOMAIN_POINT);
|
||||
const GVArray mesh_attribute = *mesh_attributes.lookup(attribute_id, ATTR_DOMAIN_POINT);
|
||||
/* Some attributes might not exist if they were builtin attribute on domains that don't
|
||||
* have any elements, i.e. a face attribute on the output of the line primitive node. */
|
||||
if (!mesh_attribute) {
|
||||
|
|
|
@ -108,7 +108,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points,
|
|||
|
||||
/* Transfer the ID attribute if it exists, using the ID of the first merged point. */
|
||||
if (attribute_ids.contains("id")) {
|
||||
VArraySpan<int> src = src_attributes.lookup_or_default<int>("id", ATTR_DOMAIN_POINT, 0);
|
||||
VArraySpan<int> src = *src_attributes.lookup_or_default<int>("id", ATTR_DOMAIN_POINT, 0);
|
||||
bke::SpanAttributeWriter<int> dst = dst_attributes.lookup_or_add_for_write_only_span<int>(
|
||||
"id", ATTR_DOMAIN_POINT);
|
||||
|
||||
|
|
|
@ -699,7 +699,7 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set
|
|||
const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type;
|
||||
const eAttrDomain domain = info.attributes.kinds[attribute_index].domain;
|
||||
if (attributes.contains(attribute_id)) {
|
||||
GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
pointcloud_info.attributes[attribute_index].emplace(std::move(attribute));
|
||||
}
|
||||
}
|
||||
|
@ -710,9 +710,9 @@ static AllPointCloudsInfo preprocess_pointclouds(const GeometrySet &geometry_set
|
|||
}
|
||||
}
|
||||
if (info.create_radius_attribute) {
|
||||
pointcloud_info.radii = attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 0.01f);
|
||||
pointcloud_info.radii = *attributes.lookup_or_default("radius", ATTR_DOMAIN_POINT, 0.01f);
|
||||
}
|
||||
const VArray<float3> position_attribute = attributes.lookup_or_default<float3>(
|
||||
const VArray<float3> position_attribute = *attributes.lookup_or_default<float3>(
|
||||
"position", ATTR_DOMAIN_POINT, float3(0));
|
||||
pointcloud_info.positions = position_attribute.get_internal_span();
|
||||
}
|
||||
|
@ -929,7 +929,7 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set,
|
|||
const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type;
|
||||
const eAttrDomain domain = info.attributes.kinds[attribute_index].domain;
|
||||
if (attributes.contains(attribute_id)) {
|
||||
GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
mesh_info.attributes[attribute_index].emplace(std::move(attribute));
|
||||
}
|
||||
}
|
||||
|
@ -939,8 +939,8 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set,
|
|||
mesh_info.stored_vertex_ids = ids_attribute.varray.get_internal_span().typed<int>();
|
||||
}
|
||||
}
|
||||
mesh_info.material_indices = attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
mesh_info.material_indices =*
|
||||
attributes.lookup_or_default<int>("material_index", ATTR_DOMAIN_FACE, 0);
|
||||
}
|
||||
|
||||
info.no_loose_edges_hint = std::all_of(
|
||||
|
@ -1231,7 +1231,7 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
|
|||
const AttributeIDRef &attribute_id = info.attributes.ids[attribute_index];
|
||||
const eCustomDataType data_type = info.attributes.kinds[attribute_index].data_type;
|
||||
if (attributes.contains(attribute_id)) {
|
||||
GVArray attribute = attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
GVArray attribute = *attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
curve_info.attributes[attribute_index].emplace(std::move(attribute));
|
||||
}
|
||||
}
|
||||
|
@ -1244,12 +1244,12 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
|
|||
|
||||
if (attributes.contains("radius")) {
|
||||
curve_info.radius =
|
||||
attributes.lookup<float>("radius", ATTR_DOMAIN_POINT).get_internal_span();
|
||||
attributes.lookup<float>("radius", ATTR_DOMAIN_POINT).varray.get_internal_span();
|
||||
info.create_radius_attribute = true;
|
||||
}
|
||||
if (attributes.contains("nurbs_weight")) {
|
||||
curve_info.nurbs_weight =
|
||||
attributes.lookup<float>("nurbs_weight", ATTR_DOMAIN_POINT).get_internal_span();
|
||||
attributes.lookup<float>("nurbs_weight", ATTR_DOMAIN_POINT).varray.get_internal_span();
|
||||
info.create_nurbs_weight_attribute = true;
|
||||
}
|
||||
curve_info.resolution = curves.resolution();
|
||||
|
@ -1258,9 +1258,9 @@ static AllCurvesInfo preprocess_curves(const GeometrySet &geometry_set,
|
|||
}
|
||||
if (attributes.contains("handle_right")) {
|
||||
curve_info.handle_left =
|
||||
attributes.lookup<float3>("handle_left", ATTR_DOMAIN_POINT).get_internal_span();
|
||||
attributes.lookup<float3>("handle_left", ATTR_DOMAIN_POINT).varray.get_internal_span();
|
||||
curve_info.handle_right =
|
||||
attributes.lookup<float3>("handle_right", ATTR_DOMAIN_POINT).get_internal_span();
|
||||
attributes.lookup<float3>("handle_right", ATTR_DOMAIN_POINT).varray.get_internal_span();
|
||||
info.create_handle_postion_attributes = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,9 +94,9 @@ static void retrieve_attribute_spans(const Span<bke::AttributeIDRef> ids,
|
|||
Vector<GMutableSpan> &dst,
|
||||
Vector<bke::GSpanAttributeWriter> &dst_attributes)
|
||||
{
|
||||
const bke::AttributeAccessor src_attributes = src_curves.attributes();
|
||||
for (const int i : ids.index_range()) {
|
||||
GVArray src_attribute = src_curves.attributes().lookup(ids[i], ATTR_DOMAIN_POINT);
|
||||
BLI_assert(src_attribute);
|
||||
const GVArray src_attribute = *src_attributes.lookup(ids[i], ATTR_DOMAIN_POINT);
|
||||
src.append(src_attribute.get_internal_span());
|
||||
|
||||
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(src_attribute.type());
|
||||
|
|
|
@ -2077,9 +2077,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
|
|||
edge_feat_settings.func_reduce = feat_data_sum_reduce;
|
||||
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> sharp_edges = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_edges = *attributes.lookup_or_default<bool>(
|
||||
"sharp_edge", ATTR_DOMAIN_EDGE, false);
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
EdgeFeatData edge_feat_data = {nullptr};
|
||||
|
|
|
@ -394,7 +394,7 @@ void ABCGenericMeshWriter::get_geo_groups(Object *object,
|
|||
std::map<std::string, std::vector<int32_t>> &geo_groups)
|
||||
{
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArraySpan<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArraySpan<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
|
||||
for (const int i : material_indices.index_range()) {
|
||||
|
@ -452,7 +452,7 @@ static void get_topology(struct Mesh *mesh,
|
|||
const OffsetIndices polys = mesh->polys();
|
||||
const Span<int> corner_verts = mesh->corner_verts();
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
for (const int i : sharp_faces.index_range()) {
|
||||
if (sharp_faces[i]) {
|
||||
|
|
|
@ -294,7 +294,7 @@ static bool collect_vertex_counts_per_poly(Mesh *me,
|
|||
{
|
||||
const blender::OffsetIndices polys = me->polys();
|
||||
const blender::bke::AttributeAccessor attributes = me->attributes();
|
||||
const blender::VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const blender::VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
bool is_triangulated = true;
|
||||
|
||||
|
@ -404,7 +404,7 @@ void GeometryExporter::create_mesh_primitive_list(short material_index,
|
|||
prepareToAppendValues(is_triangulated, *primitive_list, vcount_list);
|
||||
|
||||
const blender::bke::AttributeAccessor attributes = me->attributes();
|
||||
const blender::VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const blender::VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
|
||||
/* <p> */
|
||||
|
@ -623,7 +623,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals,
|
|||
bool use_custom_normals = false;
|
||||
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
|
||||
BKE_mesh_calc_normals_split(me);
|
||||
|
|
|
@ -89,7 +89,7 @@ static void generate_vertex_map(const Mesh *mesh,
|
|||
const StringRef uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2);
|
||||
if (!uv_name.is_empty()) {
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
uv_map = attributes.lookup<float2>(uv_name, ATTR_DOMAIN_CORNER);
|
||||
uv_map = *attributes.lookup<float2>(uv_name, ATTR_DOMAIN_CORNER);
|
||||
export_uv = !uv_map.is_empty();
|
||||
}
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams
|
|||
if (!name.is_empty()) {
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<ColorGeometry4f> color_attribute =
|
||||
attributes.lookup_or_default<ColorGeometry4f>(
|
||||
*attributes.lookup_or_default<ColorGeometry4f>(
|
||||
name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f});
|
||||
if (!color_attribute.is_empty()) {
|
||||
plyData.vertex_colors.reserve(ply_to_vertex.size());
|
||||
|
|
|
@ -108,7 +108,7 @@ void USDGenericMeshWriter::write_color_data(const Mesh *mesh,
|
|||
pxr::UsdGeomPrimvar colors_pv = pvApi.CreatePrimvar(
|
||||
primvar_name, pxr::SdfValueTypeNames->Color3fArray, prim_varying);
|
||||
|
||||
const VArray<ColorGeometry4f> attribute = mesh->attributes().lookup_or_default<ColorGeometry4f>(
|
||||
const VArray<ColorGeometry4f> attribute = *mesh->attributes().lookup_or_default<ColorGeometry4f>(
|
||||
attribute_id, meta_data.domain, {0.0f, 0.0f, 0.0f, 1.0f});
|
||||
|
||||
pxr::VtArray<pxr::GfVec3f> colors_data;
|
||||
|
@ -345,7 +345,7 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data)
|
|||
/* Only construct face groups (a.k.a. geometry subsets) when we need them for material
|
||||
* assignments. */
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
if (!material_indices.is_single() && mesh->totcol > 1) {
|
||||
const VArraySpan<int> indices_span(material_indices);
|
||||
|
@ -513,7 +513,7 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_
|
|||
bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const Span<float3> vert_normals = mesh->vert_normals();
|
||||
const Span<float3> poly_normals = mesh->poly_normals();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
const VArray<bool> sharp_faces = *attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
for (const int i : polys.index_range()) {
|
||||
const IndexRange poly = polys[i];
|
||||
|
|
|
@ -254,7 +254,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
|
|||
const StringRef name = mesh->active_color_attribute;
|
||||
if (write_colors && !name.is_empty()) {
|
||||
const bke::AttributeAccessor attributes = mesh->attributes();
|
||||
const VArray<ColorGeometry4f> attribute = attributes.lookup_or_default<ColorGeometry4f>(
|
||||
const VArray<ColorGeometry4f> attribute = *attributes.lookup_or_default<ColorGeometry4f>(
|
||||
name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f});
|
||||
|
||||
BLI_assert(tot_count == attribute.size());
|
||||
|
@ -338,7 +338,7 @@ void OBJWriter::write_poly_elements(FormatHandler &fh,
|
|||
const int tot_deform_groups = obj_mesh_data.tot_deform_groups();
|
||||
threading::EnumerableThreadSpecific<Vector<float>> group_weights;
|
||||
const bke::AttributeAccessor attributes = obj_mesh_data.get_mesh()->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
|
||||
obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler &buf, int idx) {
|
||||
|
|
|
@ -44,7 +44,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
|
|||
mesh_edges_ = export_mesh_->edges();
|
||||
mesh_polys_ = export_mesh_->polys();
|
||||
mesh_corner_verts_ = export_mesh_->corner_verts();
|
||||
sharp_faces_ = export_mesh_->attributes().lookup_or_default<bool>(
|
||||
sharp_faces_ = *export_mesh_->attributes().lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
}
|
||||
else {
|
||||
|
@ -78,7 +78,7 @@ void OBJMesh::set_mesh(Mesh *mesh)
|
|||
mesh_edges_ = mesh->edges();
|
||||
mesh_polys_ = mesh->polys();
|
||||
mesh_corner_verts_ = mesh->corner_verts();
|
||||
sharp_faces_ = export_mesh_->attributes().lookup_or_default<bool>(
|
||||
sharp_faces_ = *export_mesh_->attributes().lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ void OBJMesh::calc_smooth_groups(const bool use_bitflags)
|
|||
void OBJMesh::calc_poly_order()
|
||||
{
|
||||
const bke::AttributeAccessor attributes = export_mesh_->attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
if (material_indices.is_single() && material_indices.get_internal_single() == 0) {
|
||||
return;
|
||||
|
@ -296,7 +296,7 @@ void OBJMesh::store_uv_coords_and_indices()
|
|||
return;
|
||||
}
|
||||
const bke::AttributeAccessor attributes = export_mesh_->attributes();
|
||||
const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan uv_map = *attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
|
||||
if (uv_map.is_empty()) {
|
||||
uv_coords_.clear();
|
||||
return;
|
||||
|
|
|
@ -333,8 +333,8 @@ static void mesh_merge_transform(Mesh *result,
|
|||
}
|
||||
|
||||
const bke::AttributeAccessor cap_attributes = cap_mesh->attributes();
|
||||
if (const VArray<int> cap_material_indices = cap_attributes.lookup<int>("material_index",
|
||||
ATTR_DOMAIN_FACE)) {
|
||||
if (const VArray cap_material_indices = *cap_attributes.lookup<int>("material_index",
|
||||
ATTR_DOMAIN_FACE)) {
|
||||
bke::MutableAttributeAccessor result_attributes = result->attributes_for_write();
|
||||
bke::SpanAttributeWriter<int> result_material_indices =
|
||||
result_attributes.lookup_or_add_for_write_span<int>("material_index", ATTR_DOMAIN_FACE);
|
||||
|
|
|
@ -1086,10 +1086,8 @@ static void store_computed_output_attributes(
|
|||
|
||||
/* Try to create the attribute reusing the stored buffer. This will only succeed if the
|
||||
* attribute didn't exist before, or if it existed but was removed above. */
|
||||
if (attributes.add(store.name,
|
||||
store.domain,
|
||||
bke::cpp_type_to_custom_data_type(store.data.type()),
|
||||
bke::AttributeInitMoveArray(store.data.data()))) {
|
||||
if (attributes.add(
|
||||
store.name, store.domain, data_type, bke::AttributeInitMoveArray(store.data.data()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -138,8 +138,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
|
|||
|
||||
if (const Mesh *mesh = geometry_set.get_mesh_for_read()) {
|
||||
count++;
|
||||
if (const VArray<float3> positions = mesh->attributes().lookup<float3>("position",
|
||||
ATTR_DOMAIN_POINT)) {
|
||||
if (const VArray positions = *mesh->attributes().lookup<float3>("position")) {
|
||||
if (positions.is_span()) {
|
||||
span_count++;
|
||||
positions_span = positions.get_internal_span();
|
||||
|
@ -150,8 +149,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
|
|||
|
||||
if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) {
|
||||
count++;
|
||||
if (const VArray<float3> positions = points->attributes().lookup<float3>("position",
|
||||
ATTR_DOMAIN_POINT)) {
|
||||
if (const VArray positions = *points->attributes().lookup<float3>("position")) {
|
||||
if (positions.is_span()) {
|
||||
span_count++;
|
||||
positions_span = positions.get_internal_span();
|
||||
|
@ -182,16 +180,14 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
|
|||
int offset = 0;
|
||||
|
||||
if (const Mesh *mesh = geometry_set.get_mesh_for_read()) {
|
||||
if (const VArray<float3> varray = mesh->attributes().lookup<float3>("position",
|
||||
ATTR_DOMAIN_POINT)) {
|
||||
if (const VArray varray = *mesh->attributes().lookup<float3>("position")) {
|
||||
varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
|
||||
offset += varray.size();
|
||||
}
|
||||
}
|
||||
|
||||
if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) {
|
||||
if (const VArray<float3> varray = points->attributes().lookup<float3>("position",
|
||||
ATTR_DOMAIN_POINT)) {
|
||||
if (const VArray varray = *points->attributes().lookup<float3>("position")) {
|
||||
varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
|
||||
offset += varray.size();
|
||||
}
|
||||
|
|
|
@ -82,20 +82,21 @@ static void fill_rotation_attribute(const Span<float3> tangents,
|
|||
static void copy_curve_domain_attributes(const AttributeAccessor curve_attributes,
|
||||
MutableAttributeAccessor point_attributes)
|
||||
{
|
||||
curve_attributes.for_all([&](const bke::AttributeIDRef &id,
|
||||
const bke::AttributeMetaData &meta_data) {
|
||||
if (curve_attributes.is_builtin(id)) {
|
||||
return true;
|
||||
}
|
||||
if (meta_data.domain != ATTR_DOMAIN_CURVE) {
|
||||
return true;
|
||||
}
|
||||
point_attributes.add(id,
|
||||
ATTR_DOMAIN_POINT,
|
||||
meta_data.data_type,
|
||||
bke::AttributeInitVArray(curve_attributes.lookup(id, ATTR_DOMAIN_POINT)));
|
||||
return true;
|
||||
});
|
||||
curve_attributes.for_all(
|
||||
[&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) {
|
||||
if (curve_attributes.is_builtin(id)) {
|
||||
return true;
|
||||
}
|
||||
if (meta_data.domain != ATTR_DOMAIN_CURVE) {
|
||||
return true;
|
||||
}
|
||||
point_attributes.add(
|
||||
id,
|
||||
ATTR_DOMAIN_POINT,
|
||||
meta_data.data_type,
|
||||
bke::AttributeInitVArray(*curve_attributes.lookup(id, ATTR_DOMAIN_POINT)));
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
static PointCloud *pointcloud_from_curves(bke::CurvesGeometry curves,
|
||||
|
@ -108,8 +109,8 @@ static PointCloud *pointcloud_from_curves(bke::CurvesGeometry curves,
|
|||
|
||||
if (rotation_id) {
|
||||
MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
const VArraySpan<float3> tangents = attributes.lookup<float3>(tangent_id, ATTR_DOMAIN_POINT);
|
||||
const VArraySpan<float3> normals = attributes.lookup<float3>(normal_id, ATTR_DOMAIN_POINT);
|
||||
const VArraySpan tangents = *attributes.lookup<float3>(tangent_id, ATTR_DOMAIN_POINT);
|
||||
const VArraySpan normals = *attributes.lookup<float3>(normal_id, ATTR_DOMAIN_POINT);
|
||||
SpanAttributeWriter<float3> rotations = attributes.lookup_or_add_for_write_only_span<float3>(
|
||||
rotation_id, ATTR_DOMAIN_POINT);
|
||||
fill_rotation_attribute(tangents, normals, rotations.span);
|
||||
|
|
|
@ -298,13 +298,13 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
TIP_("Curves are not attached to any UV map"));
|
||||
return;
|
||||
}
|
||||
const VArraySpan<float2> uv_map_orig = mesh_attributes_orig.lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan<float2> uv_map_eval = mesh_attributes_eval.lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan<float3> rest_positions = mesh_attributes_eval.lookup<float3>(rest_position_name,
|
||||
ATTR_DOMAIN_POINT);
|
||||
const VArraySpan<float2> surface_uv_coords = curves.attributes().lookup_or_default(
|
||||
const VArraySpan uv_map_orig = *mesh_attributes_orig.lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan uv_map_eval = *mesh_attributes_eval.lookup<float2>(uv_map_name,
|
||||
ATTR_DOMAIN_CORNER);
|
||||
const VArraySpan rest_positions = *mesh_attributes_eval.lookup<float3>(rest_position_name,
|
||||
ATTR_DOMAIN_POINT);
|
||||
const VArraySpan surface_uv_coords = *curves.attributes().lookup_or_default<float2>(
|
||||
"surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0));
|
||||
|
||||
const Span<MLoopTri> looptris_orig = surface_mesh_orig->looptris();
|
||||
|
@ -374,7 +374,7 @@ static void node_geo_exec(GeoNodeExecParams params)
|
|||
invalid_uv_count);
|
||||
/* Then also deform edit curve information for use in sculpt mode. */
|
||||
const CurvesGeometry &curves_orig = edit_hints->curves_id_orig.geometry.wrap();
|
||||
const VArraySpan<float2> surface_uv_coords_orig = curves_orig.attributes().lookup_or_default(
|
||||
const VArraySpan<float2> surface_uv_coords_orig = *curves_orig.attributes().lookup_or_default(
|
||||
"surface_uv_coordinate", ATTR_DOMAIN_CURVE, float2(0));
|
||||
if (!surface_uv_coords_orig.is_empty()) {
|
||||
deform_curves(curves_orig,
|
||||
|
|
|
@ -41,7 +41,7 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput {
|
|||
|
||||
const AttributeAccessor attributes = curves.attributes();
|
||||
StringRef side = left_ ? "handle_left" : "handle_right";
|
||||
VArray<float3> handles = attributes.lookup_or_default<float3>(
|
||||
VArray<float3> handles = *attributes.lookup_or_default<float3>(
|
||||
side, ATTR_DOMAIN_POINT, {0, 0, 0});
|
||||
|
||||
if (relative.is_single()) {
|
||||
|
|
|
@ -76,6 +76,7 @@ static void add_instances_from_component(
|
|||
if (selection.is_empty()) {
|
||||
return;
|
||||
}
|
||||
const AttributeAccessor src_attributes = *src_component.attributes();
|
||||
|
||||
/* The initial size of the component might be non-zero when this function is called for multiple
|
||||
* component types. */
|
||||
|
@ -86,8 +87,7 @@ static void add_instances_from_component(
|
|||
MutableSpan<int> dst_handles = dst_component.reference_handles().slice(start_len, select_len);
|
||||
MutableSpan<float4x4> dst_transforms = dst_component.transforms().slice(start_len, select_len);
|
||||
|
||||
VArray<float3> positions = src_component.attributes()->lookup_or_default<float3>(
|
||||
"position", domain, {0, 0, 0});
|
||||
const VArraySpan positions = *src_attributes.lookup<float3>("position");
|
||||
|
||||
const bke::Instances *src_instances = instance.get_instances_for_read();
|
||||
|
||||
|
@ -158,24 +158,28 @@ static void add_instances_from_component(
|
|||
}
|
||||
}
|
||||
|
||||
bke::CustomDataAttributes &instance_attributes = dst_component.custom_data_attributes();
|
||||
bke::MutableAttributeAccessor dst_attributes = dst_component.attributes_for_write();
|
||||
for (const auto item : attributes_to_propagate.items()) {
|
||||
const AttributeIDRef &attribute_id = item.key;
|
||||
const AttributeKind attribute_kind = item.value;
|
||||
|
||||
const GVArray src_attribute = src_component.attributes()->lookup_or_default(
|
||||
attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
|
||||
BLI_assert(src_attribute);
|
||||
std::optional<GMutableSpan> dst_attribute_opt = instance_attributes.get_for_write(
|
||||
attribute_id);
|
||||
if (!dst_attribute_opt) {
|
||||
if (!instance_attributes.create(attribute_id, attribute_kind.data_type)) {
|
||||
continue;
|
||||
}
|
||||
dst_attribute_opt = instance_attributes.get_for_write(attribute_id);
|
||||
const AttributeIDRef &id = item.key;
|
||||
const bke::GAttributeReader src = src_attributes.lookup(id, ATTR_DOMAIN_POINT);
|
||||
if (!src) {
|
||||
/* Domain interpolation can fail if the source domain is empty. */
|
||||
continue;
|
||||
}
|
||||
|
||||
const eCustomDataType type = bke::cpp_type_to_custom_data_type(src.varray.type());
|
||||
if (src.varray.size() == dst_component.instances_num() && src.sharing_info &&
|
||||
src.varray.is_span()) {
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(),
|
||||
*src.sharing_info);
|
||||
dst_attributes.add(id, ATTR_DOMAIN_INSTANCE, type, init);
|
||||
}
|
||||
else {
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_INSTANCE, type);
|
||||
array_utils::gather(src.varray, selection, dst.span.slice(start_len, select_len));
|
||||
dst.finish();
|
||||
}
|
||||
BLI_assert(dst_attribute_opt);
|
||||
array_utils::gather(src_attribute, selection, dst_attribute_opt->slice(start_len, select_len));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,12 +50,13 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
|
|||
geometry_set.replace_pointcloud(pointcloud);
|
||||
array_utils::gather(positions, selection, pointcloud->positions_for_write());
|
||||
|
||||
bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write();
|
||||
bke::MutableAttributeAccessor dst_attributes = pointcloud->attributes_for_write();
|
||||
bke::SpanAttributeWriter<float> point_radii =
|
||||
point_attributes.lookup_or_add_for_write_only_span<float>("radius", ATTR_DOMAIN_POINT);
|
||||
dst_attributes.lookup_or_add_for_write_only_span<float>("radius", ATTR_DOMAIN_POINT);
|
||||
array_utils::gather(radii, selection, point_radii.span);
|
||||
point_radii.finish();
|
||||
|
||||
const bke::AttributeAccessor src_attributes = instances.attributes();
|
||||
Map<AttributeIDRef, AttributeKind> attributes_to_propagate;
|
||||
geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES},
|
||||
GEO_COMPONENT_TYPE_POINT_CLOUD,
|
||||
|
@ -67,18 +68,22 @@ static void convert_instances_to_points(GeometrySet &geometry_set,
|
|||
attributes_to_propagate.remove("radius");
|
||||
|
||||
for (const auto item : attributes_to_propagate.items()) {
|
||||
const AttributeIDRef &attribute_id = item.key;
|
||||
const AttributeKind attribute_kind = item.value;
|
||||
const AttributeIDRef &id = item.key;
|
||||
const eCustomDataType type = item.value.data_type;
|
||||
|
||||
const GVArray src = instances.attributes().lookup_or_default(
|
||||
attribute_id, ATTR_DOMAIN_INSTANCE, attribute_kind.data_type);
|
||||
BLI_assert(src);
|
||||
GSpanAttributeWriter dst = point_attributes.lookup_or_add_for_write_only_span(
|
||||
attribute_id, ATTR_DOMAIN_POINT, attribute_kind.data_type);
|
||||
BLI_assert(dst);
|
||||
|
||||
src.materialize_compressed_to_uninitialized(selection, dst.span.data());
|
||||
dst.finish();
|
||||
const GAttributeReader src = src_attributes.lookup(id);
|
||||
if (selection.size() == instances.instances_num() && src.sharing_info &&
|
||||
src.varray.is_span()) {
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(),
|
||||
*src.sharing_info);
|
||||
dst_attributes.add(id, ATTR_DOMAIN_POINT, type, init);
|
||||
}
|
||||
else {
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_POINT, type);
|
||||
array_utils::gather(src.varray, selection, dst.span);
|
||||
dst.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -446,7 +446,8 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
|
|||
if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) {
|
||||
return true;
|
||||
}
|
||||
if (meta_data.data_type == CD_PROP_STRING) {
|
||||
const eCustomDataType type = meta_data.data_type;
|
||||
if (type == CD_PROP_STRING) {
|
||||
return true;
|
||||
}
|
||||
if (guide_curve_attributes.is_builtin(id) &&
|
||||
|
@ -455,15 +456,14 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
|
|||
}
|
||||
|
||||
if (meta_data.domain == ATTR_DOMAIN_CURVE) {
|
||||
const GVArraySpan src_generic = guide_curve_attributes.lookup(
|
||||
id, ATTR_DOMAIN_CURVE, meta_data.data_type);
|
||||
const GVArraySpan src_generic = *guide_curve_attributes.lookup(id, ATTR_DOMAIN_CURVE, type);
|
||||
|
||||
GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_CURVE, meta_data.data_type);
|
||||
id, ATTR_DOMAIN_CURVE, type);
|
||||
if (!dst_generic) {
|
||||
return true;
|
||||
}
|
||||
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
|
||||
attribute_math::convert_to_static_type(type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
const Span<T> src = src_generic.typed<T>();
|
||||
MutableSpan<T> dst = dst_generic.span.typed<T>();
|
||||
|
@ -490,15 +490,14 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
|
|||
}
|
||||
else {
|
||||
BLI_assert(meta_data.domain == ATTR_DOMAIN_POINT);
|
||||
const GVArraySpan src_generic = guide_curve_attributes.lookup(
|
||||
id, ATTR_DOMAIN_POINT, meta_data.data_type);
|
||||
const GVArraySpan src_generic = *guide_curve_attributes.lookup(id, ATTR_DOMAIN_POINT, type);
|
||||
GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_POINT, meta_data.data_type);
|
||||
id, ATTR_DOMAIN_POINT, type);
|
||||
if (!dst_generic) {
|
||||
return true;
|
||||
}
|
||||
|
||||
attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) {
|
||||
attribute_math::convert_to_static_type(type, [&](auto dummy) {
|
||||
using T = decltype(dummy);
|
||||
const Span<T> src = src_generic.typed<T>();
|
||||
MutableSpan<T> dst = dst_generic.span.typed<T>();
|
||||
|
@ -579,14 +578,16 @@ static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves,
|
|||
return true;
|
||||
}
|
||||
|
||||
const GVArray src = point_attributes.lookup(id, ATTR_DOMAIN_POINT, meta_data.data_type);
|
||||
GSpanAttributeWriter dst = children_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_CURVE, meta_data.data_type);
|
||||
if (!dst) {
|
||||
return true;
|
||||
const GAttributeReader src = point_attributes.lookup(id);
|
||||
if (src.sharing_info && src.varray.is_span()) {
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(),
|
||||
*src.sharing_info);
|
||||
children_attributes.add(id, ATTR_DOMAIN_CURVE, meta_data.data_type, init);
|
||||
}
|
||||
else {
|
||||
children_attributes.add(
|
||||
id, ATTR_DOMAIN_CURVE, meta_data.data_type, bke::AttributeInitVArray(src.varray));
|
||||
}
|
||||
src.materialize(dst.span.data());
|
||||
dst.finish();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -673,7 +674,7 @@ static GeometrySet generate_interpolated_curves(
|
|||
}
|
||||
});
|
||||
|
||||
const VArraySpan point_positions = point_attributes.lookup<float3>("position");
|
||||
const VArraySpan point_positions = *point_attributes.lookup<float3>("position");
|
||||
const int num_child_curves = point_attributes.domain_size(ATTR_DOMAIN_POINT);
|
||||
|
||||
/* The set of guides per child are stored in a flattened array to allow fast access, reduce
|
||||
|
|
|
@ -65,7 +65,7 @@ static void fill_new_attribute(Span<const GeometryComponent *> src_components,
|
|||
if (domain_num == 0) {
|
||||
continue;
|
||||
}
|
||||
GVArray read_attribute = component->attributes()->lookup_or_default(
|
||||
GVArray read_attribute = *component->attributes()->lookup_or_default(
|
||||
attribute_id, domain, data_type, nullptr);
|
||||
|
||||
GVArraySpan src_span{read_attribute};
|
||||
|
|
|
@ -35,7 +35,7 @@ static VArray<bool> select_mesh_faces_by_material(const Mesh &mesh,
|
|||
}
|
||||
|
||||
const AttributeAccessor attributes = mesh.attributes();
|
||||
const VArray<int> material_indices = attributes.lookup_or_default<int>(
|
||||
const VArray<int> material_indices = *attributes.lookup_or_default<int>(
|
||||
"material_index", ATTR_DOMAIN_FACE, 0);
|
||||
if (material_indices.is_single()) {
|
||||
const int slot_i = material_indices.get_internal_single();
|
||||
|
|
|
@ -93,7 +93,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions,
|
|||
* have a simple utility for that yet though so there is some overhead right now. */
|
||||
MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
if (create_uv_map) {
|
||||
const VArraySpan<float2> orig_uv_map = attributes.lookup<float2>("UVMap");
|
||||
const VArraySpan orig_uv_map = *attributes.lookup<float2>("UVMap");
|
||||
SpanAttributeWriter<float2> uv_map = attributes.lookup_or_add_for_write_only_span<float2>(
|
||||
uv_map_id, ATTR_DOMAIN_CORNER);
|
||||
uv_map.span.copy_from(orig_uv_map);
|
||||
|
|
|
@ -62,6 +62,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
|
|||
geometry_set.remove_geometry_during_modify();
|
||||
return;
|
||||
}
|
||||
const AttributeAccessor src_attributes = mesh->attributes();
|
||||
bke::MeshFieldContext field_context{*mesh, domain};
|
||||
fn::FieldEvaluator evaluator{field_context, domain_size};
|
||||
evaluator.set_selection(selection_field);
|
||||
|
@ -72,16 +73,30 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
|
|||
evaluator.add(radius_field);
|
||||
evaluator.evaluate();
|
||||
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
|
||||
const VArray<float3> positions_eval = evaluator.get_evaluated<float3>(0);
|
||||
const VArray<float> radii_eval = evaluator.get_evaluated<float>(1);
|
||||
|
||||
const bool share_arrays = selection.size() == domain_size;
|
||||
const bool share_position = share_arrays && positions_eval.is_span() &&
|
||||
positions_eval.get_internal_span().data() ==
|
||||
mesh->vert_positions().data();
|
||||
|
||||
PointCloud *pointcloud;
|
||||
if (share_position) {
|
||||
/* Create an empty point cloud so the positions can be shared. */
|
||||
pointcloud = BKE_pointcloud_new_nomain(0);
|
||||
CustomData_free_layer_named(&pointcloud->pdata, "position", pointcloud->totpoint);
|
||||
pointcloud->totpoint = mesh->totvert;
|
||||
const bke::AttributeReader src = src_attributes.lookup<float3>("position");
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(), *src.sharing_info);
|
||||
pointcloud->attributes_for_write().add<float3>("position", ATTR_DOMAIN_POINT, init);
|
||||
}
|
||||
else {
|
||||
pointcloud = BKE_pointcloud_new_nomain(selection.size());
|
||||
array_utils::gather(positions_eval, selection, pointcloud->positions_for_write());
|
||||
}
|
||||
|
||||
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
|
||||
geometry_set.replace_pointcloud(pointcloud);
|
||||
MutableAttributeAccessor dst_attributes = pointcloud->attributes_for_write();
|
||||
|
||||
GSpanAttributeWriter position = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
"position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3);
|
||||
array_utils::gather(evaluator.get_evaluated(0), selection, position.span);
|
||||
position.finish();
|
||||
|
||||
GSpanAttributeWriter radius = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
"radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT);
|
||||
array_utils::gather(evaluator.get_evaluated(1), selection, radius.span);
|
||||
|
@ -93,22 +108,32 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set,
|
|||
false,
|
||||
propagation_info,
|
||||
attributes);
|
||||
attributes.remove("radius");
|
||||
attributes.remove("position");
|
||||
|
||||
const AttributeAccessor src_attributes = mesh->attributes();
|
||||
|
||||
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
|
||||
const AttributeIDRef attribute_id = entry.key;
|
||||
const eCustomDataType data_type = entry.value.data_type;
|
||||
GVArray src = src_attributes.lookup_or_default(attribute_id, domain, data_type);
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
attribute_id, ATTR_DOMAIN_POINT, data_type);
|
||||
if (dst && src) {
|
||||
array_utils::gather(src, selection, dst.span);
|
||||
const bke::GAttributeReader src = src_attributes.lookup(attribute_id, domain, data_type);
|
||||
if (!src) {
|
||||
/* Domain interpolation can fail if the source domain is empty. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (share_arrays && src.domain == domain && src.sharing_info && src.varray.is_span()) {
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(),
|
||||
*src.sharing_info);
|
||||
dst_attributes.add(attribute_id, ATTR_DOMAIN_POINT, data_type, init);
|
||||
}
|
||||
else {
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
attribute_id, ATTR_DOMAIN_POINT, data_type);
|
||||
array_utils::gather(src.varray, selection, dst.span);
|
||||
dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
geometry_set.replace_pointcloud(pointcloud);
|
||||
geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_POINT_CLOUD});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_array_utils.hh"
|
||||
|
||||
#include "DNA_pointcloud_types.h"
|
||||
|
||||
|
@ -49,26 +49,40 @@ static void geometry_set_points_to_vertices(
|
|||
propagation_info,
|
||||
attributes);
|
||||
|
||||
Mesh *mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0);
|
||||
geometry_set.replace_mesh(mesh);
|
||||
Mesh *mesh;
|
||||
if (selection.size() == points->totpoint) {
|
||||
/* Create a mesh without positions so the attribute can be shared. */
|
||||
mesh = BKE_mesh_new_nomain(0, 0, 0, 0);
|
||||
CustomData_free_layer_named(&mesh->vdata, "position", mesh->totvert);
|
||||
mesh->totvert = selection.size();
|
||||
}
|
||||
else {
|
||||
mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0);
|
||||
}
|
||||
|
||||
const AttributeAccessor src_attributes = points->attributes();
|
||||
MutableAttributeAccessor dst_attributes = mesh->attributes_for_write();
|
||||
|
||||
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
|
||||
const AttributeIDRef attribute_id = entry.key;
|
||||
const AttributeIDRef id = entry.key;
|
||||
const eCustomDataType data_type = entry.value.data_type;
|
||||
GVArray src = src_attributes.lookup_or_default(attribute_id, ATTR_DOMAIN_POINT, data_type);
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
attribute_id, ATTR_DOMAIN_POINT, data_type);
|
||||
if (dst && src) {
|
||||
src.materialize_compressed_to_uninitialized(selection, dst.span.data());
|
||||
const GAttributeReader src = src_attributes.lookup(id);
|
||||
if (selection.size() == points->totpoint && src.sharing_info && src.varray.is_span()) {
|
||||
const bke::AttributeInitShared init(src.varray.get_internal_span().data(),
|
||||
*src.sharing_info);
|
||||
dst_attributes.add(id, ATTR_DOMAIN_POINT, data_type, init);
|
||||
}
|
||||
else {
|
||||
GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span(
|
||||
id, ATTR_DOMAIN_POINT, data_type);
|
||||
array_utils::gather(src.varray, selection, dst.span);
|
||||
dst.finish();
|
||||
}
|
||||
}
|
||||
|
||||
mesh->loose_edges_tag_none();
|
||||
|
||||
geometry_set.replace_mesh(mesh);
|
||||
geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH});
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@ static void gather_point_data_from_component(Field<float> radius_field,
|
|||
if (component.is_empty()) {
|
||||
return;
|
||||
}
|
||||
VArray<float3> positions = component.attributes()->lookup_or_default<float3>(
|
||||
"position", ATTR_DOMAIN_POINT, {0, 0, 0});
|
||||
const VArray<float3> positions = *component.attributes()->lookup<float3>("position");
|
||||
|
||||
bke::GeometryFieldContext field_context{component, ATTR_DOMAIN_POINT};
|
||||
const int domain_num = component.attribute_domain_size(ATTR_DOMAIN_POINT);
|
||||
|
|
|
@ -31,10 +31,10 @@ static void set_computed_position_and_offset(GeometryComponent &component,
|
|||
MutableAttributeAccessor attributes = *component.attributes_for_write();
|
||||
|
||||
/* Optimize the case when `in_positions` references the original positions array. */
|
||||
const VArray<float3> positions_read_only = attributes.lookup<float3>("position");
|
||||
const bke::AttributeReader positions_read_only = attributes.lookup<float3>("position");
|
||||
bool positions_are_original = false;
|
||||
if (positions_read_only.is_span() && in_positions.is_span()) {
|
||||
positions_are_original = positions_read_only.get_internal_span().data() ==
|
||||
if (positions_read_only.varray.is_span() && in_positions.is_span()) {
|
||||
positions_are_original = positions_read_only.varray.get_internal_span().data() ==
|
||||
in_positions.get_internal_span().data();
|
||||
}
|
||||
|
||||
|
|
|
@ -466,8 +466,8 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval
|
|||
const blender::OffsetIndices polys = me->polys();
|
||||
const blender::Span<int> corner_verts = me->corner_verts();
|
||||
const bke::AttributeAccessor attributes = me->attributes();
|
||||
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
|
||||
"sharp_face", ATTR_DOMAIN_FACE, false);
|
||||
const VArray<bool> sharp_faces =
|
||||
attributes.lookup_or_default<bool>("sharp_face", ATTR_DOMAIN_FACE, false).varray;
|
||||
|
||||
looptri = static_cast<MLoopTri *>(MEM_mallocN(sizeof(*looptri) * tottri, __func__));
|
||||
triangles = static_cast<TriTessFace *>(MEM_callocN(sizeof(TriTessFace) * tottri, __func__));
|
||||
|
|
Loading…
Reference in New Issue
I think you make too many implicit assumptions here:
Both assumptions generally have to be checked for.
I thought it was reasonable to assume that
sharing_info != nullptr
impliesvarray.is_span()
, but I can also check the latter explicitly too. I guess this will get nicer when attributes don't always have to be stored as contiguous arrays.I should definitely check for
sharing_info
here though. I did it elsewhere and forgot here.