Blender V5.0
object_deform.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10#include <cstring>
11
12#include "MEM_guardedalloc.h"
13
14#include "BLT_translation.hh"
15
16#include "BLI_ghash.h"
17#include "BLI_listbase.h"
18#include "BLI_string_utils.hh"
19#include "BLI_utildefines.h"
20
21#include "DNA_armature_types.h"
22#include "DNA_cloth_types.h"
23#include "DNA_curve_types.h"
25#include "DNA_lattice_types.h"
26#include "DNA_mesh_types.h"
27#include "DNA_meshdata_types.h"
28#include "DNA_modifier_types.h"
30#include "DNA_object_types.h"
31#include "DNA_particle_types.h"
32#include "DNA_scene_types.h"
33
34#include "BKE_action.hh"
35#include "BKE_deform.hh"
36#include "BKE_editmesh.hh"
38#include "BKE_mesh.hh"
39#include "BKE_modifier.hh"
40#include "BKE_object.hh"
41#include "BKE_object_deform.h" /* own include */
42
43/* -------------------------------------------------------------------- */
46
48{
49 Lattice *lt = (Lattice *)id;
50 BLI_assert(GS(id->name) == ID_LT);
51 return (lt->editlatt) ? lt->editlatt->latt : lt;
52}
53
55{
56 /* these cases don't use names to refer to vertex groups, so when
57 * they get removed the numbers get out of sync, this corrects that */
58
59 if (ob->soft) {
60 ob->soft->vertgroup = map[ob->soft->vertgroup];
61 }
62
64 if (md->type == eModifierType_Explode) {
66 emd->vgroup = map[emd->vgroup];
67 }
68 else if (md->type == eModifierType_Cloth) {
70 ClothSimSettings *clsim = clmd->sim_parms;
71 ClothCollSettings *clcoll = clmd->coll_parms;
72
73 if (clsim) {
74 clsim->vgroup_mass = map[clsim->vgroup_mass];
75 clsim->vgroup_shrink = map[clsim->vgroup_shrink];
76 clsim->vgroup_struct = map[clsim->vgroup_struct];
77 clsim->vgroup_shear = map[clsim->vgroup_shear];
78 clsim->vgroup_bend = map[clsim->vgroup_bend];
79 clsim->vgroup_intern = map[clsim->vgroup_intern];
80 clsim->vgroup_pressure = map[clsim->vgroup_pressure];
81 clcoll->vgroup_selfcol = map[clcoll->vgroup_selfcol];
82 clcoll->vgroup_objcol = map[clcoll->vgroup_objcol];
83 }
84 }
85 }
86
88 for (int a = 0; a < PSYS_TOT_VG; a++) {
89 psys->vgroup[a] = map[psys->vgroup[a]];
90 }
91 }
92}
93
95
96/* -------------------------------------------------------------------- */
99
101{
102 bDeformGroup *defgroup;
103
104 if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) {
105 return nullptr;
106 }
107
108 defgroup = BKE_object_defgroup_new(ob, name);
110
111 return defgroup;
112}
113
118
120{
121 if (GS(id->name) == ID_ME) {
122 return ((Mesh *)id)->deform_verts_for_write().data();
123 }
124 if (GS(id->name) == ID_LT) {
125 Lattice *lt = (Lattice *)id;
127 size_t(lt->pntsu) * size_t(lt->pntsv) * size_t(lt->pntsw), "lattice deformVert");
128 return lt->dvert;
129 }
130
131 return nullptr;
132}
133
135
136/* -------------------------------------------------------------------- */
139
140bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
141{
142 using namespace blender;
143 using namespace blender::bke;
144 MDeformVert *dv;
145 const ListBase *defbase = BKE_object_defgroup_list(ob);
146 const int def_nr = BLI_findindex(defbase, dg);
147 bool changed = false;
148
149 if (ob->type == OB_MESH) {
150 Mesh *mesh = static_cast<Mesh *>(ob->data);
151
152 if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
153 const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
154
155 if (cd_dvert_offset != -1) {
156 BMVert *eve;
157 BMIter iter;
158
159 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
160 dv = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
161
162 if (dv && dv->dw && (!use_selection || BM_elem_flag_test(eve, BM_ELEM_SELECT))) {
163 MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
164 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
165 changed = true;
166 }
167 }
168 }
169 }
170 else {
171 if (mesh->deform_verts().data()) {
172 const AttributeAccessor attributes = mesh->attributes();
173 const VArray select_vert = *attributes.lookup_or_default<bool>(
174 ".select_vert", AttrDomain::Point, false);
175 int i;
176
177 dv = mesh->deform_verts_for_write().data();
178
179 for (i = 0; i < mesh->verts_num; i++, dv++) {
180 if (dv->dw && (!use_selection || select_vert[i])) {
181 MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
182 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
183 changed = true;
184 }
185 }
186 }
187 }
188 }
189 else if (ob->type == OB_LATTICE) {
191
192 if (lt->dvert) {
193 BPoint *bp;
194 int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
195
196 for (i = 0, bp = lt->def; i < tot; i++, bp++) {
197 if (!use_selection || (bp->f1 & SELECT)) {
198 MDeformWeight *dw;
199
200 dv = &lt->dvert[i];
201
202 dw = BKE_defvert_find_index(dv, def_nr);
203 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
204 changed = true;
205 }
206 }
207 }
208 }
209
210 return changed;
211}
212
213bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
214{
215 bool changed = false;
216
217 const ListBase *defbase = BKE_object_defgroup_list(ob);
218
219 LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
220 if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
221 changed = true;
222 }
223 }
224
225 return changed;
226}
227
229
230/* -------------------------------------------------------------------- */
233
234static void object_defgroup_remove_update_users(Object *ob, const int idx)
235{
236 int i, defbase_tot = BKE_object_defgroup_count(ob) + 1;
237 int *map = MEM_malloc_arrayN<int>(size_t(defbase_tot), "vgroup del");
238
239 map[idx] = map[0] = 0;
240 for (i = 1; i < idx; i++) {
241 map[i] = i;
242 }
243 for (i = idx + 1; i < defbase_tot; i++) {
244 map[i] = i - 1;
245 }
246
248 MEM_freeN(map);
249}
250
251static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
252{
254
255 /* Remove the group */
257
258 BLI_freelinkN(defbase, dg);
259
260 /* Update the active deform index if necessary */
261 const int active_index = BKE_object_defgroup_active_index_get(ob);
262 if (active_index > def_nr) {
263 BKE_object_defgroup_active_index_set(ob, active_index - 1);
264 }
265
266 /* Remove all deform-verts. */
267 if (BLI_listbase_is_empty(defbase)) {
268 if (ob->type == OB_MESH) {
269 Mesh *mesh = static_cast<Mesh *>(ob->data);
271 }
272 else if (ob->type == OB_LATTICE) {
274 MEM_SAFE_FREE(lt->dvert);
275 }
276 else if (ob->type == OB_GREASE_PENCIL) {
277 GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
279 }
280 }
281 else if (BKE_object_defgroup_active_index_get(ob) < 1) {
282 /* Keep a valid active index if we still have some vgroups. */
284 }
285}
286
288{
289 MDeformVert *dvert_array = nullptr;
290 int dvert_tot = 0;
291 const ListBase *defbase = BKE_object_defgroup_list(ob);
292
293 const int def_nr = BLI_findindex(defbase, dg);
294
295 BLI_assert(def_nr != -1);
296
297 BKE_object_defgroup_array_get(static_cast<ID *>(ob->data), &dvert_array, &dvert_tot);
298
299 if (dvert_array) {
300 int i, j;
301 MDeformVert *dv;
302 for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
303 MDeformWeight *dw;
304
305 dw = BKE_defvert_find_index(dv, def_nr);
306 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
307
308 /* inline, make into a function if anything else needs to do this */
309 for (j = 0; j < dv->totweight; j++) {
310 if (dv->dw[j].def_nr > def_nr) {
311 dv->dw[j].def_nr--;
312 }
313 }
314 /* done */
315 }
316 }
317
318 object_defgroup_remove_common(ob, dg, def_nr);
319}
320
322{
323 int i;
324 const ListBase *defbase = BKE_object_defgroup_list(ob);
325 const int def_nr = BLI_findindex(defbase, dg);
326
327 BLI_assert(def_nr != -1);
328
329 /* Make sure that no verts are using this group - if none were removed,
330 * we can skip next per-vert update. */
331 if (!BKE_object_defgroup_clear(ob, dg, false)) {
332 /* Nothing to do. */
333 }
334 /* Else, make sure that any groups with higher indices are adjusted accordingly */
335 else if (ob->type == OB_MESH) {
336 Mesh *mesh = static_cast<Mesh *>(ob->data);
337 BMEditMesh *em = mesh->runtime->edit_mesh.get();
338 const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
339
340 BMIter iter;
341 BMVert *eve;
342 MDeformVert *dvert;
343
344 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
345 dvert = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
346
347 if (dvert) {
348 for (i = 0; i < dvert->totweight; i++) {
349 if (dvert->dw[i].def_nr > def_nr) {
350 dvert->dw[i].def_nr--;
351 }
352 }
353 }
354 }
355 }
356 else if (ob->type == OB_LATTICE) {
357 Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
358 BPoint *bp;
359 MDeformVert *dvert = lt->dvert;
360 int a, tot;
361
362 if (dvert) {
363 tot = lt->pntsu * lt->pntsv * lt->pntsw;
364 for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
365 for (i = 0; i < dvert->totweight; i++) {
366 if (dvert->dw[i].def_nr > def_nr) {
367 dvert->dw[i].def_nr--;
368 }
369 }
370 }
371 }
372 }
373
374 object_defgroup_remove_common(ob, dg, def_nr);
375}
376
378{
381 }
382 else {
384 }
385
386 if (ob->type == OB_GREASE_PENCIL) {
388 *static_cast<GreasePencil *>(ob->data));
389 }
390
392}
393
394void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked)
395{
397
398 bDeformGroup *dg = (bDeformGroup *)defbase->first;
399 const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
400
401 if (dg) {
402 while (dg) {
403 bDeformGroup *next_dg = dg->next;
404
405 if (!only_unlocked || (dg->flag & DG_LOCK_WEIGHT) == 0) {
406 if (edit_mode) {
408 }
409 else {
411 }
412 }
413
414 dg = next_dg;
415 }
416 }
417 else { /* `defbase` is empty. */
418 /* Remove all deform-verts. */
419 if (ob->type == OB_MESH) {
420 Mesh *mesh = static_cast<Mesh *>(ob->data);
422 }
423 else if (ob->type == OB_LATTICE) {
425 MEM_SAFE_FREE(lt->dvert);
426 }
427 else if (ob->type == OB_GREASE_PENCIL) {
428 GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
430 }
431 /* Fix counters/indices */
433 }
434}
435
440
441int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
442{
443 const ListBase *src_defbase = BKE_object_defgroup_list(ob_src);
444 const ListBase *dst_defbase = BKE_object_defgroup_list(ob_dst);
445
446 /* Build src to merged mapping of vgroup indices. */
447 if (BLI_listbase_is_empty(src_defbase) || BLI_listbase_is_empty(dst_defbase)) {
448 *r_map_len = 0;
449 return nullptr;
450 }
451
452 bDeformGroup *dg_src;
453 *r_map_len = BLI_listbase_count(src_defbase);
454 int *vgroup_index_map = MEM_malloc_arrayN<int>(size_t(*r_map_len), "defgroup index map create");
455 bool is_vgroup_remap_needed = false;
456 int i;
457
458 for (dg_src = static_cast<bDeformGroup *>(src_defbase->first), i = 0; dg_src;
459 dg_src = dg_src->next, i++)
460 {
461 vgroup_index_map[i] = BKE_object_defgroup_name_index(ob_dst, dg_src->name);
462 is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i);
463 }
464
465 if (!is_vgroup_remap_needed) {
466 MEM_freeN(vgroup_index_map);
467 vgroup_index_map = nullptr;
468 *r_map_len = 0;
469 }
470
471 return vgroup_index_map;
472}
473
475 int dvert_len,
476 const int *map,
477 int map_len)
478{
479 if (map == nullptr || map_len == 0) {
480 return;
481 }
482
483 MDeformVert *dv = dvert;
484 for (int i = 0; i < dvert_len; i++, dv++) {
485 int totweight = dv->totweight;
486 for (int j = 0; j < totweight; j++) {
487 int def_nr = dv->dw[j].def_nr;
488 if (uint(def_nr) < uint(map_len) && map[def_nr] != -1) {
489 dv->dw[j].def_nr = map[def_nr];
490 }
491 else {
492 totweight--;
493 dv->dw[j] = dv->dw[totweight];
494 j--;
495 }
496 }
497 if (totweight != dv->totweight) {
498 if (totweight) {
499 dv->dw = static_cast<MDeformWeight *>(MEM_reallocN(dv->dw, sizeof(*dv->dw) * totweight));
500 }
501 else {
502 MEM_SAFE_FREE(dv->dw);
503 }
504 dv->totweight = totweight;
505 }
506 }
507}
508
509bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
510{
511 if (id) {
512 switch (GS(id->name)) {
513 case ID_ME: {
514 Mesh *mesh = (Mesh *)id;
515 *dvert_arr = mesh->deform_verts_for_write().data();
516 *dvert_tot = mesh->verts_num;
517 return true;
518 }
519 case ID_LT: {
521 *dvert_arr = lt->dvert;
522 *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
523 return true;
524 }
525 case ID_GP:
526 /* Should not be used with grease pencil objects. */
527 dvert_arr = nullptr;
528 return false;
529 default:
530 break;
531 }
532 }
533
534 *dvert_arr = nullptr;
535 *dvert_tot = 0;
536 return false;
537}
538
540
541/* --- functions for getting vgroup aligned maps --- */
542
543bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
544{
545 bool is_locked = false;
546 int i;
548 bool *lock_flags = MEM_malloc_arrayN<bool>(size_t(defbase_tot), "defflags");
549 bDeformGroup *defgroup;
550
551 for (i = 0, defgroup = static_cast<bDeformGroup *>(defbase->first); i < defbase_tot && defgroup;
552 defgroup = defgroup->next, i++)
553 {
554 lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
555 is_locked |= lock_flags[i];
556 }
557 if (is_locked) {
558 return lock_flags;
559 }
560
561 MEM_freeN(lock_flags);
562 return nullptr;
563}
564
565bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
566{
567 bDeformGroup *dg;
568 ModifierData *md;
569 bool *defgroup_validmap;
570 GHash *gh;
571 int i, step1 = 1;
572 const ListBase *defbase = BKE_object_defgroup_list(ob);
573 VirtualModifierData virtual_modifier_data;
574
575 if (BLI_listbase_is_empty(defbase)) {
576 return nullptr;
577 }
578
579 gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
580
581 /* add all names to a hash table */
582 LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
583 BLI_ghash_insert(gh, dg->name, nullptr);
584 }
585
586 BLI_assert(BLI_ghash_len(gh) == defbase_tot);
587
588 /* now loop through the armature modifiers and identify deform bones */
589 for (md = static_cast<ModifierData *>(ob->modifiers.first); md;
590 md = !md->next && step1 ? (step1 = 0),
591 BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data) :
592 md->next)
593 {
595 continue;
596 }
597
599 Object *object = (md->type == eModifierType_Armature) ?
600 ((ArmatureModifierData *)md)->object :
601 ((GreasePencilArmatureModifierData *)md)->object;
602 if (object && object->pose) {
603 bPose *pose = object->pose;
604
605 LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
606 void **val_p;
607 if (chan->bone->flag & BONE_NO_DEFORM) {
608 continue;
609 }
610
611 val_p = BLI_ghash_lookup_p(gh, chan->name);
612 if (val_p) {
613 *val_p = POINTER_FROM_INT(1);
614 }
615 }
616 }
617 }
618 }
619
620 defgroup_validmap = MEM_malloc_arrayN<bool>(size_t(defbase_tot), "wpaint valid map");
621
622 /* add all names to a hash table */
623 for (dg = static_cast<bDeformGroup *>(defbase->first), i = 0; dg; dg = dg->next, i++) {
624 defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != nullptr);
625 }
626
627 BLI_assert(i == BLI_ghash_len(gh));
628
629 BLI_ghash_free(gh, nullptr, nullptr);
630
631 return defgroup_validmap;
632}
633
634bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
635{
636 bool *dg_selection = MEM_malloc_arrayN<bool>(size_t(defbase_tot), __func__);
637 bDeformGroup *defgroup;
638 uint i;
640 (*r_dg_flags_sel_tot) = 0;
641
642 const ListBase *defbase = BKE_object_defgroup_list(ob);
643
644 if (armob) {
645 bPose *pose = armob->pose;
646 for (i = 0, defgroup = static_cast<bDeformGroup *>(defbase->first);
647 i < defbase_tot && defgroup;
648 defgroup = defgroup->next, i++)
649 {
650 bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
651 if (pchan && (pchan->flag & POSE_SELECTED)) {
652 dg_selection[i] = true;
653 (*r_dg_flags_sel_tot) += 1;
654 }
655 else {
656 dg_selection[i] = false;
657 }
658 }
659 }
660 else {
661 memset(dg_selection, false, sizeof(*dg_selection) * defbase_tot);
662 }
663
664 return dg_selection;
665}
666
667bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags,
668 const bool *validmap,
669 int index)
670{
671 return validmap && validmap[index] && !(lock_flags && lock_flags[index]);
672}
673
675 const bool *lock_flags,
676 const bool *selected,
677 int sel_tot)
678{
679 if (lock_flags == nullptr) {
680 return true;
681 }
682
683 if (selected == nullptr || sel_tot <= 1) {
684 return true;
685 }
686
687 for (int i = 0; i < defbase_tot; i++) {
688 if (selected[i] && lock_flags[i]) {
689 return false;
690 }
691 }
692
693 return true;
694}
695
697{
698 bDeformGroup *dg;
699 switch (ob->type) {
700 case OB_GREASE_PENCIL: {
701 GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
702 dg = static_cast<bDeformGroup *>(BLI_findlink(&grease_pencil->vertex_group_names,
703 grease_pencil->vertex_group_active_index - 1));
704 break;
705 }
706 default: {
707 Mesh *mesh = static_cast<Mesh *>(ob->data);
708 dg = static_cast<bDeformGroup *>(
709 BLI_findlink(&mesh->vertex_group_names, mesh->vertex_group_active_index - 1));
710 break;
711 }
712 }
713 return dg->flag & DG_LOCK_WEIGHT;
714}
715
717 int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
718{
719 if (!locked) {
720 if (r_unlocked != deform) {
721 memcpy(r_unlocked, deform, sizeof(bool) * defbase_tot);
722 }
723 if (r_locked) {
724 memset(r_locked, 0, sizeof(bool) * defbase_tot);
725 }
726 return;
727 }
728
729 for (int i = 0; i < defbase_tot; i++) {
730 bool is_locked = locked[i];
731 bool is_deform = deform[i];
732
733 r_locked[i] = is_deform && is_locked;
734 r_unlocked[i] = is_deform && !is_locked;
735 }
736}
737
739 int defbase_tot,
740 const bool *dg_selection,
741 bool *dg_flags_sel,
742 int *r_dg_flags_sel_tot)
743{
744 const ListBase *defbase = BKE_object_defgroup_list(ob);
745
746 bDeformGroup *defgroup;
747 uint i;
748 int i_mirr;
749
750 for (i = 0, defgroup = static_cast<bDeformGroup *>(defbase->first); i < defbase_tot && defgroup;
751 defgroup = defgroup->next, i++)
752 {
753 if (dg_selection[i]) {
754 char name_flip[MAXBONENAME];
755
756 BLI_string_flip_side_name(name_flip, defgroup->name, false, sizeof(name_flip));
757 i_mirr = STREQ(name_flip, defgroup->name) ? i :
758 BKE_object_defgroup_name_index(ob, name_flip);
759
760 if ((i_mirr >= 0 && i_mirr < defbase_tot) && (dg_flags_sel[i_mirr] == false)) {
761 dg_flags_sel[i_mirr] = true;
762 (*r_dg_flags_sel_tot) += 1;
763 }
764 }
765 }
766}
767
769 eVGroupSelect subset_type,
770 int *r_defgroup_tot,
771 int *r_subset_count)
772{
773 bool *defgroup_validmap = nullptr;
774
775 *r_defgroup_tot = BKE_object_defgroup_count(ob);
776
777 switch (subset_type) {
778 case WT_VGROUP_ACTIVE: {
779 const int def_nr_active = BKE_object_defgroup_active_index_get(ob) - 1;
780 defgroup_validmap = MEM_malloc_arrayN<bool>(size_t(*r_defgroup_tot), __func__);
781 memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
782 if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
783 *r_subset_count = 1;
784 defgroup_validmap[def_nr_active] = true;
785 }
786 else {
787 *r_subset_count = 0;
788 }
789 break;
790 }
792 defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
793 break;
794 }
796 int i;
797 defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
798 *r_subset_count = 0;
799 for (i = 0; i < *r_defgroup_tot; i++) {
800 if (defgroup_validmap[i] == true) {
801 *r_subset_count += 1;
802 }
803 }
804 break;
805 }
807 int i;
808 defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
809 *r_subset_count = 0;
810 for (i = 0; i < *r_defgroup_tot; i++) {
811 defgroup_validmap[i] = !defgroup_validmap[i];
812 if (defgroup_validmap[i] == true) {
813 *r_subset_count += 1;
814 }
815 }
816 break;
817 }
818 case WT_VGROUP_ALL:
819 default: {
820 defgroup_validmap = MEM_malloc_arrayN<bool>(size_t(*r_defgroup_tot), __func__);
821 memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
822 *r_subset_count = *r_defgroup_tot;
823 break;
824 }
825 }
826
827 return defgroup_validmap;
828}
829
830void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap,
831 const int defgroup_tot,
832 int *r_defgroup_subset_map)
833{
834 int i, j = 0;
835 for (i = 0; i < defgroup_tot; i++) {
836 if (defgroup_validmap[i]) {
837 r_defgroup_subset_map[j++] = i;
838 }
839 }
840}
Blender kernel action and pose functionality.
bPoseChannel * BKE_pose_channel_find_name(const bPose *pose, const char *name)
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
bool CustomData_free_layer_active(CustomData *data, eCustomDataType type)
support for deformation groups and hooks.
void BKE_object_defgroup_active_index_set(Object *ob, int new_index)
Definition deform.cc:612
int BKE_object_defgroup_active_index_get(const Object *ob)
Definition deform.cc:607
bDeformGroup * BKE_object_defgroup_new(Object *ob, blender::StringRef name)
Definition deform.cc:48
int BKE_object_defgroup_count(const Object *ob)
Definition deform.cc:602
const ListBase * BKE_object_defgroup_list(const Object *ob)
Definition deform.cc:585
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:806
ListBase * BKE_object_defgroup_list_mutable(Object *ob)
Definition deform.cc:596
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition deform.cc:880
int BKE_object_defgroup_name_index(const Object *ob, blender::StringRef name)
Definition deform.cc:591
Utility functions for vertex groups in grease pencil objects.
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
void BKE_object_batch_cache_dirty_tag(Object *ob)
Object * BKE_object_pose_armature_get(Object *ob)
bool BKE_object_is_in_editmode_vgroup(const Object *ob)
Functions for dealing with objects and deform verts, used by painting and tools.
#define BLI_assert(a)
Definition BLI_assert.h:46
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:745
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:702
GHash * BLI_ghash_str_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.cc:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.cc:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.cc:860
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_freelinkN(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:270
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
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
unsigned int uint
#define POINTER_FROM_INT(i)
#define ELEM(...)
#define STREQ(a, b)
#define DATA_(msgid)
@ ID_ME
@ ID_LT
@ ID_GP
@ POSE_SELECTED
#define MAXBONENAME
@ BONE_NO_DEFORM
@ CD_MDEFORMVERT
@ eModifierMode_Virtual
@ eModifierMode_Realtime
@ eModifierType_Explode
@ eModifierType_GreasePencilArmature
@ eModifierType_Cloth
@ eModifierType_Armature
Object is a sort of wrapper for general info.
@ DG_LOCK_WEIGHT
@ OB_LATTICE
@ OB_GREASE_PENCIL
@ OB_MESH
#define OB_TYPE_SUPPORT_VGROUP(_type)
@ PSYS_TOT_VG
eVGroupSelect
@ WT_VGROUP_BONE_SELECT
@ WT_VGROUP_ALL
@ WT_VGROUP_BONE_DEFORM_OFF
@ WT_VGROUP_ACTIVE
@ WT_VGROUP_BONE_DEFORM
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
@ BM_ELEM_SELECT
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
#define SELECT
#define GS(x)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
void clear_vertex_groups(GreasePencil &grease_pencil)
void validate_drawing_vertex_groups(GreasePencil &grease_pencil)
bool BKE_object_defgroup_check_lock_relative(const bool *lock_flags, const bool *validmap, int index)
bool * BKE_object_defgroup_subset_from_select_type(Object *ob, eVGroupSelect subset_type, int *r_defgroup_tot, int *r_subset_count)
void BKE_object_defgroup_mirror_selection(Object *ob, int defbase_tot, const bool *dg_selection, bool *dg_flags_sel, int *r_dg_flags_sel_tot)
bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
void BKE_object_defgroup_split_locked_validmap(int defbase_tot, const bool *locked, const bool *deform, bool *r_locked, bool *r_unlocked)
static void object_defgroup_remove_update_users(Object *ob, const int idx)
bool * BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap, const int defgroup_tot, int *r_defgroup_subset_map)
bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
bool * BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
int * BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
bool BKE_object_defgroup_active_is_locked(const Object *ob)
static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
bool BKE_object_defgroup_check_lock_relative_multi(int defbase_tot, const bool *lock_flags, const bool *selected, int sel_tot)
void BKE_object_defgroup_index_map_apply(MDeformVert *dvert, int dvert_len, const int *map, int map_len)
bool * BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked)
void BKE_object_defgroup_remap_update_users(Object *ob, const int *map)
bDeformGroup * BKE_object_defgroup_add(Object *ob)
void BKE_object_defgroup_remove_all(Object *ob)
static Lattice * object_defgroup_lattice_get(ID *id)
void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
bDeformGroup * BKE_object_defgroup_add_name(Object *ob, const char *name)
MDeformVert * BKE_object_defgroup_data_create(ID *id)
const char * name
CustomData vdata
uint8_t f1
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct Lattice * latt
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct MDeformVert * dvert
struct EditLatt * editlatt
struct BPoint * def
void * first
struct MDeformWeight * dw
unsigned int def_nr
struct ModifierData * next
ListBase particlesystem
struct bPose * pose
ListBase modifiers
struct SoftBody * soft
struct bDeformGroup * next
ListBase chanbase
i
Definition text_draw.cc:230