57 defgroup = MEM_cnew<bDeformGroup>(__func__);
59 name.copy(defgroup->
name);
92 bDeformGroup *outgroup = MEM_cnew<bDeformGroup>(__func__);
97 outgroup->
next = outgroup->
prev =
nullptr;
104 const bool *vgroup_subset,
105 const int vgroup_num)
108 for (defgroup = 0; defgroup < vgroup_num; defgroup++) {
109 if (vgroup_subset[defgroup]) {
117 const bool *vgroup_subset,
118 const int vgroup_num,
120 const int flip_map_num)
123 for (defgroup = 0; defgroup < vgroup_num && defgroup < flip_map_num; defgroup++) {
124 if (vgroup_subset[defgroup] && (dvert_dst != dvert_src || flip_map[defgroup] != defgroup)) {
146 dvert_dst->
dw =
nullptr;
154 const int defgroup_dst,
156 const int defgroup_src)
181 for (
int i = 0; i < dvert_src->
totweight; i++, dw_src++) {
200 const int flip_map_num,
201 const bool use_ensure)
205 for (
int i = 0; i < dvert_src->
totweight; i++, dw_src++) {
206 if (dw_src->
def_nr < flip_map_num) {
226 for (
int i = dvert->
totweight; i != 0; i--, dw++) {
227 if (dw->
def_nr < map_len) {
236 const bool *vgroup_subset,
237 const int vgroup_num)
244 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
250 float tot_weight = 0.0f;
251 for (
int i = dvert->
totweight; i != 0; i--, dw++) {
252 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
257 if (tot_weight > 0.0f) {
258 float scalar = 1.0f / tot_weight;
260 for (
int i = dvert->
totweight; i != 0; i--, dw++) {
261 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
283 float tot_weight = 0.0f;
285 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
289 if (tot_weight > 0.0f) {
290 float scalar = 1.0f / tot_weight;
291 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
302 const bool *vgroup_subset,
303 const int vgroup_num,
304 const uint def_nr_lock)
311 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
312 if (def_nr_lock != dw->
def_nr) {
321 float tot_weight = 0.0f;
322 float lock_iweight = 1.0f;
324 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
325 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
326 if (dw->
def_nr != def_nr_lock) {
331 lock_iweight = (1.0f - dw_lock->
weight);
332 CLAMP(lock_iweight, 0.0f, 1.0f);
337 if (tot_weight > 0.0f) {
340 float scalar = (1.0f / tot_weight) * lock_iweight;
341 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
342 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
356 const bool *vgroup_subset,
357 const int vgroup_num,
358 const bool *lock_flags,
359 const int defbase_num)
366 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
367 if ((dw->
def_nr < defbase_num) && (lock_flags[dw->
def_nr] ==
false)) {
375 float tot_weight = 0.0f;
376 float lock_iweight = 0.0f;
378 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
379 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
380 if ((dw->
def_nr < defbase_num) && (lock_flags[dw->
def_nr] ==
false)) {
385 lock_iweight += dw->
weight;
390 lock_iweight =
max_ff(0.0f, 1.0f - lock_iweight);
392 if (tot_weight > 0.0f) {
395 float scalar = (1.0f / tot_weight) * lock_iweight;
396 for (i = dvert->
totweight, dw = dvert->
dw; i != 0; i--, dw++) {
397 if ((dw->
def_nr < vgroup_num) && vgroup_subset[dw->
def_nr]) {
398 if ((dw->
def_nr < defbase_num) && (lock_flags[dw->
def_nr] ==
false)) {
415 for (dw = dvert->
dw, i = 0; i < dvert->
totweight; dw++, i++) {
416 if (dw->
def_nr < flip_map_num) {
417 if (flip_map[dw->
def_nr] >= 0) {
431 for (dw = dvert->
dw, i = 0; i < totweight; dw++, i++) {
432 if (dw->
def_nr < flip_map_num) {
433 if (flip_map[dw->
def_nr] >= 0) {
459 const ID *
id =
static_cast<const ID *
>(ob->
data);
466 switch (
GS(id->name)) {
468 const Mesh *mesh = (
const Mesh *)
id;
496 return &mesh->vertex_group_active_index;
522 if (name.is_empty()) {
527 if (name == group->name) {
553 if (name.is_empty()) {
558 if (name == group->name) {
559 if (r_index !=
nullptr) {
562 if (r_group !=
nullptr) {
614 const bool use_default,
615 const bool use_only_unlocked,
620 *r_flip_map_num = defbase_num;
622 if (defbase_num == 0) {
627 char name_flip[
sizeof(dg->
name)];
629 int *map =
static_cast<int *
>(
MEM_mallocN(defbase_num *
sizeof(
int), __func__));
631 for (i = 0; i < defbase_num; i++) {
651 if (flip_num != -1) {
667 const bool use_default,
674 const bool use_default,
680 *r_flip_map_num = defbase_num;
682 if (defbase_num == 0) {
687 int i, flip_num, *map =
static_cast<int *
>(
MEM_mallocN(defbase_num *
sizeof(
int), __func__));
689 for (i = 0; i < defbase_num; i++) {
690 map[i] = use_default ? i : -1;
699 if (flip_num != -1) {
700 map[defgroup] = flip_num;
701 map[flip_num] = defgroup;
715 char name_flip[
sizeof(dg->
name)];
723 return (flip_index == -1 && use_default) ? index : flip_index;
737 if (curdef->name == name) {
760 std::string old_name = dg->
name;
773 return dw ? dw->
weight : 0.0f;
785 if (defgroup == -1) {
788 if (dvert ==
nullptr) {
797 if (dvert && defgroup >= 0) {
801 for (i = dvert->
totweight; i != 0; i--, dw++) {
802 if (dw->
def_nr == defgroup) {
819 if (!dvert || defgroup < 0) {
838 dw_new->
def_nr = defgroup;
853 if (!dvert || defgroup < 0) {
867 dw_new->
def_nr = defgroup;
883 const int i = dw - dvert->
dw;
917 for (i = dvert_a->
totweight; i != 0; i--, dw++) {
930 for (
int i = dvert->
totweight; i != 0; i--, dw++) {
943 const bool *defbase_sel)
948 if (defbase_sel ==
nullptr) {
952 for (
int i = dv->
totweight; i != 0; i--, dw++) {
953 if (dw->
def_nr < defbase_num) {
954 if (defbase_sel[dw->
def_nr]) {
964 const int defbase_num,
965 const bool *defbase_sel,
966 const int defbase_sel_num,
967 const bool is_normalized)
973 if (!is_normalized) {
974 total /= defbase_sel_num;
982 float unlocked_weight)
985 if (unlocked_weight > 0.0f) {
986 return weight / unlocked_weight;
990 if (locked_weight <= 0.0f) {
996 if (weight != 0.0f) {
1005 return weight / (1.0f - locked_weight);
1010 const int defbase_num,
1011 const bool *defbase_locked,
1012 const bool *defbase_unlocked)
1016 if (unlocked > 0.0f) {
1017 return weight / unlocked;
1039 for (
int i = 0; i < totvert; i++) {
1043 memcpy(dst[i].dw, src[i].dw,
sizeof(
MDeformWeight) * src[i].totweight);
1059 for (
int i = 0; i < totvert; i++) {
1083 const int verts_num,
1084 const bool invert_vgroup,
1087 if (dvert && defgroup != -1) {
1092 r_weights[i] = invert_vgroup ? (1.0f -
w) :
w;
1096 copy_vn_fl(r_weights, verts_num, invert_vgroup ? 1.0f : 0.0f);
1102 const int verts_num,
1104 const int edges_num,
1105 const bool invert_vgroup,
1108 if (
UNLIKELY(!dvert || defgroup == -1)) {
1114 float *tmp_weights =
static_cast<float *
>(
1115 MEM_mallocN(
sizeof(*tmp_weights) *
size_t(verts_num), __func__));
1118 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1123 r_weights[i] = (tmp_weights[edge[0]] + tmp_weights[edge[1]]) * 0.5f;
1131 const int verts_num,
1132 const int *corner_verts,
1133 const int loops_num,
1134 const bool invert_vgroup,
1137 if (
UNLIKELY(!dvert || defgroup == -1)) {
1143 float *tmp_weights =
static_cast<float *
>(
1144 MEM_mallocN(
sizeof(*tmp_weights) *
size_t(verts_num), __func__));
1147 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1150 r_weights[i] = tmp_weights[corner_verts[i]];
1158 const int verts_num,
1159 const int *corner_verts,
1162 const bool invert_vgroup,
1165 if (
UNLIKELY(!dvert || defgroup == -1)) {
1170 int i = faces.size();
1171 float *tmp_weights =
static_cast<float *
>(
1172 MEM_mallocN(
sizeof(*tmp_weights) *
size_t(verts_num), __func__));
1175 dvert, defgroup, verts_num, invert_vgroup, tmp_weights);
1179 const int *corner_vert = &corner_verts[face.start()];
1180 int j = face.
size();
1183 for (; j--; corner_vert++) {
1184 w += tmp_weights[*corner_vert];
1186 r_weights[i] =
w /
float(face.size());
1200 const void **sources,
1201 const float *weights,
1203 const float mix_factor)
1210 const int mix_mode = laymap->
mix_mode;
1216 float weight_src = 0.0f, weight_dst = 0.0f;
1218 bool has_dw_sources =
false;
1220 for (i =
count; i--;) {
1221 for (j = data_src[i]->totweight; j--;) {
1222 if ((dw_src = &data_src[i]->dw[j])->def_nr == idx_src) {
1223 weight_src += dw_src->
weight * weights[i];
1224 has_dw_sources =
true;
1232 weight_dst = dw_dst->
weight;
1240 CLAMP(weight_src, 0.0f, 1.0f);
1243 if (!has_dw_sources) {
1246 dw_dst->
weight = weight_src;
1253 dw_dst->
weight = weight_src;
1259 const float mix_factor,
1260 const float *mix_weights,
1261 const int num_elem_dst,
1262 const bool use_create,
1263 const bool use_delete,
1272 const bool *use_layers_src,
1273 const int num_layers_src)
1289 idx_src = num_layers_src;
1290 while (idx_src-- && !use_layers_src[idx_src]) {
1295 if (idx_dst < idx_src) {
1298 for (; idx_dst < idx_src; idx_dst++) {
1307 else if (use_delete && idx_dst > idx_src) {
1308 while (idx_dst-- > idx_src) {
1321 if (!use_layers_src[idx_src]) {
1353 dg_dst = dg_dst_next;
1358 idx_src < num_layers_src;
1359 idx_src++, dg_src = dg_src->
next)
1361 if (!use_layers_src[idx_src]) {
1411 const float mix_factor,
1412 const float *mix_weights,
1413 const int num_elem_dst,
1414 const bool use_create,
1415 const bool use_delete,
1420 const bool use_dupref_dst,
1421 const int fromlayers,
1424 int idx_src, idx_dst;
1451 if (data_dst && use_dupref_dst && r_map) {
1460 if (fromlayers >= 0) {
1461 idx_src = fromlayers;
1473 if (tolayers >= 0) {
1494 if (num <= idx_dst) {
1499 for (; num <= idx_dst; num++) {
1544 int num_src, num_sel_unused;
1545 bool *use_layers_src =
nullptr;
1548 switch (fromlayers) {
1563 if (use_layers_src) {
1598 const float blend = ((weight / 2.0f) + 0.5f);
1600 if (weight <= 0.25f) {
1602 r_rgb[1] =
blend * weight * 4.0f;
1605 else if (weight <= 0.50f) {
1608 r_rgb[2] =
blend * (1.0f - ((weight - 0.25f) * 4.0f));
1610 else if (weight <= 0.75f) {
1611 r_rgb[0] =
blend * ((weight - 0.50f) * 4.0f);
1615 else if (weight <= 1.0f) {
1617 r_rgb[1] =
blend * (1.0f - ((weight - 0.75f) * 4.0f));
1644 if (dvlist ==
nullptr) {
1652 for (
int i = 0; i <
count; i++) {
1661 if (mdverts ==
nullptr) {
1665 for (
int i =
count; i > 0; i--, mdverts++) {
1672 memcpy(dw_tmp, dw, dw_len);
1677 mdverts->
dw =
nullptr;
1694 const int dvert_index_;
1704 dverts_(const_cast<
MDeformVert *>(dverts.data())),
1705 dvert_index_(dvert_index)
1711 if (dverts_ ==
nullptr) {
1714 if (
const MDeformWeight *weight = this->find_weight_at_index(index)) {
1715 return weight->weight;
1723 if (value == 0.0f) {
1724 if (
MDeformWeight *weight = this->find_weight_at_index(index)) {
1725 weight->weight = 0.0f;
1730 weight->weight = value;
1737 for (const int64_t i : range) {
1738 this->set(i, src[i]);
1745 if (dverts_ ==
nullptr) {
1746 mask.foreach_index([&](
const int i) { dst[i] = 0.0f; });
1749 mask.slice(range).foreach_index_optimized<int64_t>([&](const int64_t index) {
1750 if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
1751 dst[index] = weight->weight;
1762 this->materialize(mask, dst);
1769 if (weight.def_nr == dvert_index_) {
1777 for (
const MDeformWeight &weight :
Span(dverts_[index].dw, dverts_[index].totweight)) {
1778 if (weight.def_nr == dvert_index_) {
1791 const int defgroup_index)
1799 for (MDeformVert &dvert : dverts.slice(range)) {
1800 MDeformWeight *weight = BKE_defvert_find_index(&dvert, defgroup_index);
1801 BKE_defvert_remove_group(&dvert, weight);
1802 for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) {
1803 if (weight.def_nr > defgroup_index) {
1815 threading::parallel_for(indices.index_range(), 512, [&](
const IndexRange range) {
1816 for (const int dst_i : range) {
1817 const int src_i = indices[dst_i];
1818 dst[dst_i].dw = static_cast<MDeformWeight *>(MEM_dupallocN(src[src_i].dw));
1819 dst[dst_i].totweight = src[src_i].totweight;
1820 dst[dst_i].flag = src[src_i].flag;
1830 dst[dst_i].totweight = src[src_i].totweight;
1831 dst[dst_i].flag = src[src_i].flag;
CustomData interface, see also DNA_customdata_types.h.
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
@ DT_LAYERS_VGROUP_SRC_BONE_SELECT
@ DT_LAYERS_VGROUP_SRC_BONE_DEFORM
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()
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const struct 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)
#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(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(1
#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)
struct MDeformVert MDeformVert
struct MDeformWeight MDeformWeight
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)
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr IndexRange index_range() const
void set_all(Span< float > src) override
void materialize(const IndexMask &mask, float *dst) const override
float get(const int64_t index) const override
void set(const int64_t index, const float value) override
void materialize_to_uninitialized(const IndexMask &mask, float *dst) const override
VArrayImpl_For_VertexWeights(MutableSpan< MDeformVert > dverts, const int dvert_index)
VArrayImpl_For_VertexWeights(Span< MDeformVert > dverts, const int dvert_index)
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)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
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))
_W64 unsigned int uintptr_t
int vertex_group_active_index
ListBase vertex_group_names
ListBase vertex_group_names
int vertex_group_active_index
ListBase vertex_group_names
ListBase vertex_group_names
int vertex_group_active_index