56 name.copy_utf8_truncated(defgroup->
name);
94 outgroup->
next = outgroup->
prev =
nullptr;
101 const bool *vgroup_subset,
102 const int vgroup_num)
105 for (defgroup = 0; defgroup < vgroup_num; defgroup++) {
106 if (vgroup_subset[defgroup]) {
114 const bool *vgroup_subset,
115 const int vgroup_num,
117 const int flip_map_num)
120 for (defgroup = 0; defgroup < vgroup_num && defgroup < flip_map_num; defgroup++) {
121 if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
143 dvert_dst->
dw =
nullptr;
151 const int defgroup_dst,
153 const int defgroup_src)
178 for (
int i = 0;
i < dvert_src->
totweight;
i++, dw_src++) {
197 const int flip_map_num,
198 const bool use_ensure)
202 for (
int i = 0;
i < dvert_src->
totweight;
i++, dw_src++) {
203 if (dw_src->
def_nr < flip_map_num) {
224 if (dw->
def_nr < map_len) {
254 const bool use_subset = !subset_flags.
is_empty();
255 const bool use_locks = !lock_flags.
is_empty();
256 const bool use_soft_locks = !soft_lock_flags.
is_empty();
284 if (use_subset && !subset_flags[dw->
def_nr]) {
288 const bool is_unlocked = lock_flags.
is_empty() || !lock_flags[dw->
def_nr];
299 float total_locked_weight = 0.0f;
300 float total_soft_locked_weight = 0.0f;
301 float total_regular_weight = 0.0f;
302 int soft_locked_group_count = 0;
304 if (use_subset && !subset_flags[dw.def_nr]) {
309 if (use_locks && lock_flags[dw.def_nr]) {
311 total_locked_weight += dw.weight;
313 else if (use_soft_locks && soft_lock_flags[dw.def_nr]) {
314 total_soft_locked_weight += dw.weight;
315 soft_locked_group_count++;
318 total_regular_weight += dw.weight;
322 const float available_weight =
max_ff(0.0f, 1.0f - total_locked_weight);
329 if (total_regular_weight <= 0.0f && total_soft_locked_weight <= 0.0f) {
354 if (soft_locked_group_count == 0) {
358 const float weight = available_weight / soft_locked_group_count;
360 if (!subset_flags.
is_empty() && !subset_flags[dw.def_nr]) {
365 if (!lock_flags.
is_empty() && lock_flags[dw.def_nr]) {
370 if (use_soft_locks && soft_lock_flags[dw.def_nr]) {
379 float soft_locked_scale;
381 const bool must_adjust_soft_locked = total_soft_locked_weight >= available_weight ||
382 total_regular_weight <= 0.0f;
383 if (must_adjust_soft_locked) {
384 soft_locked_scale = available_weight / total_soft_locked_weight;
385 regular_scale = 0.0f;
388 soft_locked_scale = 1.0f;
389 regular_scale = (available_weight - total_soft_locked_weight) / total_regular_weight;
394 if (use_subset && !subset_flags[dw.def_nr]) {
399 if (use_locks && lock_flags[dw.def_nr]) {
404 if (use_soft_locks && soft_lock_flags[dw.def_nr]) {
405 dw.weight *= soft_locked_scale;
408 dw.weight *= regular_scale;
412 CLAMP(dw.weight, 0.0f, 1.0f);
422 if (dw->
def_nr < flip_map_num) {
423 if (flip_map[dw->
def_nr] >= 0) {
437 for (dw = dvert->
dw,
i = 0;
i < totweight; dw++,
i++) {
438 if (dw->
def_nr < flip_map_num) {
439 if (flip_map[dw->
def_nr] >= 0) {
465 const ID *
id =
static_cast<const ID *
>(ob->
data);
474 const Mesh *mesh = (
const Mesh *)
id;
528 if (
name.is_empty()) {
533 if (
name == group->name) {
559 if (
name.is_empty()) {
564 if (
name == group->name) {
565 if (r_index !=
nullptr) {
568 if (r_group !=
nullptr) {
620 const bool use_default,
621 const bool use_only_unlocked,
626 *r_flip_map_num = defbase_num;
628 if (defbase_num == 0) {
633 char name_flip[
sizeof(dg->
name)];
637 for (
i = 0;
i < defbase_num;
i++) {
657 if (flip_num != -1) {
673 const bool use_default,
680 const bool use_default,
686 *r_flip_map_num = defbase_num;
688 if (defbase_num == 0) {
695 for (
i = 0;
i < defbase_num;
i++) {
696 map[
i] = use_default ?
i : -1;
705 if (flip_num != -1) {
706 map[defgroup] = flip_num;
707 map[flip_num] = defgroup;
721 char name_flip[
sizeof(dg->
name)];
729 return (flip_index == -1 && use_default) ? index : flip_index;
743 if (curdef->name ==
name) {
764 std::string old_name = dg->
name;
777 return dw ? dw->
weight : 0.0f;
790 if (defgroup == -1) {
793 if (dvert ==
nullptr) {
794 return invert ? 1.0 : 0.0f;
800 weight = 1.0f - weight;
808 if (dvert && defgroup >= 0) {
813 if (dw->
def_nr == defgroup) {
830 if (!dvert || defgroup < 0) {
848 dw_new->
def_nr = defgroup;
863 if (!dvert || defgroup < 0) {
876 dw_new->
def_nr = defgroup;
892 const int i = dw - dvert->
dw;
952 const bool *defbase_sel)
957 if (defbase_sel ==
nullptr) {
962 if (dw->
def_nr < defbase_num) {
963 if (defbase_sel[dw->
def_nr]) {
973 const int defbase_num,
974 const bool *defbase_sel,
975 const int defbase_sel_num,
976 const bool is_normalized)
982 if (!is_normalized) {
983 total /= defbase_sel_num;
991 float unlocked_weight)
994 if (unlocked_weight > 0.0f) {
995 return weight / unlocked_weight;
999 if (locked_weight <= 0.0f) {
1005 if (weight != 0.0f) {
1014 return weight / (1.0f - locked_weight);
1019 const int defbase_num,
1020 const bool *defbase_locked,
1021 const bool *defbase_unlocked)
1025 if (unlocked > 0.0f) {
1026 return weight / unlocked;
1048 for (
int i = 0;
i < totvert;
i++) {
1067 for (
int i = 0;
i < totvert;
i++) {
1091 const int verts_num,
1092 const bool invert_vgroup,
1095 if (dvert && defgroup != -1) {
1100 r_weights[
i] = invert_vgroup ? (1.0f -
w) :
w;
1104 copy_vn_fl(r_weights, verts_num, invert_vgroup ? 1.0f : 0.0f);
1110 const int verts_num,
1112 const bool invert_vgroup,
1115 if (
UNLIKELY(!dvert || defgroup == -1)) {
1120 int i = edges.
size();
1124 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1129 r_weights[
i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
1137 const int verts_num,
1139 const bool invert_vgroup,
1142 if (
UNLIKELY(!dvert || defgroup == -1)) {
1147 int i = corner_verts.
size();
1151 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1154 r_weights[
i] = tmp_weights[corner_verts[
i]];
1162 const int verts_num,
1165 const bool invert_vgroup,
1168 if (
UNLIKELY(!dvert || defgroup == -1)) {
1177 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1181 const int *corner_vert = &corner_verts[face.
start()];
1182 int j = face.
size();
1185 for (; j--; corner_vert++) {
1186 w += tmp_weights[*corner_vert];
1202 const void **sources,
1203 const float *weights,
1205 const float mix_factor)
1212 const int mix_mode = laymap->
mix_mode;
1217 float weight_src = 0.0f, weight_dst = 0.0f;
1219 bool has_dw_sources =
false;
1222 for (j = data_src[
i]->totweight; j--;) {
1224 if (dw_src->
def_nr == idx_src) {
1225 weight_src += dw_src->
weight * weights[
i];
1226 has_dw_sources =
true;
1234 weight_dst = dw_dst->
weight;
1242 CLAMP(weight_src, 0.0f, 1.0f);
1245 if (!has_dw_sources) {
1248 dw_dst->
weight = weight_src;
1255 dw_dst->
weight = weight_src;
1261 const float mix_factor,
1262 const float *mix_weights,
1263 const bool use_create,
1264 const bool use_delete,
1266 const Mesh &mesh_src,
1270 const bool *use_layers_src,
1271 const int num_layers_src)
1287 idx_src = num_layers_src;
1288 while (idx_src-- && !use_layers_src[idx_src]) {
1293 if (idx_dst < idx_src) {
1296 for (; idx_dst < idx_src; idx_dst++) {
1305 else if (use_delete && idx_dst > idx_src) {
1306 while (idx_dst-- > idx_src) {
1312 if (!use_layers_src[idx_src]) {
1320 mesh_src.deform_verts().data(),
1321 mesh_dst.deform_verts_for_write().data(),
1344 dg_dst = dg_dst_next;
1349 idx_src < num_layers_src;
1350 idx_src++, dg_src = dg_src->
next)
1352 if (!use_layers_src[idx_src]) {
1357 if (idx_dst == -1) {
1373 mesh_src.deform_verts().data(),
1374 mesh_dst.deform_verts_for_write().data(),
1396 const float mix_factor,
1397 const float *mix_weights,
1398 const bool use_create,
1399 const bool use_delete,
1402 const Mesh &mesh_src,
1404 const bool use_dupref_dst,
1405 const int fromlayers,
1408 int idx_src, idx_dst;
1429 if (fromlayers >= 0) {
1430 idx_src = fromlayers;
1442 if (tolayers >= 0) {
1451 if (idx_dst == -1) {
1464 if (
num <= idx_dst) {
1469 for (;
num <= idx_dst;
num++) {
1477 if (idx_dst == -1) {
1495 mesh_src.deform_verts().data(),
1496 mesh_dst.deform_verts_for_write().data(),
1508 int num_src, num_sel_unused;
1509 bool *use_layers_src =
nullptr;
1512 switch (fromlayers) {
1527 if (use_layers_src) {
1558 const float blend = ((weight / 2.0f) + 0.5f);
1560 if (weight <= 0.25f) {
1562 r_rgb[1] =
blend * weight * 4.0f;
1565 else if (weight <= 0.50f) {
1568 r_rgb[2] =
blend * (1.0f - ((weight - 0.25f) * 4.0f));
1570 else if (weight <= 0.75f) {
1571 r_rgb[0] =
blend * ((weight - 0.50f) * 4.0f);
1575 else if (weight <= 1.0f) {
1577 r_rgb[1] =
blend * (1.0f - ((weight - 0.75f) * 4.0f));
1604 if (dvlist ==
nullptr) {
1621 if (mdverts ==
nullptr) {
1625 for (
int i =
count;
i > 0;
i--, mdverts++) {
1632 memcpy(dw_tmp, dw, dw_len);
1637 mdverts->
dw =
nullptr;
1654 const int dvert_index_;
1665 dvert_index_(dvert_index)
1671 if (dverts_ ==
nullptr) {
1674 if (
const MDeformWeight *weight = this->find_weight_at_index(index)) {
1675 return weight->weight;
1683 if (value == 0.0f) {
1684 if (
MDeformWeight *weight = this->find_weight_at_index(index)) {
1685 weight->weight = 0.0f;
1697 for (const int64_t i : range) {
1698 this->set(i, src[i]);
1705 const bool )
const override
1707 if (dverts_ ==
nullptr) {
1708 mask.foreach_index([&](
const int i) { dst[
i] = 0.0f; });
1711 mask.slice(range).foreach_index_optimized<int64_t>([&](const int64_t index) {
1712 if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
1713 dst[index] = weight->weight;
1726 if (weight.def_nr == dvert_index_) {
1734 for (
const MDeformWeight &weight :
Span(dverts_[index].dw, dverts_[index].totweight)) {
1735 if (weight.def_nr == dvert_index_) {
1748 const int defgroup_index)
1756 for (MDeformVert &dvert : dverts.slice(range)) {
1757 MDeformWeight *weight = BKE_defvert_find_index(&dvert, defgroup_index);
1758 BKE_defvert_remove_group(&dvert, weight);
1759 for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) {
1760 if (weight.def_nr > defgroup_index) {
1773 for (const int dst_i : range) {
1774 const int src_i = indices[dst_i];
1775 dst[dst_i].dw = static_cast<MDeformWeight *>(MEM_dupallocN(src[src_i].dw));
1776 dst[dst_i].totweight = src[src_i].totweight;
1777 dst[dst_i].flag = src[src_i].flag;
1787 dst[dst_i].totweight = src[src_i].totweight;
1788 dst[dst_i].flag = src[src_i].flag;
CustomData interface, see also DNA_customdata_types.h.
Low-level operations for grease pencil.
void BKE_grease_pencil_vgroup_name_update(Object *ob, const char *old_name, const char *new_name)
Utility functions for vertex groups in grease pencil objects.
General operations, lookup, etc. for blender objects.
void BKE_object_batch_cache_dirty_tag(Object *ob)
#define BLI_assert_unreachable()
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float max_ff(float a, float b)
void copy_vn_fl(float *array_tar, int size, float val)
ATTR_WARN_UNUSED_RESULT const size_t num
#define STRNCPY_UTF8(dst, src)
size_t BLI_string_flip_side_name(char *name_dst, const char *name_src, bool strip_number, size_t name_dst_maxncpy) ATTR_NONNULL(1
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define UNUSED_VARS_NDEBUG(...)
#define BLO_write_struct(writer, struct_name, data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
@ DT_LAYERS_VGROUP_SRC_BONE_SELECT
@ DT_LAYERS_VGROUP_SRC_BONE_DEFORM
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
Object is a sort of wrapper for general info.
#define OB_TYPE_SUPPORT_VGROUP(_type)
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
static VArray from(Args &&...args)
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
static VMutableArray from(Args &&...args)
void set_all(Span< float > src) override
float get(const int64_t index) const override
void set(const int64_t index, const float value) override
VArrayImpl_For_VertexWeights(MutableSpan< MDeformVert > dverts, const int dvert_index)
VArrayImpl_For_VertexWeights(Span< MDeformVert > dverts, const int dvert_index)
void materialize(const IndexMask &mask, float *dst, const bool) const override
void data_transfer_layersmapping_add_item(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n, const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag, cd_datatransfer_interp interp, void *interp_data)
float data_transfer_interp_float_do(const int mix_mode, const float val_dst, const float val_src, const float mix_factor)
CCL_NAMESPACE_BEGIN ccl_device float invert(const float color, const float factor)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
void validate_drawing_vertex_groups(GreasePencil &grease_pencil)
void remove_defgroup_index(MutableSpan< MDeformVert > dverts, int defgroup_index)
void gather_deform_verts(Span< MDeformVert > src, Span< int > indices, MutableSpan< MDeformVert > dst)
VMutableArray< float > varray_for_mutable_deform_verts(MutableSpan< MDeformVert > dverts, int defgroup_index)
VArray< float > varray_for_deform_verts(Span< MDeformVert > dverts, int defgroup_index)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
VecBase< int32_t, 2 > int2
int vertex_group_active_index
ListBase vertex_group_names
ListBase vertex_group_names
int vertex_group_active_index
ListBase vertex_group_names
int vertex_group_active_index
ListBase vertex_group_names
int vertex_group_active_index
static int blend(const Tex *tex, const float texvec[3], TexResult *texres)