Blender V4.3
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
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"
26#include "DNA_lattice_types.h"
27#include "DNA_mesh_types.h"
28#include "DNA_meshdata_types.h"
29#include "DNA_modifier_types.h"
31#include "DNA_object_types.h"
32#include "DNA_particle_types.h"
33#include "DNA_scene_types.h"
34
35#include "BKE_action.hh"
36#include "BKE_deform.hh"
37#include "BKE_editmesh.hh"
38#include "BKE_gpencil_legacy.h"
40#include "BKE_mesh.hh"
41#include "BKE_modifier.hh"
42#include "BKE_object.hh"
43#include "BKE_object_deform.h" /* own include */
44
45/* -------------------------------------------------------------------- */
50{
51 Lattice *lt = (Lattice *)id;
52 BLI_assert(GS(id->name) == ID_LT);
53 return (lt->editlatt) ? lt->editlatt->latt : lt;
54}
55
57{
58 /* these cases don't use names to refer to vertex groups, so when
59 * they get removed the numbers get out of sync, this corrects that */
60
61 if (ob->soft) {
62 ob->soft->vertgroup = map[ob->soft->vertgroup];
63 }
64
66 if (md->type == eModifierType_Explode) {
68 emd->vgroup = map[emd->vgroup];
69 }
70 else if (md->type == eModifierType_Cloth) {
72 ClothSimSettings *clsim = clmd->sim_parms;
73 ClothCollSettings *clcoll = clmd->coll_parms;
74
75 if (clsim) {
76 clsim->vgroup_mass = map[clsim->vgroup_mass];
77 clsim->vgroup_shrink = map[clsim->vgroup_shrink];
78 clsim->vgroup_struct = map[clsim->vgroup_struct];
79 clsim->vgroup_shear = map[clsim->vgroup_shear];
80 clsim->vgroup_bend = map[clsim->vgroup_bend];
81 clsim->vgroup_intern = map[clsim->vgroup_intern];
82 clsim->vgroup_pressure = map[clsim->vgroup_pressure];
83 clcoll->vgroup_selfcol = map[clcoll->vgroup_selfcol];
84 clcoll->vgroup_objcol = map[clcoll->vgroup_objcol];
85 }
86 }
87 }
88
90 for (int a = 0; a < PSYS_TOT_VG; a++) {
91 psys->vgroup[a] = map[psys->vgroup[a]];
92 }
93 }
94}
95
98/* -------------------------------------------------------------------- */
103{
104 bDeformGroup *defgroup;
105
106 if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) {
107 return nullptr;
108 }
109
110 defgroup = BKE_object_defgroup_new(ob, name);
112
113 return defgroup;
114}
115
120
122{
123 if (GS(id->name) == ID_ME) {
124 return ((Mesh *)id)->deform_verts_for_write().data();
125 }
126 if (GS(id->name) == ID_LT) {
127 Lattice *lt = (Lattice *)id;
128 lt->dvert = static_cast<MDeformVert *>(MEM_callocN(
129 sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"));
130 return lt->dvert;
131 }
132
133 return nullptr;
134}
135
138/* -------------------------------------------------------------------- */
142bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
143{
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 bool *select_vert = (const bool *)CustomData_get_layer_named(
173 &mesh->vert_data, CD_PROP_BOOL, ".select_vert");
174 int i;
175
176 dv = mesh->deform_verts_for_write().data();
177
178 for (i = 0; i < mesh->verts_num; i++, dv++) {
179 if (dv->dw && (!use_selection || (select_vert && select_vert[i]))) {
180 MDeformWeight *dw = BKE_defvert_find_index(dv, def_nr);
181 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
182 changed = true;
183 }
184 }
185 }
186 }
187 }
188 else if (ob->type == OB_LATTICE) {
190
191 if (lt->dvert) {
192 BPoint *bp;
193 int i, tot = lt->pntsu * lt->pntsv * lt->pntsw;
194
195 for (i = 0, bp = lt->def; i < tot; i++, bp++) {
196 if (!use_selection || (bp->f1 & SELECT)) {
197 MDeformWeight *dw;
198
199 dv = &lt->dvert[i];
200
201 dw = BKE_defvert_find_index(dv, def_nr);
202 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
203 changed = true;
204 }
205 }
206 }
207 }
208
209 return changed;
210}
211
212bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
213{
214 bool changed = false;
215
216 const ListBase *defbase = BKE_object_defgroup_list(ob);
217
218 LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
219 if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
220 changed = true;
221 }
222 }
223
224 return changed;
225}
226
229/* -------------------------------------------------------------------- */
233static void object_defgroup_remove_update_users(Object *ob, const int idx)
234{
235 int i, defbase_tot = BKE_object_defgroup_count(ob) + 1;
236 int *map = static_cast<int *>(MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del"));
237
238 map[idx] = map[0] = 0;
239 for (i = 1; i < idx; i++) {
240 map[i] = i;
241 }
242 for (i = idx + 1; i < defbase_tot; i++) {
243 map[i] = i - 1;
244 }
245
247 MEM_freeN(map);
248}
249
250static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const int def_nr)
251{
253
254 /* Remove the group */
256
257 BLI_freelinkN(defbase, dg);
258
259 /* Update the active deform index if necessary */
260 const int active_index = BKE_object_defgroup_active_index_get(ob);
261 if (active_index > def_nr) {
262 BKE_object_defgroup_active_index_set(ob, active_index - 1);
263 }
264
265 /* Remove all deform-verts. */
266 if (BLI_listbase_is_empty(defbase)) {
267 if (ob->type == OB_MESH) {
268 Mesh *mesh = static_cast<Mesh *>(ob->data);
269 CustomData_free_layer_active(&mesh->vert_data, CD_MDEFORMVERT, mesh->verts_num);
270 }
271 else if (ob->type == OB_LATTICE) {
273 MEM_SAFE_FREE(lt->dvert);
274 }
275 else if (ob->type == OB_GREASE_PENCIL) {
276 GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
278 }
279 }
280 else if (BKE_object_defgroup_active_index_get(ob) < 1) {
281 /* Keep a valid active index if we still have some vgroups. */
283 }
284}
285
287{
288 MDeformVert *dvert_array = nullptr;
289 int dvert_tot = 0;
290 const ListBase *defbase = BKE_object_defgroup_list(ob);
291
292 const int def_nr = BLI_findindex(defbase, dg);
293
294 BLI_assert(def_nr != -1);
295
296 BKE_object_defgroup_array_get(static_cast<ID *>(ob->data), &dvert_array, &dvert_tot);
297
298 if (dvert_array) {
299 int i, j;
300 MDeformVert *dv;
301 for (i = 0, dv = dvert_array; i < dvert_tot; i++, dv++) {
302 MDeformWeight *dw;
303
304 dw = BKE_defvert_find_index(dv, def_nr);
305 BKE_defvert_remove_group(dv, dw); /* dw can be nullptr */
306
307 /* inline, make into a function if anything else needs to do this */
308 for (j = 0; j < dv->totweight; j++) {
309 if (dv->dw[j].def_nr > def_nr) {
310 dv->dw[j].def_nr--;
311 }
312 }
313 /* done */
314 }
315 }
316
317 object_defgroup_remove_common(ob, dg, def_nr);
318}
319
321{
322 int i;
323 const ListBase *defbase = BKE_object_defgroup_list(ob);
324 const int def_nr = BLI_findindex(defbase, dg);
325
326 BLI_assert(def_nr != -1);
327
328 /* Make sure that no verts are using this group - if none were removed,
329 * we can skip next per-vert update. */
330 if (!BKE_object_defgroup_clear(ob, dg, false)) {
331 /* Nothing to do. */
332 }
333 /* Else, make sure that any groups with higher indices are adjusted accordingly */
334 else if (ob->type == OB_MESH) {
335 Mesh *mesh = static_cast<Mesh *>(ob->data);
336 BMEditMesh *em = mesh->runtime->edit_mesh.get();
337 const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
338
339 BMIter iter;
340 BMVert *eve;
341 MDeformVert *dvert;
342
343 BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
344 dvert = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
345
346 if (dvert) {
347 for (i = 0; i < dvert->totweight; i++) {
348 if (dvert->dw[i].def_nr > def_nr) {
349 dvert->dw[i].def_nr--;
350 }
351 }
352 }
353 }
354 }
355 else if (ob->type == OB_LATTICE) {
356 Lattice *lt = ((Lattice *)(ob->data))->editlatt->latt;
357 BPoint *bp;
358 MDeformVert *dvert = lt->dvert;
359 int a, tot;
360
361 if (dvert) {
362 tot = lt->pntsu * lt->pntsv * lt->pntsw;
363 for (a = 0, bp = lt->def; a < tot; a++, bp++, dvert++) {
364 for (i = 0; i < dvert->totweight; i++) {
365 if (dvert->dw[i].def_nr > def_nr) {
366 dvert->dw[i].def_nr--;
367 }
368 }
369 }
370 }
371 }
372
373 object_defgroup_remove_common(ob, dg, def_nr);
374}
375
377{
380 }
381 else {
383 }
384
385 if (ob->type == OB_GREASE_PENCIL) {
387 *static_cast<GreasePencil *>(ob->data));
388 }
389
391}
392
393void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked)
394{
396
397 bDeformGroup *dg = (bDeformGroup *)defbase->first;
398 const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
399
400 if (dg) {
401 while (dg) {
402 bDeformGroup *next_dg = dg->next;
403
404 if (!only_unlocked || (dg->flag & DG_LOCK_WEIGHT) == 0) {
405 if (edit_mode) {
407 }
408 else {
410 }
411 }
412
413 dg = next_dg;
414 }
415 }
416 else { /* `defbase` is empty. */
417 /* Remove all deform-verts. */
418 if (ob->type == OB_MESH) {
419 Mesh *mesh = static_cast<Mesh *>(ob->data);
420 CustomData_free_layer_active(&mesh->vert_data, CD_MDEFORMVERT, mesh->verts_num);
421 }
422 else if (ob->type == OB_LATTICE) {
424 MEM_SAFE_FREE(lt->dvert);
425 }
426 else if (ob->type == OB_GREASE_PENCIL) {
427 GreasePencil *grease_pencil = static_cast<GreasePencil *>(ob->data);
429 }
430 /* Fix counters/indices */
432 }
433}
434
439
440int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
441{
442 const ListBase *src_defbase = BKE_object_defgroup_list(ob_src);
443 const ListBase *dst_defbase = BKE_object_defgroup_list(ob_dst);
444
445 /* Build src to merged mapping of vgroup indices. */
446 if (BLI_listbase_is_empty(src_defbase) || BLI_listbase_is_empty(dst_defbase)) {
447 *r_map_len = 0;
448 return nullptr;
449 }
450
451 bDeformGroup *dg_src;
452 *r_map_len = BLI_listbase_count(src_defbase);
453 int *vgroup_index_map = static_cast<int *>(
454 MEM_malloc_arrayN(*r_map_len, sizeof(*vgroup_index_map), "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. */
528 break;
529 default:
530 break;
531 }
532 }
533
534 *dvert_arr = nullptr;
535 *dvert_tot = 0;
536 return false;
537}
538
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 = static_cast<bool *>(MEM_mallocN(defbase_tot * sizeof(bool), "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
598 if (md->type == eModifierType_Armature) {
600
601 if (amd->object && amd->object->pose) {
602 bPose *pose = amd->object->pose;
603
604 LISTBASE_FOREACH (bPoseChannel *, chan, &pose->chanbase) {
605 void **val_p;
606 if (chan->bone->flag & BONE_NO_DEFORM) {
607 continue;
608 }
609
610 val_p = BLI_ghash_lookup_p(gh, chan->name);
611 if (val_p) {
612 *val_p = POINTER_FROM_INT(1);
613 }
614 }
615 }
616 }
617 }
618
619 defgroup_validmap = static_cast<bool *>(
620 MEM_mallocN(sizeof(*defgroup_validmap) * 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 = static_cast<bool *>(MEM_mallocN(defbase_tot * sizeof(bool), __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->bone->flag & BONE_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 = static_cast<bool *>(
781 MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__));
782 memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
783 if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {
784 *r_subset_count = 1;
785 defgroup_validmap[def_nr_active] = true;
786 }
787 else {
788 *r_subset_count = 0;
789 }
790 break;
791 }
793 defgroup_validmap = BKE_object_defgroup_selected_get(ob, *r_defgroup_tot, r_subset_count);
794 break;
795 }
797 int i;
798 defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
799 *r_subset_count = 0;
800 for (i = 0; i < *r_defgroup_tot; i++) {
801 if (defgroup_validmap[i] == true) {
802 *r_subset_count += 1;
803 }
804 }
805 break;
806 }
808 int i;
809 defgroup_validmap = BKE_object_defgroup_validmap_get(ob, *r_defgroup_tot);
810 *r_subset_count = 0;
811 for (i = 0; i < *r_defgroup_tot; i++) {
812 defgroup_validmap[i] = !defgroup_validmap[i];
813 if (defgroup_validmap[i] == true) {
814 *r_subset_count += 1;
815 }
816 }
817 break;
818 }
819 case WT_VGROUP_ALL:
820 default: {
821 defgroup_validmap = static_cast<bool *>(
822 MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__));
823 memset(defgroup_validmap, true, *r_defgroup_tot * sizeof(*defgroup_validmap));
824 *r_subset_count = *r_defgroup_tot;
825 break;
826 }
827 }
828
829 return defgroup_validmap;
830}
831
832void BKE_object_defgroup_subset_to_index_array(const bool *defgroup_validmap,
833 const int defgroup_tot,
834 int *r_defgroup_subset_map)
835{
836 int i, j = 0;
837 for (i = 0; i < defgroup_tot; i++) {
838 if (defgroup_validmap[i]) {
839 r_defgroup_subset_map[j++] = i;
840 }
841 }
842}
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)
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool CustomData_free_layer_active(CustomData *data, eCustomDataType type, int totelem)
support for deformation groups and hooks.
void BKE_object_defgroup_active_index_set(Object *ob, int new_index)
Definition deform.cc:606
int BKE_object_defgroup_active_index_get(const Object *ob)
Definition deform.cc:601
bDeformGroup * BKE_object_defgroup_new(Object *ob, blender::StringRef name)
Definition deform.cc:51
int BKE_object_defgroup_count(const Object *ob)
Definition deform.cc:596
const ListBase * BKE_object_defgroup_list(const Object *ob)
Definition deform.cc:579
MDeformWeight * BKE_defvert_find_index(const MDeformVert *dv, int defgroup)
Definition deform.cc:795
ListBase * BKE_object_defgroup_list_mutable(Object *ob)
Definition deform.cc:590
void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
Definition deform.cc:871
int BKE_object_defgroup_name_index(const Object *ob, blender::StringRef name)
Definition deform.cc:585
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_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
void ** BLI_ghash_lookup_p(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:745
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c: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.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
#define LISTBASE_FOREACH(type, var, list)
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:269
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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 STREQ(a, b)
#define DATA_(msgid)
@ ID_ME
@ ID_LT
@ ID_GP
#define MAXBONENAME
@ BONE_SELECTED
@ BONE_NO_DEFORM
@ CD_MDEFORMVERT
@ eModifierMode_Virtual
@ eModifierMode_Realtime
@ eModifierType_Explode
@ eModifierType_Cloth
@ eModifierType_Armature
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_GREASE_PENCIL
@ OB_MESH
@ DG_LOCK_WEIGHT
#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
#define SELECT
#define GS(x)
Definition iris.cc:202
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition mallocn.cc:45
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
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)
CustomData vdata
uint8_t f1
struct ClothSimSettings * sim_parms
struct ClothCollSettings * coll_parms
struct Lattice * latt
Definition DNA_ID.h:413
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
struct Bone * bone
ListBase chanbase