CurvesGeometry: Add initial vertex group support #106944

Merged
Falk David merged 24 commits from filedescriptor/blender:curves-deform-verts into main 2023-09-27 10:26:16 +02:00
6 changed files with 124 additions and 130 deletions
Showing only changes of commit 78d830d0dd - Show all commits

View File

@ -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<float> varray_for_deform_verts(Span<MDeformVert> dverts, const int dvert_index);
VMutableArray<float> varray_for_deform_verts(MutableSpan<MDeformVert> dverts, int dvert_index);
filedescriptor marked this conversation as resolved Outdated
  • const int -> int
  • dvert_index -> defgroup_index/vgroup_index
- `const int` -> `int` - `dvert_index` -> `defgroup_index`/`vgroup_index`
} // namespace blender::bke
#endif
void BKE_defvert_weight_to_rgb(float r_rgb[3], float weight);

View File

@ -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<float> {
private:
MDeformVert *dverts_;
const int dvert_index_;
public:
VArrayImpl_For_VertexWeights(MutableSpan<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index)
{
}
VArrayImpl_For_VertexWeights(Span<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()),
dverts_(const_cast<MDeformVert *>(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<float> 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<int64_t>([&](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

View File

@ -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

View File

@ -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<float> {
private:
MDeformVert *dverts_;
const int dvert_index_;
public:
VArrayImpl_For_VertexWeights(MutableSpan<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index)
{
}
VArrayImpl_For_VertexWeights(Span<MDeformVert> dverts, const int dvert_index)
: VMutableArrayImpl<float>(dverts.size()),
dverts_(const_cast<MDeformVert *>(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<float> 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<int64_t>([&](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<float> varray_for_deform_verts(Span<MDeformVert> dverts, const int dvert_index)
{
return VArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, dvert_index);
}
VMutableArray<float> varray_for_deform_verts(MutableSpan<MDeformVert> dverts, const int dvert_index)
{
return VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, dvert_index);
}
} // namespace blender::bke
/** \} */

View File

@ -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<float>::ForSingle(default_value, curves->points_num()), ATTR_DOMAIN_POINT};
}
return {VArray<float>::For<VArrayImpl_For_VertexWeights>(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<MDeformVert> dverts = curves->deform_verts_for_write();
return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(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

View File

@ -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<float>::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT};
}
return {VArray<float>::For<VArrayImpl_For_VertexWeights>(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<MDeformVert> dverts = mesh->deform_verts_for_write();
return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(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