CurvesGeometry: Add initial vertex group support #106944
@ -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
|
||||
} // namespace blender::bke
|
||||
#endif
|
||||
|
||||
void BKE_defvert_weight_to_rgb(float r_rgb[3], float weight);
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/** \} */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user
const int
->int
dvert_index
->defgroup_index
/vgroup_index