From 17aea2a75327c4554c3abc0900942c2a671234bd Mon Sep 17 00:00:00 2001 From: Falk David Date: Fri, 14 Apr 2023 13:15:07 +0200 Subject: [PATCH 01/24] Initial commit --- source/blender/blenkernel/BKE_curves.hh | 9 ++++++++ .../blenkernel/intern/curves_geometry.cc | 22 +++++++++++++++++++ source/blender/makesdna/DNA_curves_types.h | 10 +++++++++ 3 files changed, 41 insertions(+) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index a6f60772f85..ffe97f61654 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -25,6 +25,8 @@ #include "BKE_attribute_math.hh" #include "BKE_curves.h" +#include "DNA_meshdata_types.h" + namespace blender::bke { namespace curves::nurbs { @@ -257,6 +259,13 @@ class CurvesGeometry : public ::CurvesGeometry { Span surface_uv_coords() const; MutableSpan surface_uv_coords_for_write(); + /** + * Vertex group data, encoded as an array of indices and weights for every vertex. + * \warning: May be empty. + */ + Span deform_verts() const; + MutableSpan deform_verts_for_write(); + /** * The largest and smallest position values of evaluated points. */ diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index c175606d1bd..460af28c1c5 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -458,6 +458,28 @@ MutableSpan CurvesGeometry::surface_uv_coords_for_write() return get_mutable_attribute(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_UV_COORDINATE); } +Span CurvesGeometry::deform_verts() const +{ + const MDeformVert *dverts = (const MDeformVert *)CustomData_get_layer(&this->point_data, + CD_MDEFORMVERT); + if (dverts == nullptr) { + return {}; + } + return {dverts, this->point_num}; +} + +MutableSpan CurvesGeometry::deform_verts_for_write() +{ + MDeformVert *dvert = (MDeformVert *)CustomData_get_layer_for_write( + &this->point_data, CD_MDEFORMVERT, this->point_num); + if (dvert != nullptr) { + return {dvert, this->point_num}; + } + return {(MDeformVert *)CustomData_add_layer( + &this->point_data, CD_MDEFORMVERT, CD_SET_DEFAULT, this->point_num), + this->point_num}; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index e209c5857b8..75c76962139 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -10,7 +10,9 @@ #include "DNA_ID.h" #include "DNA_customdata_types.h" +#include "DNA_object_types.h" +#include "BLI_listbase.h" #include "BLI_utildefines.h" #ifdef __cplusplus @@ -132,6 +134,14 @@ typedef struct CurvesGeometry { */ int curve_num; + /** + * List of vertex group (#bDeformGroup) names and flags only. + */ + ListBase vertex_group_names; + /** The active index in the #vertex_group_names list. */ + int vertex_group_active_index; + char _pad[4]; + /** * Runtime data for curves, stored as a pointer to allow defining this as a C++ class. */ -- 2.30.2 From da05c97961be881501f28d3646ba6e52935ed81e Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 18 Apr 2023 13:40:41 +0200 Subject: [PATCH 02/24] Use static_cast --- source/blender/blenkernel/intern/curves_geometry.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 460af28c1c5..47a253fcbc9 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -460,8 +460,8 @@ MutableSpan CurvesGeometry::surface_uv_coords_for_write() Span CurvesGeometry::deform_verts() const { - const MDeformVert *dverts = (const MDeformVert *)CustomData_get_layer(&this->point_data, - CD_MDEFORMVERT); + const MDeformVert *dverts = static_cast( + CustomData_get_layer(&this->point_data, CD_MDEFORMVERT)); if (dverts == nullptr) { return {}; } @@ -470,8 +470,8 @@ Span CurvesGeometry::deform_verts() const MutableSpan CurvesGeometry::deform_verts_for_write() { - MDeformVert *dvert = (MDeformVert *)CustomData_get_layer_for_write( - &this->point_data, CD_MDEFORMVERT, this->point_num); + MDeformVert *dvert = static_cast( + CustomData_get_layer_for_write(&this->point_data, CD_MDEFORMVERT, this->point_num)); if (dvert != nullptr) { return {dvert, this->point_num}; } -- 2.30.2 From 57de98a8ef01b2b234c669783a802865a3801410 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 18 Apr 2023 18:15:41 +0200 Subject: [PATCH 03/24] Data handling of vertex group names list --- .../blender/blenkernel/intern/curves_geometry.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 47a253fcbc9..c98455208cb 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -28,6 +28,7 @@ #include "BKE_curves.hh" #include "BKE_curves_utils.hh" #include "BKE_customdata.h" +#include "BKE_deform.h" namespace blender::bke { @@ -81,6 +82,8 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num) this->curve_offsets = nullptr; } + BLI_listbase_clear(&this->vertex_group_names); + /* Fill the type counts with the default so they're in a valid state. */ this->runtime->type_counts[CURVE_TYPE_CATMULL_ROM] = curve_num; } @@ -97,6 +100,9 @@ static void copy_curves_geometry(CurvesGeometry &dst, const CurvesGeometry &src) CustomData_copy(&src.point_data, &dst.point_data, CD_MASK_ALL, dst.point_num); CustomData_copy(&src.curve_data, &dst.curve_data, CD_MASK_ALL, dst.curve_num); + dst.vertex_group_active_index = src.vertex_group_active_index; + BKE_defgroup_copy_list(&dst.vertex_group_names, &src.vertex_group_names); + implicit_sharing::copy_shared_pointer(src.curve_offsets, src.runtime->curve_offsets_sharing_info, &dst.curve_offsets, @@ -143,6 +149,11 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src) std::swap(dst.curve_offsets, src.curve_offsets); + dst.vertex_group_active_index = src.vertex_group_active_index; + std::swap(dst.vertex_group_names.first, src.vertex_group_names.first); + std::swap(dst.vertex_group_names.last, src.vertex_group_names.last); + src.vertex_group_active_index = 0; + std::swap(dst.runtime, src.runtime); } @@ -165,6 +176,7 @@ CurvesGeometry::~CurvesGeometry() CustomData_free(&this->curve_data, this->curve_num); implicit_sharing::free_shared_data(&this->curve_offsets, &this->runtime->curve_offsets_sharing_info); + BLI_freelistN(&this->vertex_group_names); MEM_delete(this->runtime); this->runtime = nullptr; } @@ -1495,6 +1507,8 @@ void CurvesGeometry::blend_read(BlendDataReader &reader) this->curve_offsets); } + BLO_read_list(&reader, &this->vertex_group_names); + /* Recalculate curve type count cache that isn't saved in files. */ this->update_curve_types(); } @@ -1517,6 +1531,8 @@ void CurvesGeometry::blend_write(BlendWriter &writer, &writer, &this->curve_data, write_data.curve_layers, this->curve_num, CD_MASK_ALL, &id); BLO_write_int32_array(&writer, this->curve_num + 1, this->curve_offsets); + + BKE_defbase_blend_write(&writer, &this->vertex_group_names); } /** \} */ -- 2.30.2 From 66a2e0415901d1a5aa6cfd665dd3552be1cc6542 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 18 Apr 2023 18:16:15 +0200 Subject: [PATCH 04/24] Attribute provider for deform verts for curves --- source/blender/blenkernel/BKE_deform.h | 4 + source/blender/blenkernel/BKE_deform.hh | 119 ++++++++++++++++++ source/blender/blenkernel/CMakeLists.txt | 1 + source/blender/blenkernel/intern/deform.cc | 17 ++- .../intern/geometry_component_curves.cc | 112 ++++++++++++++++- .../intern/geometry_component_mesh.cc | 26 +++- 6 files changed, 271 insertions(+), 8 deletions(-) create mode 100644 source/blender/blenkernel/BKE_deform.hh diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 6488da1eb93..d825cfd4220 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -49,6 +49,10 @@ void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index); const struct ListBase *BKE_id_defgroup_list_get(const struct ID *id); struct ListBase *BKE_id_defgroup_list_get_mutable(struct ID *id); int BKE_id_defgroup_name_index(const struct ID *id, const char *name); +bool BKE_defgroup_listbase_name_find(const ListBase *defbase, + const char *name, + int *r_index, + struct bDeformGroup **r_group); bool BKE_id_defgroup_name_find(const struct ID *id, const char *name, int *r_index, diff --git a/source/blender/blenkernel/BKE_deform.hh b/source/blender/blenkernel/BKE_deform.hh new file mode 100644 index 00000000000..cbcd247bedf --- /dev/null +++ b/source/blender/blenkernel/BKE_deform.hh @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. */ + +#pragma once + +/** \file + * \ingroup bke + * + * Low-level deform utilities. + */ + +#include "BKE_deform.h" + +#include "BLI_index_mask.hh" +#include "BLI_index_range.hh" +#include "BLI_span.hh" +#include "BLI_task.hh" +#include "BLI_virtual_array.hh" + +#include "DNA_meshdata_types.h" + +namespace blender::bke { + +class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { + private: + MDeformVert *dverts_; + const int dvert_index_; + + public: + VArrayImpl_For_VertexWeights(MutableSpan dverts, const int dvert_index) + : VMutableArrayImpl(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index) + { + } + + VArrayImpl_For_VertexWeights(Span dverts, const int dvert_index) + : VMutableArrayImpl(dverts.size()), + dverts_(const_cast(dverts.data())), + dvert_index_(dvert_index) + { + } + + float get(const int64_t index) const override + { + if (dverts_ == nullptr) { + return 0.0f; + } + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + return weight->weight; + } + return 0.0f; + } + + void set(const int64_t index, const float value) override + { + MDeformVert &dvert = dverts_[index]; + if (value == 0.0f) { + if (MDeformWeight *weight = this->find_weight_at_index(index)) { + weight->weight = 0.0f; + } + } + else { + MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_); + weight->weight = value; + } + } + + void set_all(Span src) override + { + threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) { + for (const int64_t i : range) { + this->set(i, src[i]); + } + }); + } + + void materialize(IndexMask mask, float *dst) const override + { + if (dverts_ == nullptr) { + mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); + } + threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { + for (const int64_t i : mask.slice(range)) { + if (const MDeformWeight *weight = this->find_weight_at_index(i)) { + dst[i] = weight->weight; + } + else { + dst[i] = 0.0f; + } + } + }); + } + + void materialize_to_uninitialized(IndexMask mask, float *dst) const override + { + this->materialize(mask, dst); + } + + private: + MDeformWeight *find_weight_at_index(const int64_t index) + { + for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; + } + const MDeformWeight *find_weight_at_index(const int64_t index) const + { + for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; + } +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index e46439cccaa..26a189cb95f 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -378,6 +378,7 @@ set(SRC BKE_customdata_file.h BKE_data_transfer.h BKE_deform.h + BKE_deform.hh BKE_displist.h BKE_duplilist.h BKE_dynamicpaint.h diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index c30b7a157b1..98757a3bc81 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -516,15 +516,14 @@ int BKE_id_defgroup_name_index(const ID *id, const char *name) return index; } -bool BKE_id_defgroup_name_find(const ID *id, - const char *name, - int *r_index, - bDeformGroup **r_group) +bool BKE_defgroup_listbase_name_find(const ListBase *defbase, + const char *name, + int *r_index, + bDeformGroup **r_group) { if (name == nullptr || name[0] == '\0') { return false; } - const ListBase *defbase = BKE_id_defgroup_list_get(id); int index; LISTBASE_FOREACH_INDEX (bDeformGroup *, group, defbase, index) { if (STREQ(name, group->name)) { @@ -540,6 +539,14 @@ bool BKE_id_defgroup_name_find(const ID *id, return false; } +bool BKE_id_defgroup_name_find(const ID *id, + const char *name, + int *r_index, + bDeformGroup **r_group) +{ + return BKE_defgroup_listbase_name_find(BKE_id_defgroup_list_get(id), name, r_index, r_group); +} + const ListBase *BKE_object_defgroup_list(const Object *ob) { BLI_assert(BKE_object_supports_vertex_groups(ob)); diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index ddf0118fac1..98b091f4546 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -10,6 +10,7 @@ #include "BKE_attribute_math.hh" #include "BKE_curve.h" #include "BKE_curves.hh" +#include "BKE_deform.hh" #include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" @@ -331,6 +332,114 @@ static void tag_component_normals_changed(void *owner) /** \name Attribute Provider Declaration * \{ */ +/** + * This provider makes vertex groups available as float attributes. + */ +class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvider { + public: + GAttributeReader try_get_for_read(const void *owner, + const AttributeIDRef &attribute_id) const final + { + if (attribute_id.is_anonymous()) { + return {}; + } + const CurvesGeometry *curves = static_cast(owner); + if (curves == nullptr) { + return {}; + } + const std::string name = attribute_id.name(); + const int vertex_group_index = BLI_findstringindex( + &curves->vertex_group_names, name.c_str(), offsetof(bDeformGroup, name)); + if (vertex_group_index < 0) { + return {}; + } + const Span dverts = curves->deform_verts(); + if (dverts.is_empty()) { + static const float default_value = 0.0f; + return {VArray::ForSingle(default_value, curves->points_num()), ATTR_DOMAIN_POINT}; + } + return {VArray::For(dverts, vertex_group_index), + ATTR_DOMAIN_POINT}; + } + + GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final + { + if (attribute_id.is_anonymous()) { + return {}; + } + CurvesGeometry *curves = static_cast(owner); + if (curves == nullptr) { + return {}; + } + const std::string name = attribute_id.name(); + const int vertex_group_index = BLI_findstringindex( + &curves->vertex_group_names, name.c_str(), offsetof(bDeformGroup, name)); + if (vertex_group_index < 0) { + return {}; + } + MutableSpan dverts = curves->deform_verts_for_write(); + return {VMutableArray::For(dverts, vertex_group_index), + ATTR_DOMAIN_POINT}; + } + + bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final + { + if (attribute_id.is_anonymous()) { + return false; + } + CurvesGeometry *curves = static_cast(owner); + if (curves == nullptr) { + return true; + } + const std::string name = attribute_id.name(); + + int index; + bDeformGroup *group; + if (!BKE_defgroup_listbase_name_find( + &curves->vertex_group_names, name.c_str(), &index, &group)) { + return false; + } + BLI_remlink(&curves->vertex_group_names, group); + MEM_freeN(group); + if (curves->deform_verts().is_empty()) { + return true; + } + + MutableSpan dverts = curves->deform_verts_for_write(); + threading::parallel_for(dverts.index_range(), 1024, [&](IndexRange range) { + for (MDeformVert &dvert : dverts.slice(range)) { + MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); + BKE_defvert_remove_group(&dvert, weight); + for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { + if (weight.def_nr > index) { + weight.def_nr--; + } + } + } + }); + return true; + } + + bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final + { + const CurvesGeometry *curves = static_cast(owner); + if (curves == nullptr) { + return true; + } + LISTBASE_FOREACH (const bDeformGroup *, group, &curves->vertex_group_names) { + if (!callback(group->name, {ATTR_DOMAIN_POINT, CD_PROP_FLOAT})) { + return false; + } + } + return true; + } + + void foreach_domain(const FunctionRef callback) const final + { + callback(ATTR_DOMAIN_POINT); + } +}; + /** * In this function all the attribute providers for a curves component are created. * Most data in this function is statically allocated, because it does not change over time. @@ -538,6 +647,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() curve_access, tag_component_topology_changed); + static CurvesVertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider curve_custom_data(ATTR_DOMAIN_CURVE, curve_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); @@ -556,7 +666,7 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() &curve_type, &resolution, &cyclic}, - {&curve_custom_data, &point_custom_data}); + {&vertex_groups, &curve_custom_data, &point_custom_data}); } /** \} */ diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index a0205ce43c3..da978742cd7 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -10,7 +10,7 @@ #include "DNA_object_types.h" #include "BKE_attribute_math.hh" -#include "BKE_deform.h" +#include "BKE_deform.hh" #include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" @@ -951,10 +951,20 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { } }; +static float get_crease(const float &crease) +{ + return crease; +} + +static void set_crease(float &crease, const float value) +{ + crease = std::clamp(value, 0.0f, 1.0f); +} + /** * This provider makes vertex groups available as float attributes. */ -class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { +class MeshVertexGroupsAttributeProvider final : public DynamicAttributesProvider { public: GAttributeReader try_get_for_read(const void *owner, const AttributeIDRef &attribute_id) const final @@ -1191,6 +1201,18 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() edge_access, nullptr); + static BuiltinCustomDataLayerProvider crease( + "crease", + ATTR_DOMAIN_EDGE, + CD_PROP_FLOAT, + CD_CREASE, + BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Deletable, + edge_access, + make_array_read_attribute, + make_derived_write_attribute, + nullptr); + static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); -- 2.30.2 From dc3d2d2eb8621468fd286e0d81fd16431e3e6e99 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 8 Aug 2023 15:44:28 +0200 Subject: [PATCH 05/24] Fix rebase issues --- source/blender/blenkernel/BKE_deform.hh | 14 +-- .../intern/geometry_component_mesh.cc | 117 +----------------- 2 files changed, 8 insertions(+), 123 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.hh b/source/blender/blenkernel/BKE_deform.hh index cbcd247bedf..8bccfb56e3d 100644 --- a/source/blender/blenkernel/BKE_deform.hh +++ b/source/blender/blenkernel/BKE_deform.hh @@ -73,24 +73,24 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { }); } - void materialize(IndexMask mask, float *dst) const override + void materialize(const IndexMask &mask, float *dst) const override { if (dverts_ == nullptr) { mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); } threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { - for (const int64_t i : mask.slice(range)) { - if (const MDeformWeight *weight = this->find_weight_at_index(i)) { - dst[i] = weight->weight; + mask.slice(range).foreach_index_optimized([&](const int64_t index) { + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + dst[index] = weight->weight; } else { - dst[i] = 0.0f; + dst[index] = 0.0f; } - } + }); }); } - void materialize_to_uninitialized(IndexMask mask, float *dst) const override + void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override { this->materialize(mask, dst); } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index da978742cd7..87825b6bff5 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -858,109 +858,6 @@ static void tag_component_positions_changed(void *owner) } } -class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { - private: - MDeformVert *dverts_; - const int dvert_index_; - - public: - VArrayImpl_For_VertexWeights(MutableSpan dverts, const int dvert_index) - : VMutableArrayImpl(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index) - { - } - - VArrayImpl_For_VertexWeights(Span dverts, const int dvert_index) - : VMutableArrayImpl(dverts.size()), - dverts_(const_cast(dverts.data())), - dvert_index_(dvert_index) - { - } - - float get(const int64_t index) const override - { - if (dverts_ == nullptr) { - return 0.0f; - } - if (const MDeformWeight *weight = this->find_weight_at_index(index)) { - return weight->weight; - } - return 0.0f; - } - - void set(const int64_t index, const float value) override - { - MDeformVert &dvert = dverts_[index]; - if (value == 0.0f) { - if (MDeformWeight *weight = this->find_weight_at_index(index)) { - weight->weight = 0.0f; - } - } - else { - MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_); - weight->weight = value; - } - } - - void set_all(Span src) override - { - threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) { - for (const int64_t i : range) { - this->set(i, src[i]); - } - }); - } - - void materialize(const IndexMask &mask, float *dst) const override - { - if (dverts_ == nullptr) { - mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); - } - mask.foreach_index(GrainSize(4096), [&](const int64_t i) { - if (const MDeformWeight *weight = this->find_weight_at_index(i)) { - dst[i] = weight->weight; - } - else { - dst[i] = 0.0f; - } - }); - } - - void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override - { - this->materialize(mask, dst); - } - - private: - MDeformWeight *find_weight_at_index(const int64_t index) - { - for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) { - if (weight.def_nr == dvert_index_) { - return &weight; - } - } - return nullptr; - } - const MDeformWeight *find_weight_at_index(const int64_t index) const - { - for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) { - if (weight.def_nr == dvert_index_) { - return &weight; - } - } - return nullptr; - } -}; - -static float get_crease(const float &crease) -{ - return crease; -} - -static void set_crease(float &crease, const float value) -{ - crease = std::clamp(value, 0.0f, 1.0f); -} - /** * This provider makes vertex groups available as float attributes. */ @@ -1201,19 +1098,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() edge_access, nullptr); - static BuiltinCustomDataLayerProvider crease( - "crease", - ATTR_DOMAIN_EDGE, - CD_PROP_FLOAT, - CD_CREASE, - BuiltinAttributeProvider::Creatable, - BuiltinAttributeProvider::Deletable, - edge_access, - make_array_read_attribute, - make_derived_write_attribute, - nullptr); - - static VertexGroupsAttributeProvider vertex_groups; + static MeshVertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); static CustomDataAttributeProvider edge_custom_data(ATTR_DOMAIN_EDGE, edge_access); -- 2.30.2 From 1328468881416b08147a4da8c699418279080f72 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 8 Aug 2023 15:45:52 +0200 Subject: [PATCH 06/24] Make Curves object support vertex groups --- source/blender/blenkernel/intern/deform.cc | 14 +++++++++++++- source/blender/makesdna/DNA_object_types.h | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 98757a3bc81..890f6a1fe6f 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -14,6 +14,7 @@ #include "MEM_guardedalloc.h" +#include "DNA_curves_types.h" #include "DNA_gpencil_legacy_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -440,7 +441,7 @@ bool BKE_id_supports_vertex_groups(const ID *id) if (id == nullptr) { return false; } - return ELEM(GS(id->name), ID_ME, ID_LT, ID_GD_LEGACY); + return ELEM(GS(id->name), ID_ME, ID_LT, ID_GD_LEGACY, ID_CV); } bool BKE_object_supports_vertex_groups(const Object *ob) @@ -465,6 +466,10 @@ const ListBase *BKE_id_defgroup_list_get(const ID *id) const bGPdata *gpd = (const bGPdata *)id; return &gpd->vertex_group_names; } + case ID_CV: { + const Curves *curves_id = reinterpret_cast(id); + return &curves_id->geometry.vertex_group_names; + } default: { BLI_assert_unreachable(); } @@ -488,6 +493,13 @@ static const int *object_defgroup_active_index_get_p(const Object *ob) const bGPdata *gpd = (const bGPdata *)ob->data; return &gpd->vertex_group_active_index; } + case OB_CURVES: { + const Curves *curves_id = static_cast(ob->data); + return &curves_id->geometry.vertex_group_active_index; + } + default: { + BLI_assert_unreachable(); + } } return nullptr; } diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 6e89c77dd7b..9ccddabde7d 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -599,7 +599,8 @@ typedef enum ObjectType { OB_POINTCLOUD, \ OB_VOLUME, \ OB_GREASE_PENCIL)) -#define OB_TYPE_SUPPORT_VGROUP(_type) (ELEM(_type, OB_MESH, OB_LATTICE, OB_GPENCIL_LEGACY)) +#define OB_TYPE_SUPPORT_VGROUP(_type) \ + (ELEM(_type, OB_MESH, OB_LATTICE, OB_GPENCIL_LEGACY, OB_CURVES)) #define OB_TYPE_SUPPORT_EDITMODE(_type) \ (ELEM(_type, \ OB_MESH, \ -- 2.30.2 From 764c1e955e5679d5d9d9db1b284c28b31f2a23ac Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 8 Aug 2023 15:46:43 +0200 Subject: [PATCH 07/24] Add vertex groups to Curves object data properties --- .../startup/bl_ui/properties_data_curves.py | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/scripts/startup/bl_ui/properties_data_curves.py b/scripts/startup/bl_ui/properties_data_curves.py index aa86b1c8d7e..c69eb8ad955 100644 --- a/scripts/startup/bl_ui/properties_data_curves.py +++ b/scripts/startup/bl_ui/properties_data_curves.py @@ -157,6 +157,71 @@ class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): col.operator("geometry.attribute_remove", icon='REMOVE', text="") +class DATA_PT_curves_vertex_groups(DataButtonsPanel, Panel): + bl_label = "Vertex Groups" + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} + + def draw(self, context): + layout = self.layout + + ob = context.object + group = ob.vertex_groups.active + + rows = 3 + if group: + rows = 5 + + row = layout.row() + row.template_list("CURVES_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows) + + col = row.column(align=True) + + col.operator("object.vertex_group_add", icon='ADD', text="") + props = col.operator("object.vertex_group_remove", icon='REMOVE', text="") + props.all_unlocked = props.all = False + + col.separator() + + if group: + col.separator() + col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + + if ( + ob.vertex_groups and + (ob.mode == 'EDIT' or + (ob.mode == 'WEIGHT_PAINT' and ob.type == 'CURVES' and ob.data.use_paint_mask_vertex)) + ): + row = layout.row() + + sub = row.row(align=True) + sub.operator("object.vertex_group_assign", text="Assign") + sub.operator("object.vertex_group_remove_from", text="Remove") + + sub = row.row(align=True) + sub.operator("object.vertex_group_select", text="Select") + sub.operator("object.vertex_group_deselect", text="Deselect") + + layout.prop(context.tool_settings, "vertex_group_weight", text="Weight") + + +class CURVES_UL_vgroups(UIList): + def draw_item(self, _context, layout, _data, item, icon, _active_data_, _active_propname, _index): + vgroup = item + if self.layout_type in {'DEFAULT', 'COMPACT'}: + layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon) + icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED' + layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False) + elif self.layout_type == 'GRID': + layout.alignment = 'CENTER' + layout.label(text="", icon_value=icon) + + class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = { 'BLENDER_RENDER', @@ -172,8 +237,10 @@ classes = ( DATA_PT_CURVES_attributes, DATA_PT_curves_surface, DATA_PT_custom_props_curves, + DATA_PT_curves_vertex_groups, CURVES_MT_add_attribute, CURVES_UL_attributes, + CURVES_UL_vgroups, ) if __name__ == "__main__": # only for live edit. -- 2.30.2 From 3deeeb6633aa031c8f6edd04a3ce11330e6f6263 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 8 Aug 2023 15:47:03 +0200 Subject: [PATCH 08/24] Fix crash in attributes API --- source/blender/blenkernel/intern/curves_geometry.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index c98455208cb..3978495ba32 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -61,6 +61,10 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num) CustomData_reset(&this->point_data); CustomData_reset(&this->curve_data); + /* Make sure to clear this before using the attributes API. Otherwise the vertex group accessor + * might try to read from invalid memory. */ + BLI_listbase_clear(&this->vertex_group_names); + this->attributes_for_write().add( "position", ATTR_DOMAIN_POINT, AttributeInitConstruct()); @@ -82,8 +86,6 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num) this->curve_offsets = nullptr; } - BLI_listbase_clear(&this->vertex_group_names); - /* Fill the type counts with the default so they're in a valid state. */ this->runtime->type_counts[CURVE_TYPE_CATMULL_ROM] = curve_num; } -- 2.30.2 From 1617379a68637e17e213282e6c6519d317cb5af4 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 8 Aug 2023 15:47:41 +0200 Subject: [PATCH 09/24] Implement vertex group operators for Curves --- .../blenkernel/intern/object_deform.cc | 78 +++++++++++++++++-- .../blender/editors/object/object_vgroup.cc | 64 +++++++++++++++ 2 files changed, 134 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/object_deform.cc b/source/blender/blenkernel/intern/object_deform.cc index a0d5f3ee090..b201fa01b41 100644 --- a/source/blender/blenkernel/intern/object_deform.cc +++ b/source/blender/blenkernel/intern/object_deform.cc @@ -32,6 +32,7 @@ #include "DNA_scene_types.h" #include "BKE_action.h" +#include "BKE_curves.hh" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_gpencil_legacy.h" @@ -111,14 +112,22 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob) MDeformVert *BKE_object_defgroup_data_create(ID *id) { - if (GS(id->name) == ID_ME) { - return BKE_mesh_deform_verts_for_write((Mesh *)id); - } - if (GS(id->name) == ID_LT) { - Lattice *lt = (Lattice *)id; - lt->dvert = static_cast(MEM_callocN( - sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert")); - return lt->dvert; + switch (GS(id->name)) { + case ID_ME: { + return BKE_mesh_deform_verts_for_write((Mesh *)id); + } + case ID_LT: { + Lattice *lt = (Lattice *)id; + lt->dvert = static_cast(MEM_callocN( + sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert")); + return lt->dvert; + } + case ID_CV: { + Curves *curves_id = reinterpret_cast(id); + return curves_id->geometry.wrap().deform_verts_for_write().data(); + } + default: + BLI_assert_unreachable(); } return nullptr; @@ -197,6 +206,25 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele } } } + else if (ob->type == OB_CURVES) { + using namespace blender; + Curves *curves_id = static_cast(ob->data); + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + const Span dverts = curves.deform_verts(); + if (!dverts.is_empty()) { + const VArray selection = *curves.attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, true); + + MutableSpan dverts = curves.deform_verts_for_write(); + for (const int64_t index : curves.points_range()) { + if (&dverts[index] && (!use_selection || selection[index])) { + MDeformWeight *dw = BKE_defvert_find_index(&dverts[index], def_nr); + BKE_defvert_remove_group(&dverts[index], dw); /* dw can be nullptr */ + changed = true; + } + } + } + } return changed; } @@ -264,6 +292,11 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); MEM_SAFE_FREE(lt->dvert); } + else if (ob->type == OB_CURVES) { + Curves *curves_id = static_cast(ob->data); + CustomData_free_layer_active( + &curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num); + } } else if (BKE_object_defgroup_active_index_get(ob) < 1) { /* Keep a valid active index if we still have some vgroups. */ @@ -357,6 +390,25 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg) } } } + else if (ob->type == OB_CURVES) { + using namespace blender; + Curves *curves_id = static_cast(ob->data); + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + + MutableSpan dverts = curves.deform_verts_for_write(); + threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { + for (const int64_t index : range) { + MDeformVert *dvert = &dverts[index]; + if (dvert) { + for (int64_t i = 0; i < dvert->totweight; i++) { + if (dvert->dw[i].def_nr > def_nr) { + dvert->dw[i].def_nr--; + } + } + } + } + }); + } object_defgroup_remove_common(ob, dg, def_nr); } @@ -411,6 +463,11 @@ void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked) Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); MEM_SAFE_FREE(lt->dvert); } + else if (ob->type == OB_CURVES) { + Curves *curves_id = static_cast(ob->data); + CustomData_free_layer_active( + &curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num); + } /* Fix counters/indices */ BKE_object_defgroup_active_index_set(ob, 0); } @@ -506,6 +563,11 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw; return true; } + case ID_CV: { + Curves *curves_id = reinterpret_cast(id); + *dvert_arr = const_cast(curves_id->geometry.wrap().deform_verts().data()); + *dvert_tot = curves_id->geometry.point_num; + } default: break; } diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 55c1675d7dc..f7513eddcaa 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -33,6 +33,7 @@ #include "BKE_attribute.hh" #include "BKE_context.h" +#include "BKE_curves.hh" #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" @@ -60,6 +61,7 @@ #include "WM_api.hh" #include "WM_types.hh" +#include "ED_curves.hh" #include "ED_mesh.hh" #include "ED_object.hh" #include "ED_screen.hh" @@ -254,7 +256,34 @@ bool ED_vgroup_parray_alloc(ID *id, } return false; } + case ID_CV: { + Curves *curves_id = reinterpret_cast(id); + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + if (!curves.deform_verts().is_empty()) { + MutableSpan dverts = curves.deform_verts_for_write(); + *dvert_tot = curves.points_num(); + *dvert_arr = static_cast( + MEM_mallocN(sizeof(void *) * curves.points_num(), __func__)); + + if (use_vert_sel) { + const VArray selection = *curves.attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, true); + + for (int64_t i = 0; i < curves.points_num(); i++) { + (*dvert_arr)[i] = selection[i] ? &dverts[i] : nullptr; + } + } + else { + for (int64_t i = 0; i < curves.points_num(); i++) { + (*dvert_arr)[i] = &dverts[i]; + } + } + + return true; + } + return false; + } default: break; } @@ -1106,6 +1135,24 @@ static void vgroup_select_verts(Object *ob, int select) } } } + else if (ob->type == OB_CURVES) { + Curves *curves_id = static_cast(ob->data); + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + const Span dverts = curves.deform_verts(); + if (!dverts.is_empty()) { + bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute( + curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL); + MutableSpan selection_typed = selection.span.typed(); + threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { + for (const int64_t index : range) { + if (BKE_defvert_find_index(&dverts[index], def_nr)) { + selection_typed[index] = bool(select); + } + } + }); + selection.finish(); + } + } } static void vgroup_duplicate(Object *ob) @@ -2308,6 +2355,23 @@ static void vgroup_assign_verts(Object *ob, const float weight) } } } + else if (ob->type == OB_CURVES) { + Curves *curves_id = static_cast(ob->data); + bke::CurvesGeometry &curves = curves_id->geometry.wrap(); + const VArray selection = *curves.attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, true); + + MutableSpan dverts = curves.deform_verts_for_write(); + threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { + for (const int64_t index : range) { + if (selection[index]) { + if (MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[index], def_nr)) { + dw->weight = weight; + } + } + } + }); + } } /** \} */ -- 2.30.2 From 47e48795b1617a56d2f0058d1543bd60206b6af9 Mon Sep 17 00:00:00 2001 From: Falk David Date: Thu, 14 Sep 2023 10:01:22 +0200 Subject: [PATCH 10/24] Revert change to `BKE_id_supports_vertex_groups` --- source/blender/blenkernel/intern/deform.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 890f6a1fe6f..778da359b19 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -441,7 +441,7 @@ bool BKE_id_supports_vertex_groups(const ID *id) if (id == nullptr) { return false; } - return ELEM(GS(id->name), ID_ME, ID_LT, ID_GD_LEGACY, ID_CV); + return ELEM(GS(id->name), ID_ME, ID_LT, ID_GD_LEGACY); } bool BKE_object_supports_vertex_groups(const Object *ob) -- 2.30.2 From 78d830d0dd0041c28849492e6617e39ce45354fd Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 18 Sep 2023 11:55:19 +0200 Subject: [PATCH 11/24] Move `VArrayImpl_For_VertexWeights` out of header --- source/blender/blenkernel/BKE_deform.h | 4 + source/blender/blenkernel/BKE_deform.hh | 119 ------------------ source/blender/blenkernel/CMakeLists.txt | 1 - source/blender/blenkernel/intern/deform.cc | 114 +++++++++++++++++ .../intern/geometry_component_curves.cc | 8 +- .../intern/geometry_component_mesh.cc | 8 +- 6 files changed, 124 insertions(+), 130 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_deform.hh diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index d825cfd4220..215b43f4361 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -296,6 +296,10 @@ void BKE_defvert_extract_vgroup_to_faceweights(const struct MDeformVert *dvert, bool invert_vgroup, float *r_weights); +namespace blender::bke { +VArray varray_for_deform_verts(Span dverts, const int dvert_index); +VMutableArray varray_for_deform_verts(MutableSpan dverts, int dvert_index); +} // namespace blender::bke #endif void BKE_defvert_weight_to_rgb(float r_rgb[3], float weight); diff --git a/source/blender/blenkernel/BKE_deform.hh b/source/blender/blenkernel/BKE_deform.hh deleted file mode 100644 index 8bccfb56e3d..00000000000 --- a/source/blender/blenkernel/BKE_deform.hh +++ /dev/null @@ -1,119 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2023 Blender Foundation. */ - -#pragma once - -/** \file - * \ingroup bke - * - * Low-level deform utilities. - */ - -#include "BKE_deform.h" - -#include "BLI_index_mask.hh" -#include "BLI_index_range.hh" -#include "BLI_span.hh" -#include "BLI_task.hh" -#include "BLI_virtual_array.hh" - -#include "DNA_meshdata_types.h" - -namespace blender::bke { - -class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { - private: - MDeformVert *dverts_; - const int dvert_index_; - - public: - VArrayImpl_For_VertexWeights(MutableSpan dverts, const int dvert_index) - : VMutableArrayImpl(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index) - { - } - - VArrayImpl_For_VertexWeights(Span dverts, const int dvert_index) - : VMutableArrayImpl(dverts.size()), - dverts_(const_cast(dverts.data())), - dvert_index_(dvert_index) - { - } - - float get(const int64_t index) const override - { - if (dverts_ == nullptr) { - return 0.0f; - } - if (const MDeformWeight *weight = this->find_weight_at_index(index)) { - return weight->weight; - } - return 0.0f; - } - - void set(const int64_t index, const float value) override - { - MDeformVert &dvert = dverts_[index]; - if (value == 0.0f) { - if (MDeformWeight *weight = this->find_weight_at_index(index)) { - weight->weight = 0.0f; - } - } - else { - MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_); - weight->weight = value; - } - } - - void set_all(Span src) override - { - threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) { - for (const int64_t i : range) { - this->set(i, src[i]); - } - }); - } - - void materialize(const IndexMask &mask, float *dst) const override - { - if (dverts_ == nullptr) { - mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); - } - threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { - mask.slice(range).foreach_index_optimized([&](const int64_t index) { - if (const MDeformWeight *weight = this->find_weight_at_index(index)) { - dst[index] = weight->weight; - } - else { - dst[index] = 0.0f; - } - }); - }); - } - - void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override - { - this->materialize(mask, dst); - } - - private: - MDeformWeight *find_weight_at_index(const int64_t index) - { - for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) { - if (weight.def_nr == dvert_index_) { - return &weight; - } - } - return nullptr; - } - const MDeformWeight *find_weight_at_index(const int64_t index) const - { - for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) { - if (weight.def_nr == dvert_index_) { - return &weight; - } - } - return nullptr; - } -}; - -} // namespace blender::bke diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 26a189cb95f..e46439cccaa 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -378,7 +378,6 @@ set(SRC BKE_customdata_file.h BKE_data_transfer.h BKE_deform.h - BKE_deform.hh BKE_displist.h BKE_duplilist.h BKE_dynamicpaint.h diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 778da359b19..4b596204b3b 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1664,3 +1664,117 @@ void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdv } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Virtual array implementation for vertex groups. + * \{ */ + +namespace blender::bke { + +class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { + private: + MDeformVert *dverts_; + const int dvert_index_; + + public: + VArrayImpl_For_VertexWeights(MutableSpan dverts, const int dvert_index) + : VMutableArrayImpl(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index) + { + } + + VArrayImpl_For_VertexWeights(Span dverts, const int dvert_index) + : VMutableArrayImpl(dverts.size()), + dverts_(const_cast(dverts.data())), + dvert_index_(dvert_index) + { + } + + float get(const int64_t index) const override + { + if (dverts_ == nullptr) { + return 0.0f; + } + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + return weight->weight; + } + return 0.0f; + } + + void set(const int64_t index, const float value) override + { + MDeformVert &dvert = dverts_[index]; + if (value == 0.0f) { + if (MDeformWeight *weight = this->find_weight_at_index(index)) { + weight->weight = 0.0f; + } + } + else { + MDeformWeight *weight = BKE_defvert_ensure_index(&dvert, dvert_index_); + weight->weight = value; + } + } + + void set_all(Span src) override + { + threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) { + for (const int64_t i : range) { + this->set(i, src[i]); + } + }); + } + + void materialize(const IndexMask &mask, float *dst) const override + { + if (dverts_ == nullptr) { + mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); + } + threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { + mask.slice(range).foreach_index_optimized([&](const int64_t index) { + if (const MDeformWeight *weight = this->find_weight_at_index(index)) { + dst[index] = weight->weight; + } + else { + dst[index] = 0.0f; + } + }); + }); + } + + void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override + { + this->materialize(mask, dst); + } + + private: + MDeformWeight *find_weight_at_index(const int64_t index) + { + for (MDeformWeight &weight : MutableSpan(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; + } + const MDeformWeight *find_weight_at_index(const int64_t index) const + { + for (const MDeformWeight &weight : Span(dverts_[index].dw, dverts_[index].totweight)) { + if (weight.def_nr == dvert_index_) { + return &weight; + } + } + return nullptr; + } +}; + +VArray varray_for_deform_verts(Span dverts, const int dvert_index) +{ + return VArray::For(dverts, dvert_index); +} +VMutableArray varray_for_deform_verts(MutableSpan dverts, const int dvert_index) +{ + return VMutableArray::For(dverts, dvert_index); +} + +} // namespace blender::bke + +/** \} */ diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 98b091f4546..d5b393b713b 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -10,7 +10,7 @@ #include "BKE_attribute_math.hh" #include "BKE_curve.h" #include "BKE_curves.hh" -#include "BKE_deform.hh" +#include "BKE_deform.h" #include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" @@ -358,8 +358,7 @@ class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvid static const float default_value = 0.0f; return {VArray::ForSingle(default_value, curves->points_num()), ATTR_DOMAIN_POINT}; } - return {VArray::For(dverts, vertex_group_index), - ATTR_DOMAIN_POINT}; + return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final @@ -378,8 +377,7 @@ class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvid return {}; } MutableSpan dverts = curves->deform_verts_for_write(); - return {VMutableArray::For(dverts, vertex_group_index), - ATTR_DOMAIN_POINT}; + return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 87825b6bff5..ea057481e2f 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -10,7 +10,7 @@ #include "DNA_object_types.h" #include "BKE_attribute_math.hh" -#include "BKE_deform.hh" +#include "BKE_deform.h" #include "BKE_geometry_fields.hh" #include "BKE_geometry_set.hh" #include "BKE_lib_id.h" @@ -884,8 +884,7 @@ class MeshVertexGroupsAttributeProvider final : public DynamicAttributesProvider static const float default_value = 0.0f; return {VArray::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT}; } - return {VArray::For(dverts, vertex_group_index), - ATTR_DOMAIN_POINT}; + return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final @@ -905,8 +904,7 @@ class MeshVertexGroupsAttributeProvider final : public DynamicAttributesProvider return {}; } MutableSpan dverts = mesh->deform_verts_for_write(); - return {VMutableArray::For(dverts, vertex_group_index), - ATTR_DOMAIN_POINT}; + return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final -- 2.30.2 From 832ca4bc057c0f85bee588b936eb3de193c3f6b7 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 18 Sep 2023 13:06:54 +0200 Subject: [PATCH 12/24] Swap vertex_group_active_index --- source/blender/blenkernel/intern/curves_geometry.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 3978495ba32..1067269e28e 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -151,9 +151,9 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src) std::swap(dst.curve_offsets, src.curve_offsets); - dst.vertex_group_active_index = src.vertex_group_active_index; std::swap(dst.vertex_group_names.first, src.vertex_group_names.first); std::swap(dst.vertex_group_names.last, src.vertex_group_names.last); + std::swap(dst.vertex_group_active_index, src.vertex_group_active_index); src.vertex_group_active_index = 0; std::swap(dst.runtime, src.runtime); -- 2.30.2 From ed12d73cd8059e8b8cd265ea9307589af0634f52 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 18 Sep 2023 13:07:34 +0200 Subject: [PATCH 13/24] Remove comment --- source/blender/blenkernel/intern/curves_geometry.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 1067269e28e..bd3fe7dcdf4 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -60,9 +60,6 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num) this->curve_num = curve_num; CustomData_reset(&this->point_data); CustomData_reset(&this->curve_data); - - /* Make sure to clear this before using the attributes API. Otherwise the vertex group accessor - * might try to read from invalid memory. */ BLI_listbase_clear(&this->vertex_group_names); this->attributes_for_write().add( -- 2.30.2 From 5dbde50c16128beec553010db1d1bc4fc0376091 Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 18 Sep 2023 13:09:39 +0200 Subject: [PATCH 14/24] Revert the UI changes --- .../startup/bl_ui/properties_data_curves.py | 67 ------------------- 1 file changed, 67 deletions(-) diff --git a/scripts/startup/bl_ui/properties_data_curves.py b/scripts/startup/bl_ui/properties_data_curves.py index c69eb8ad955..aa86b1c8d7e 100644 --- a/scripts/startup/bl_ui/properties_data_curves.py +++ b/scripts/startup/bl_ui/properties_data_curves.py @@ -157,71 +157,6 @@ class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): col.operator("geometry.attribute_remove", icon='REMOVE', text="") -class DATA_PT_curves_vertex_groups(DataButtonsPanel, Panel): - bl_label = "Vertex Groups" - COMPAT_ENGINES = { - 'BLENDER_RENDER', - 'BLENDER_EEVEE', - 'BLENDER_EEVEE_NEXT', - 'BLENDER_WORKBENCH', - 'BLENDER_WORKBENCH_NEXT'} - - def draw(self, context): - layout = self.layout - - ob = context.object - group = ob.vertex_groups.active - - rows = 3 - if group: - rows = 5 - - row = layout.row() - row.template_list("CURVES_UL_vgroups", "", ob, "vertex_groups", ob.vertex_groups, "active_index", rows=rows) - - col = row.column(align=True) - - col.operator("object.vertex_group_add", icon='ADD', text="") - props = col.operator("object.vertex_group_remove", icon='REMOVE', text="") - props.all_unlocked = props.all = False - - col.separator() - - if group: - col.separator() - col.operator("object.vertex_group_move", icon='TRIA_UP', text="").direction = 'UP' - col.operator("object.vertex_group_move", icon='TRIA_DOWN', text="").direction = 'DOWN' - - if ( - ob.vertex_groups and - (ob.mode == 'EDIT' or - (ob.mode == 'WEIGHT_PAINT' and ob.type == 'CURVES' and ob.data.use_paint_mask_vertex)) - ): - row = layout.row() - - sub = row.row(align=True) - sub.operator("object.vertex_group_assign", text="Assign") - sub.operator("object.vertex_group_remove_from", text="Remove") - - sub = row.row(align=True) - sub.operator("object.vertex_group_select", text="Select") - sub.operator("object.vertex_group_deselect", text="Deselect") - - layout.prop(context.tool_settings, "vertex_group_weight", text="Weight") - - -class CURVES_UL_vgroups(UIList): - def draw_item(self, _context, layout, _data, item, icon, _active_data_, _active_propname, _index): - vgroup = item - if self.layout_type in {'DEFAULT', 'COMPACT'}: - layout.prop(vgroup, "name", text="", emboss=False, icon_value=icon) - icon = 'LOCKED' if vgroup.lock_weight else 'UNLOCKED' - layout.prop(vgroup, "lock_weight", text="", icon=icon, emboss=False) - elif self.layout_type == 'GRID': - layout.alignment = 'CENTER' - layout.label(text="", icon_value=icon) - - class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = { 'BLENDER_RENDER', @@ -237,10 +172,8 @@ classes = ( DATA_PT_CURVES_attributes, DATA_PT_curves_surface, DATA_PT_custom_props_curves, - DATA_PT_curves_vertex_groups, CURVES_MT_add_attribute, CURVES_UL_attributes, - CURVES_UL_vgroups, ) if __name__ == "__main__": # only for live edit. -- 2.30.2 From aa4f47d2bf0619bf51bef54252e8ed3500c9d5ab Mon Sep 17 00:00:00 2001 From: Falk David Date: Mon, 18 Sep 2023 13:20:14 +0200 Subject: [PATCH 15/24] Fix compiler errors --- source/blender/blenkernel/BKE_deform.h | 4 +++- source/blender/blenkernel/intern/deform.cc | 2 +- source/blender/blenkernel/intern/geometry_component_curves.cc | 2 +- source/blender/blenkernel/intern/geometry_component_mesh.cc | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 215b43f4361..a71d980a49b 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -7,6 +7,7 @@ #ifdef __cplusplus # include "BLI_math_vector_types.hh" # include "BLI_offset_indices.hh" +# include "BLI_virtual_array.hh" #endif #ifdef __cplusplus @@ -298,7 +299,8 @@ void BKE_defvert_extract_vgroup_to_faceweights(const struct MDeformVert *dvert, namespace blender::bke { VArray varray_for_deform_verts(Span dverts, const int dvert_index); -VMutableArray varray_for_deform_verts(MutableSpan dverts, int dvert_index); +VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, + int dvert_index); } // namespace blender::bke #endif diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 4b596204b3b..0af9494b7ba 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1770,7 +1770,7 @@ VArray varray_for_deform_verts(Span dverts, const int dvert_ { return VArray::For(dverts, dvert_index); } -VMutableArray varray_for_deform_verts(MutableSpan dverts, const int dvert_index) +VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, const int dvert_index) { return VMutableArray::For(dverts, dvert_index); } diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index d5b393b713b..063f7445e2c 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -377,7 +377,7 @@ class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvid return {}; } MutableSpan dverts = curves->deform_verts_for_write(); - return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; + return {bke::varray_for_mutable_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index ea057481e2f..2ec9f966851 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -904,7 +904,7 @@ class MeshVertexGroupsAttributeProvider final : public DynamicAttributesProvider return {}; } MutableSpan dverts = mesh->deform_verts_for_write(); - return {bke::varray_for_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; + return {bke::varray_for_mutable_deform_verts(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final -- 2.30.2 From 1566bd2888313b079851c509d690363e672d7099 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 10:54:27 +0200 Subject: [PATCH 16/24] Fix casting --- source/blender/blenkernel/intern/curves_geometry.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index bd3fe7dcdf4..59510f2b13d 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -486,8 +486,8 @@ MutableSpan CurvesGeometry::deform_verts_for_write() if (dvert != nullptr) { return {dvert, this->point_num}; } - return {(MDeformVert *)CustomData_add_layer( - &this->point_data, CD_MDEFORMVERT, CD_SET_DEFAULT, this->point_num), + return {static_cast(CustomData_add_layer( + &this->point_data, CD_MDEFORMVERT, CD_SET_DEFAULT, this->point_num)), this->point_num}; } -- 2.30.2 From a6acbb0cdc808db956a83d36bc460dd1e627f6ad Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 10:57:18 +0200 Subject: [PATCH 17/24] Revert vertex group API for curves object --- source/blender/blenkernel/intern/deform.cc | 8 --- .../blenkernel/intern/object_deform.cc | 57 ------------------- 2 files changed, 65 deletions(-) diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 0af9494b7ba..ee5a371911d 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -466,10 +466,6 @@ const ListBase *BKE_id_defgroup_list_get(const ID *id) const bGPdata *gpd = (const bGPdata *)id; return &gpd->vertex_group_names; } - case ID_CV: { - const Curves *curves_id = reinterpret_cast(id); - return &curves_id->geometry.vertex_group_names; - } default: { BLI_assert_unreachable(); } @@ -493,10 +489,6 @@ static const int *object_defgroup_active_index_get_p(const Object *ob) const bGPdata *gpd = (const bGPdata *)ob->data; return &gpd->vertex_group_active_index; } - case OB_CURVES: { - const Curves *curves_id = static_cast(ob->data); - return &curves_id->geometry.vertex_group_active_index; - } default: { BLI_assert_unreachable(); } diff --git a/source/blender/blenkernel/intern/object_deform.cc b/source/blender/blenkernel/intern/object_deform.cc index b201fa01b41..7a1b391b650 100644 --- a/source/blender/blenkernel/intern/object_deform.cc +++ b/source/blender/blenkernel/intern/object_deform.cc @@ -122,10 +122,6 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id) sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert")); return lt->dvert; } - case ID_CV: { - Curves *curves_id = reinterpret_cast(id); - return curves_id->geometry.wrap().deform_verts_for_write().data(); - } default: BLI_assert_unreachable(); } @@ -206,25 +202,6 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele } } } - else if (ob->type == OB_CURVES) { - using namespace blender; - Curves *curves_id = static_cast(ob->data); - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - const Span dverts = curves.deform_verts(); - if (!dverts.is_empty()) { - const VArray selection = *curves.attributes().lookup_or_default( - ".selection", ATTR_DOMAIN_POINT, true); - - MutableSpan dverts = curves.deform_verts_for_write(); - for (const int64_t index : curves.points_range()) { - if (&dverts[index] && (!use_selection || selection[index])) { - MDeformWeight *dw = BKE_defvert_find_index(&dverts[index], def_nr); - BKE_defvert_remove_group(&dverts[index], dw); /* dw can be nullptr */ - changed = true; - } - } - } - } return changed; } @@ -292,11 +269,6 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); MEM_SAFE_FREE(lt->dvert); } - else if (ob->type == OB_CURVES) { - Curves *curves_id = static_cast(ob->data); - CustomData_free_layer_active( - &curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num); - } } else if (BKE_object_defgroup_active_index_get(ob) < 1) { /* Keep a valid active index if we still have some vgroups. */ @@ -390,25 +362,6 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg) } } } - else if (ob->type == OB_CURVES) { - using namespace blender; - Curves *curves_id = static_cast(ob->data); - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - - MutableSpan dverts = curves.deform_verts_for_write(); - threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { - for (const int64_t index : range) { - MDeformVert *dvert = &dverts[index]; - if (dvert) { - for (int64_t i = 0; i < dvert->totweight; i++) { - if (dvert->dw[i].def_nr > def_nr) { - dvert->dw[i].def_nr--; - } - } - } - } - }); - } object_defgroup_remove_common(ob, dg, def_nr); } @@ -463,11 +416,6 @@ void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked) Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); MEM_SAFE_FREE(lt->dvert); } - else if (ob->type == OB_CURVES) { - Curves *curves_id = static_cast(ob->data); - CustomData_free_layer_active( - &curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num); - } /* Fix counters/indices */ BKE_object_defgroup_active_index_set(ob, 0); } @@ -563,11 +511,6 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw; return true; } - case ID_CV: { - Curves *curves_id = reinterpret_cast(id); - *dvert_arr = const_cast(curves_id->geometry.wrap().deform_verts().data()); - *dvert_tot = curves_id->geometry.point_num; - } default: break; } -- 2.30.2 From a0454c26f3b6c588ccff925cd9987fdfd51be3e4 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 10:57:44 +0200 Subject: [PATCH 18/24] Fix const declaration and naming --- source/blender/blenkernel/BKE_deform.h | 4 ++-- source/blender/blenkernel/intern/deform.cc | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index a71d980a49b..ca95beaa0b6 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -298,9 +298,9 @@ void BKE_defvert_extract_vgroup_to_faceweights(const struct MDeformVert *dvert, float *r_weights); namespace blender::bke { -VArray varray_for_deform_verts(Span dverts, const int dvert_index); +VArray varray_for_deform_verts(Span dverts, int defgroup_index); VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, - int dvert_index); + int defgroup_index); } // namespace blender::bke #endif diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index ee5a371911d..e5ca85890a1 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1758,13 +1758,15 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { } }; -VArray varray_for_deform_verts(Span dverts, const int dvert_index) +VArray varray_for_deform_verts(Span dverts, const int defgroup_index) { - return VArray::For(dverts, dvert_index); + return VArray::For(dverts, defgroup_index); } -VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, const int dvert_index) +VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, + const int defgroup_index) { - return VMutableArray::For(dverts, dvert_index); + return VMutableArray::For(dverts, defgroup_index); +} } } // namespace blender::bke -- 2.30.2 From c58e8d58a232ddd4da7a2d6cfc6ec86139ee7c5e Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 10:59:37 +0200 Subject: [PATCH 19/24] Add common function to remove vertex group --- source/blender/blenkernel/BKE_deform.h | 1 + source/blender/blenkernel/intern/deform.cc | 14 ++++++++++++++ .../blenkernel/intern/geometry_component_curves.cc | 12 +----------- .../blenkernel/intern/geometry_component_mesh.cc | 12 +----------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index ca95beaa0b6..00d061388ed 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -301,6 +301,7 @@ namespace blender::bke { VArray varray_for_deform_verts(Span dverts, int defgroup_index); VMutableArray varray_for_mutable_deform_verts(MutableSpan dverts, int defgroup_index); +void remove_defgroup_index(MutableSpan dverts, int defgroup_index); } // namespace blender::bke #endif diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index e5ca85890a1..0c06f0145ec 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1767,6 +1767,20 @@ VMutableArray varray_for_mutable_deform_verts(MutableSpan dv { return VMutableArray::For(dverts, defgroup_index); } + +void remove_defgroup_index(MutableSpan dverts, const int defgroup_index) +{ + threading::parallel_for(dverts.index_range(), 1024, [&](IndexRange range) { + for (MDeformVert &dvert : dverts.slice(range)) { + MDeformWeight *weight = BKE_defvert_find_index(&dvert, defgroup_index); + BKE_defvert_remove_group(&dvert, weight); + for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { + if (weight.def_nr > defgroup_index) { + weight.def_nr--; + } + } + } + }); } } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 063f7445e2c..dfc5c0cb7e4 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -404,17 +404,7 @@ class CurvesVertexGroupsAttributeProvider final : public DynamicAttributesProvid } MutableSpan dverts = curves->deform_verts_for_write(); - threading::parallel_for(dverts.index_range(), 1024, [&](IndexRange range) { - for (MDeformVert &dvert : dverts.slice(range)) { - MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); - BKE_defvert_remove_group(&dvert, weight); - for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { - if (weight.def_nr > index) { - weight.def_nr--; - } - } - } - }); + bke::remove_defgroup_index(dverts, index); return true; } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 2ec9f966851..ace3d1ccd79 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -931,17 +931,7 @@ class MeshVertexGroupsAttributeProvider final : public DynamicAttributesProvider } MutableSpan dverts = mesh->deform_verts_for_write(); - threading::parallel_for(dverts.index_range(), 1024, [&](IndexRange range) { - for (MDeformVert &dvert : dverts.slice(range)) { - MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); - BKE_defvert_remove_group(&dvert, weight); - for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { - if (weight.def_nr > index) { - weight.def_nr--; - } - } - } - }); + bke::remove_defgroup_index(dverts, index); return true; } -- 2.30.2 From 481caf24674b9dd4b93672ea33cbc6fa48017ed8 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 15:02:51 +0200 Subject: [PATCH 20/24] Revert more changes --- source/blender/blenkernel/BKE_deform.h | 4 -- source/blender/blenkernel/intern/deform.cc | 20 ++---- .../blenkernel/intern/object_deform.cc | 21 +++--- .../blender/editors/object/object_vgroup.cc | 64 ------------------- source/blender/makesdna/DNA_object_types.h | 3 +- 5 files changed, 14 insertions(+), 98 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 00d061388ed..4c5f03166dc 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -50,10 +50,6 @@ void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index); const struct ListBase *BKE_id_defgroup_list_get(const struct ID *id); struct ListBase *BKE_id_defgroup_list_get_mutable(struct ID *id); int BKE_id_defgroup_name_index(const struct ID *id, const char *name); -bool BKE_defgroup_listbase_name_find(const ListBase *defbase, - const char *name, - int *r_index, - struct bDeformGroup **r_group); bool BKE_id_defgroup_name_find(const struct ID *id, const char *name, int *r_index, diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 0c06f0145ec..867362b52ff 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -489,9 +489,6 @@ static const int *object_defgroup_active_index_get_p(const Object *ob) const bGPdata *gpd = (const bGPdata *)ob->data; return &gpd->vertex_group_active_index; } - default: { - BLI_assert_unreachable(); - } } return nullptr; } @@ -520,15 +517,16 @@ int BKE_id_defgroup_name_index(const ID *id, const char *name) return index; } -bool BKE_defgroup_listbase_name_find(const ListBase *defbase, - const char *name, - int *r_index, - bDeformGroup **r_group) +bool BKE_id_defgroup_name_find(const ID *id, + const char *name, + int *r_index, + bDeformGroup **r_group) { if (name == nullptr || name[0] == '\0') { return false; } int index; + const ListBase *defbase = BKE_id_defgroup_list_get(id); LISTBASE_FOREACH_INDEX (bDeformGroup *, group, defbase, index) { if (STREQ(name, group->name)) { if (r_index != nullptr) { @@ -543,14 +541,6 @@ bool BKE_defgroup_listbase_name_find(const ListBase *defbase, return false; } -bool BKE_id_defgroup_name_find(const ID *id, - const char *name, - int *r_index, - bDeformGroup **r_group) -{ - return BKE_defgroup_listbase_name_find(BKE_id_defgroup_list_get(id), name, r_index, r_group); -} - const ListBase *BKE_object_defgroup_list(const Object *ob) { BLI_assert(BKE_object_supports_vertex_groups(ob)); diff --git a/source/blender/blenkernel/intern/object_deform.cc b/source/blender/blenkernel/intern/object_deform.cc index 7a1b391b650..a0d5f3ee090 100644 --- a/source/blender/blenkernel/intern/object_deform.cc +++ b/source/blender/blenkernel/intern/object_deform.cc @@ -32,7 +32,6 @@ #include "DNA_scene_types.h" #include "BKE_action.h" -#include "BKE_curves.hh" #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_gpencil_legacy.h" @@ -112,18 +111,14 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob) MDeformVert *BKE_object_defgroup_data_create(ID *id) { - switch (GS(id->name)) { - case ID_ME: { - return BKE_mesh_deform_verts_for_write((Mesh *)id); - } - case ID_LT: { - Lattice *lt = (Lattice *)id; - lt->dvert = static_cast(MEM_callocN( - sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert")); - return lt->dvert; - } - default: - BLI_assert_unreachable(); + if (GS(id->name) == ID_ME) { + return BKE_mesh_deform_verts_for_write((Mesh *)id); + } + if (GS(id->name) == ID_LT) { + Lattice *lt = (Lattice *)id; + lt->dvert = static_cast(MEM_callocN( + sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert")); + return lt->dvert; } return nullptr; diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index f7513eddcaa..55c1675d7dc 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -33,7 +33,6 @@ #include "BKE_attribute.hh" #include "BKE_context.h" -#include "BKE_curves.hh" #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" @@ -61,7 +60,6 @@ #include "WM_api.hh" #include "WM_types.hh" -#include "ED_curves.hh" #include "ED_mesh.hh" #include "ED_object.hh" #include "ED_screen.hh" @@ -256,34 +254,7 @@ bool ED_vgroup_parray_alloc(ID *id, } return false; } - case ID_CV: { - Curves *curves_id = reinterpret_cast(id); - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - if (!curves.deform_verts().is_empty()) { - MutableSpan dverts = curves.deform_verts_for_write(); - *dvert_tot = curves.points_num(); - *dvert_arr = static_cast( - MEM_mallocN(sizeof(void *) * curves.points_num(), __func__)); - - if (use_vert_sel) { - const VArray selection = *curves.attributes().lookup_or_default( - ".selection", ATTR_DOMAIN_POINT, true); - - for (int64_t i = 0; i < curves.points_num(); i++) { - (*dvert_arr)[i] = selection[i] ? &dverts[i] : nullptr; - } - } - else { - for (int64_t i = 0; i < curves.points_num(); i++) { - (*dvert_arr)[i] = &dverts[i]; - } - } - - return true; - } - return false; - } default: break; } @@ -1135,24 +1106,6 @@ static void vgroup_select_verts(Object *ob, int select) } } } - else if (ob->type == OB_CURVES) { - Curves *curves_id = static_cast(ob->data); - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - const Span dverts = curves.deform_verts(); - if (!dverts.is_empty()) { - bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute( - curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL); - MutableSpan selection_typed = selection.span.typed(); - threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { - for (const int64_t index : range) { - if (BKE_defvert_find_index(&dverts[index], def_nr)) { - selection_typed[index] = bool(select); - } - } - }); - selection.finish(); - } - } } static void vgroup_duplicate(Object *ob) @@ -2355,23 +2308,6 @@ static void vgroup_assign_verts(Object *ob, const float weight) } } } - else if (ob->type == OB_CURVES) { - Curves *curves_id = static_cast(ob->data); - bke::CurvesGeometry &curves = curves_id->geometry.wrap(); - const VArray selection = *curves.attributes().lookup_or_default( - ".selection", ATTR_DOMAIN_POINT, true); - - MutableSpan dverts = curves.deform_verts_for_write(); - threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) { - for (const int64_t index : range) { - if (selection[index]) { - if (MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[index], def_nr)) { - dw->weight = weight; - } - } - } - }); - } } /** \} */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 9ccddabde7d..6e89c77dd7b 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -599,8 +599,7 @@ typedef enum ObjectType { OB_POINTCLOUD, \ OB_VOLUME, \ OB_GREASE_PENCIL)) -#define OB_TYPE_SUPPORT_VGROUP(_type) \ - (ELEM(_type, OB_MESH, OB_LATTICE, OB_GPENCIL_LEGACY, OB_CURVES)) +#define OB_TYPE_SUPPORT_VGROUP(_type) (ELEM(_type, OB_MESH, OB_LATTICE, OB_GPENCIL_LEGACY)) #define OB_TYPE_SUPPORT_EDITMODE(_type) \ (ELEM(_type, \ OB_MESH, \ -- 2.30.2 From aa57d67dfe801d71aa7a9d89587209c6292722c0 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 15:04:08 +0200 Subject: [PATCH 21/24] Revert include --- source/blender/blenkernel/intern/deform.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 867362b52ff..49b8c44bdac 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -14,7 +14,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_curves_types.h" #include "DNA_gpencil_legacy_types.h" #include "DNA_lattice_types.h" #include "DNA_mesh_types.h" @@ -525,8 +524,8 @@ bool BKE_id_defgroup_name_find(const ID *id, if (name == nullptr || name[0] == '\0') { return false; } - int index; const ListBase *defbase = BKE_id_defgroup_list_get(id); + int index; LISTBASE_FOREACH_INDEX (bDeformGroup *, group, defbase, index) { if (STREQ(name, group->name)) { if (r_index != nullptr) { -- 2.30.2 From d028ed7a5f3950e15b88da3dad3d9d1679e51b93 Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 15:11:40 +0200 Subject: [PATCH 22/24] Undo revert of `BKE_defgroup_listbase_name_find` --- source/blender/blenkernel/BKE_deform.h | 4 ++++ source/blender/blenkernel/intern/deform.cc | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 4c5f03166dc..00d061388ed 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -50,6 +50,10 @@ void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index); const struct ListBase *BKE_id_defgroup_list_get(const struct ID *id); struct ListBase *BKE_id_defgroup_list_get_mutable(struct ID *id); int BKE_id_defgroup_name_index(const struct ID *id, const char *name); +bool BKE_defgroup_listbase_name_find(const ListBase *defbase, + const char *name, + int *r_index, + struct bDeformGroup **r_group); bool BKE_id_defgroup_name_find(const struct ID *id, const char *name, int *r_index, diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index 49b8c44bdac..ff5db0c3790 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -516,15 +516,14 @@ int BKE_id_defgroup_name_index(const ID *id, const char *name) return index; } -bool BKE_id_defgroup_name_find(const ID *id, - const char *name, - int *r_index, - bDeformGroup **r_group) +bool BKE_defgroup_listbase_name_find(const ListBase *defbase, + const char *name, + int *r_index, + bDeformGroup **r_group) { if (name == nullptr || name[0] == '\0') { return false; } - const ListBase *defbase = BKE_id_defgroup_list_get(id); int index; LISTBASE_FOREACH_INDEX (bDeformGroup *, group, defbase, index) { if (STREQ(name, group->name)) { @@ -540,6 +539,14 @@ bool BKE_id_defgroup_name_find(const ID *id, return false; } +bool BKE_id_defgroup_name_find(const ID *id, + const char *name, + int *r_index, + bDeformGroup **r_group) +{ + return BKE_defgroup_listbase_name_find(BKE_id_defgroup_list_get(id), name, r_index, r_group); +} + const ListBase *BKE_object_defgroup_list(const Object *ob) { BLI_assert(BKE_object_supports_vertex_groups(ob)); -- 2.30.2 From 6a1ca2da933c479b9c020b528617a01a115588fc Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 16:08:31 +0200 Subject: [PATCH 23/24] Remove unecessary line --- source/blender/blenkernel/intern/curves_geometry.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 59510f2b13d..92a208cacd1 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -151,7 +151,6 @@ static void move_curves_geometry(CurvesGeometry &dst, CurvesGeometry &src) std::swap(dst.vertex_group_names.first, src.vertex_group_names.first); std::swap(dst.vertex_group_names.last, src.vertex_group_names.last); std::swap(dst.vertex_group_active_index, src.vertex_group_active_index); - src.vertex_group_active_index = 0; std::swap(dst.runtime, src.runtime); } -- 2.30.2 From c1047f590208998e99463a68e0db16b6f4cd48af Mon Sep 17 00:00:00 2001 From: Falk David Date: Tue, 26 Sep 2023 16:13:06 +0200 Subject: [PATCH 24/24] Forward decalare `MDeformVert` --- source/blender/blenkernel/BKE_curves.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index ffe97f61654..c26eae2739a 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -25,7 +25,7 @@ #include "BKE_attribute_math.hh" #include "BKE_curves.h" -#include "DNA_meshdata_types.h" +struct MDeformVert; namespace blender::bke { -- 2.30.2