Blender  V3.3
gpencil_armature.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2018 Blender Foundation. */
3 
10 #include <math.h>
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include "MEM_guardedalloc.h"
17 
18 #include "BLI_math.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_armature_types.h"
22 #include "DNA_gpencil_types.h"
23 #include "DNA_meshdata_types.h"
24 #include "DNA_scene_types.h"
25 
26 #include "BKE_action.h"
27 #include "BKE_armature.h"
28 #include "BKE_context.h"
29 #include "BKE_deform.h"
30 #include "BKE_gpencil.h"
31 #include "BKE_gpencil_modifier.h"
32 #include "BKE_main.h"
33 #include "BKE_object_deform.h"
34 #include "BKE_report.h"
35 
36 #include "WM_api.h"
37 #include "WM_types.h"
38 
39 #include "RNA_access.h"
40 #include "RNA_define.h"
41 #include "RNA_enum_types.h"
42 
43 #include "ED_gpencil.h"
44 #include "ED_mesh.h"
45 #include "ED_object.h"
46 
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_query.h"
49 
50 #include "gpencil_intern.h"
51 
52 enum {
55 };
56 
57 #define DEFAULT_RATIO 0.10f
58 #define DEFAULT_DECAY 0.8f
59 
60 static int gpencil_bone_looper(Object *ob,
61  Bone *bone,
62  void *data,
63  int (*bone_func)(Object *, Bone *, void *))
64 {
65  /* We want to apply the function bone_func to every bone
66  * in an armature -- feed bone_looper the first bone and
67  * a pointer to the bone_func and watch it go! The int count
68  * can be useful for counting bones with a certain property
69  * (e.g. skinnable)
70  */
71  int count = 0;
72 
73  if (bone) {
74  /* only do bone_func if the bone is non null */
75  count += bone_func(ob, bone, data);
76 
77  /* try to execute bone_func for the first child */
78  count += gpencil_bone_looper(ob, bone->childbase.first, data, bone_func);
79 
80  /* try to execute bone_func for the next bone at this
81  * depth of the recursion.
82  */
83  count += gpencil_bone_looper(ob, bone->next, data, bone_func);
84  }
85 
86  return count;
87 }
88 
89 static int gpencil_bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
90 {
91  /* Bones that are deforming
92  * are regarded to be "skinnable" and are eligible for
93  * auto-skinning.
94  *
95  * This function performs 2 functions:
96  *
97  * a) It returns 1 if the bone is skinnable.
98  * If we loop over all bones with this
99  * function, we can count the number of
100  * skinnable bones.
101  * b) If the pointer data is non null,
102  * it is treated like a handle to a
103  * bone pointer -- the bone pointer
104  * is set to point at this bone, and
105  * the pointer the handle points to
106  * is incremented to point to the
107  * next member of an array of pointers
108  * to bones. This way we can loop using
109  * this function to construct an array of
110  * pointers to bones that point to all
111  * skinnable bones.
112  */
113  Bone ***hbone;
114  int a, segments;
115  struct {
116  Object *armob;
117  void *list;
118  int heat;
119  } *data = datap;
120 
121  if (!(bone->flag & BONE_HIDDEN_P)) {
122  if (!(bone->flag & BONE_NO_DEFORM)) {
123  if (data->heat && data->armob->pose &&
124  BKE_pose_channel_find_name(data->armob->pose, bone->name)) {
125  segments = bone->segments;
126  }
127  else {
128  segments = 1;
129  }
130 
131  if (data->list != NULL) {
132  hbone = (Bone ***)&data->list;
133 
134  for (a = 0; a < segments; a++) {
135  **hbone = bone;
136  (*hbone)++;
137  }
138  }
139  return segments;
140  }
141  }
142  return 0;
143 }
144 
145 static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
146 {
147  /* This group creates a vertex group to ob that has the
148  * same name as bone (provided the bone is skinnable).
149  * If such a vertex group already exist the routine exits.
150  */
151  if (!(bone->flag & BONE_NO_DEFORM)) {
152  if (!BKE_object_defgroup_find_name(ob, bone->name)) {
154  return 1;
155  }
156  }
157  return 0;
158 }
159 
160 static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
161 {
162  /* Bones that are deforming
163  * are regarded to be "skinnable" and are eligible for
164  * auto-skinning.
165  *
166  * This function performs 2 functions:
167  *
168  * a) If the bone is skinnable, it creates
169  * a vertex group for ob that has
170  * the name of the skinnable bone
171  * (if one doesn't exist already).
172  * b) If the pointer data is non null,
173  * it is treated like a handle to a
174  * bDeformGroup pointer -- the
175  * bDeformGroup pointer is set to point
176  * to the deform group with the bone's
177  * name, and the pointer the handle
178  * points to is incremented to point to the
179  * next member of an array of pointers
180  * to bDeformGroups. This way we can loop using
181  * this function to construct an array of
182  * pointers to bDeformGroups, all with names
183  * of skinnable bones.
184  */
185  bDeformGroup ***hgroup, *defgroup = NULL;
186  int a, segments;
187  struct {
188  Object *armob;
189  void *list;
190  int heat;
191  } *data = datap;
192  bArmature *arm = data->armob->data;
193 
194  if (!(bone->flag & BONE_HIDDEN_P)) {
195  if (!(bone->flag & BONE_NO_DEFORM)) {
196  if (data->heat && data->armob->pose &&
197  BKE_pose_channel_find_name(data->armob->pose, bone->name)) {
198  segments = bone->segments;
199  }
200  else {
201  segments = 1;
202  }
203 
204  if (arm->layer & bone->layer) {
205  if (!(defgroup = BKE_object_defgroup_find_name(ob, bone->name))) {
206  defgroup = BKE_object_defgroup_add_name(ob, bone->name);
207  }
208  else if (defgroup->flag & DG_LOCK_WEIGHT) {
209  /* In case vgroup already exists and is locked, do not modify it here. See T43814. */
210  defgroup = NULL;
211  }
212  }
213 
214  if (data->list != NULL) {
215  hgroup = (bDeformGroup ***)&data->list;
216 
217  for (a = 0; a < segments; a++) {
218  **hgroup = defgroup;
219  (*hgroup)++;
220  }
221  }
222  return segments;
223  }
224  }
225  return 0;
226 }
227 
228 /* get weight value depending of distance and decay value */
229 static float get_weight(float dist, float decay_rad, float dif_rad)
230 {
231  float weight = 1.0f;
232  if (dist < decay_rad) {
233  weight = 1.0f;
234  }
235  else {
236  weight = interpf(0.0f, 0.9f, (dist - decay_rad) / dif_rad);
237  }
238 
239  return weight;
240 }
241 
242 /* This functions implements the automatic computation of vertex group weights */
244  const bContext *C, Object *ob, Object *ob_arm, const float ratio, const float decay)
245 {
246  bArmature *arm = ob_arm->data;
247  Bone **bonelist, *bone;
248  bDeformGroup **dgrouplist;
249  bPoseChannel *pchan;
250  bGPdata *gpd = (bGPdata *)ob->data;
251  const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
252 
253  Mat4 bbone_array[MAX_BBONE_SUBDIV], *bbone = NULL;
254  float(*root)[3], (*tip)[3], (*verts)[3];
255  float *radsqr;
256  int *selected;
257  float weight;
258  int numbones, i, j, segments = 0;
259  struct {
260  Object *armob;
261  void *list;
262  int heat;
263  } looper_data;
264 
265  looper_data.armob = ob_arm;
266  looper_data.heat = true;
267  looper_data.list = NULL;
268 
269  /* count the number of skinnable bones */
270  numbones = gpencil_bone_looper(ob, arm->bonebase.first, &looper_data, gpencil_bone_skinnable_cb);
271 
272  if (numbones == 0) {
273  return;
274  }
275 
276  /* create an array of pointer to bones that are skinnable
277  * and fill it with all of the skinnable bones */
278  bonelist = MEM_callocN(numbones * sizeof(Bone *), "bonelist");
279  looper_data.list = bonelist;
281 
282  /* create an array of pointers to the deform groups that
283  * correspond to the skinnable bones (creating them
284  * as necessary. */
285  dgrouplist = MEM_callocN(numbones * sizeof(bDeformGroup *), "dgrouplist");
286 
287  looper_data.list = dgrouplist;
288  gpencil_bone_looper(ob, arm->bonebase.first, &looper_data, dgroup_skinnable_cb);
289 
290  /* create an array of root and tip positions transformed into
291  * global coords */
292  root = MEM_callocN(sizeof(float[3]) * numbones, "root");
293  tip = MEM_callocN(sizeof(float[3]) * numbones, "tip");
294  selected = MEM_callocN(sizeof(int) * numbones, "selected");
295  radsqr = MEM_callocN(sizeof(float) * numbones, "radsqr");
296 
297  for (j = 0; j < numbones; j++) {
298  bone = bonelist[j];
299 
300  /* handle bbone */
301  if (segments == 0) {
302  segments = 1;
303  bbone = NULL;
304 
305  if ((ob_arm->pose) && (pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name))) {
306  if (bone->segments > 1) {
307  segments = bone->segments;
308  BKE_pchan_bbone_spline_setup(pchan, true, false, bbone_array);
309  bbone = bbone_array;
310  }
311  }
312  }
313 
314  segments--;
315 
316  /* compute root and tip */
317  if (bbone) {
318  mul_v3_m4v3(root[j], bone->arm_mat, bbone[segments].mat[3]);
319  if ((segments + 1) < bone->segments) {
320  mul_v3_m4v3(tip[j], bone->arm_mat, bbone[segments + 1].mat[3]);
321  }
322  else {
323  copy_v3_v3(tip[j], bone->arm_tail);
324  }
325  }
326  else {
327  copy_v3_v3(root[j], bone->arm_head);
328  copy_v3_v3(tip[j], bone->arm_tail);
329  }
330 
331  mul_m4_v3(ob_arm->obmat, root[j]);
332  mul_m4_v3(ob_arm->obmat, tip[j]);
333 
334  selected[j] = 1;
335 
336  /* calculate radius squared */
337  radsqr[j] = len_squared_v3v3(root[j], tip[j]) * ratio;
338  }
339 
340  /* loop all strokes */
341  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
342  bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
343  bGPDspoint *pt = NULL;
344 
345  for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
346  if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
347 
348  if (gpf == NULL) {
349  continue;
350  }
351 
352  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
353  /* skip strokes that are invalid for current view */
354  if (ED_gpencil_stroke_can_use(C, gps) == false) {
355  continue;
356  }
357 
359 
360  /* create verts array */
361  verts = MEM_callocN(gps->totpoints * sizeof(*verts), __func__);
362 
363  /* transform stroke points to global space */
364  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
365  copy_v3_v3(verts[i], &pt->x);
366  mul_m4_v3(ob->obmat, verts[i]);
367  }
368 
369  /* loop groups and assign weight */
370  for (j = 0; j < numbones; j++) {
371  int def_nr = BLI_findindex(&gpd->vertex_group_names, dgrouplist[j]);
372  if (def_nr < 0) {
373  continue;
374  }
375 
376  float decay_rad = radsqr[j] - (radsqr[j] * decay);
377  float dif_rad = radsqr[j] - decay_rad;
378 
379  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
380  MDeformVert *dvert = &gps->dvert[i];
381  float dist = dist_squared_to_line_segment_v3(verts[i], root[j], tip[j]);
382  if (dist > radsqr[j]) {
383  /* if not in cylinder, check if inside extreme spheres */
384  weight = 0.0f;
385  dist = len_squared_v3v3(root[j], verts[i]);
386  if (dist < radsqr[j]) {
387  weight = get_weight(dist, decay_rad, dif_rad);
388  }
389  else {
390  dist = len_squared_v3v3(tip[j], verts[i]);
391  if (dist < radsqr[j]) {
392  weight = get_weight(dist, decay_rad, dif_rad);
393  }
394  }
395  }
396  else {
397  /* inside bone cylinder */
398  weight = get_weight(dist, decay_rad, dif_rad);
399  }
400 
401  /* assign weight */
402  MDeformWeight *dw = BKE_defvert_ensure_index(dvert, def_nr);
403  if (dw) {
404  dw->weight = weight;
405  }
406  }
407  }
409  }
410  }
411 
412  /* If not multi-edit, exit loop. */
413  if (!is_multiedit) {
414  break;
415  }
416  }
417  }
418 
419  /* free the memory allocated */
420  MEM_SAFE_FREE(bonelist);
421  MEM_SAFE_FREE(dgrouplist);
422  MEM_SAFE_FREE(root);
423  MEM_SAFE_FREE(tip);
424  MEM_SAFE_FREE(radsqr);
425  MEM_SAFE_FREE(selected);
426 }
427 
429  Object *ob,
430  Object *ob_arm,
431  const int mode,
432  const float ratio,
433  const float decay)
434 {
435  /* Lets try to create some vertex groups
436  * based on the bones of the parent armature.
437  */
438  bArmature *arm = ob_arm->data;
439 
440  /* always create groups */
441  const int defbase_tot = BKE_object_defgroup_count(ob);
442  int defbase_add;
443  /* Traverse the bone list, trying to create empty vertex
444  * groups corresponding to the bone.
445  */
447 
448  if (defbase_add) {
449  /* It's possible there are DWeights outside the range of the current
450  * object's deform groups. In this case the new groups won't be empty */
451  ED_vgroup_data_clamp_range(ob->data, defbase_tot);
452  }
453 
454  if (mode == GP_ARMATURE_AUTO) {
455  /* Traverse the bone list, trying to fill vertex groups
456  * with the corresponding vertex weights for which the
457  * bone is closest.
458  */
459  gpencil_add_verts_to_dgroups(C, ob, ob_arm, ratio, decay);
460  }
461 
463 }
464 
465 bool ED_gpencil_add_armature(const bContext *C, ReportList *reports, Object *ob, Object *ob_arm)
466 {
467  Main *bmain = CTX_data_main(C);
469 
470  if (ob == NULL) {
471  return false;
472  }
473 
474  /* if no armature modifier, add a new one */
476  if (md == NULL) {
478  reports, bmain, scene, ob, "Armature", eGpencilModifierType_Armature);
479  if (md == NULL) {
480  BKE_report(reports, RPT_ERROR, "Unable to add a new Armature modifier to object");
481  return false;
482  }
484  }
485 
486  /* verify armature */
488  if (mmd->object == NULL) {
489  mmd->object = ob_arm;
490  }
491  else {
492  if (ob_arm != mmd->object) {
493  BKE_report(reports,
494  RPT_ERROR,
495  "The existing Armature modifier is already using a different Armature object");
496  return false;
497  }
498  }
499  return true;
500 }
501 
503  const bContext *C, ReportList *reports, Object *ob, Object *ob_arm, int mode)
504 {
505  if (ob == NULL) {
506  return false;
507  }
508 
509  bool success = ED_gpencil_add_armature(C, reports, ob, ob_arm);
510 
511  /* add weights */
512  if (success) {
514  }
515 
516  return success;
517 }
518 /* ***************** Generate armature weights ************************** */
520 {
522 
523  if (ob == NULL) {
524  return false;
525  }
526 
527  if (ob->type != OB_GPENCIL) {
528  return false;
529  }
530 
531  ViewLayer *view_layer = CTX_data_view_layer(C);
532  bGPdata *gpd = (bGPdata *)ob->data;
533 
534  if (BLI_listbase_count(&gpd->layers) == 0) {
535  return false;
536  }
537 
538  /* need some armature in the view layer */
539  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
540  if (base->object->type == OB_ARMATURE) {
541  return true;
542  }
543  }
544 
545  return false;
546 }
547 
549 {
551  ViewLayer *view_layer = CTX_data_view_layer(C);
553  Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
554  bGPdata *gpd = (bGPdata *)ob->data;
555  Object *ob_arm = NULL;
556 
557  const int mode = RNA_enum_get(op->ptr, "mode");
558  const float ratio = RNA_float_get(op->ptr, "ratio");
559  const float decay = RNA_float_get(op->ptr, "decay");
560 
561  /* sanity checks */
562  if (ELEM(NULL, ob, gpd)) {
563  return OPERATOR_CANCELLED;
564  }
565 
566  /* get armature */
567  const int arm_idx = RNA_enum_get(op->ptr, "armature");
568  if (arm_idx > 0) {
569  Base *base = BLI_findlink(&view_layer->object_bases, arm_idx - 1);
570  ob_arm = base->object;
571  }
572  else {
573  /* get armature from modifier */
576  if (md == NULL) {
577  BKE_report(op->reports, RPT_ERROR, "The grease pencil object need an Armature modifier");
578  return OPERATOR_CANCELLED;
579  }
580 
582  if (mmd->object == NULL) {
583  BKE_report(op->reports, RPT_ERROR, "Armature modifier is not valid or wrong defined");
584  return OPERATOR_CANCELLED;
585  }
586 
587  ob_arm = mmd->object;
588  }
589 
590  if (ob_arm == NULL) {
591  BKE_report(op->reports, RPT_ERROR, "No Armature object in the view layer");
592  return OPERATOR_CANCELLED;
593  }
594 
595  gpencil_object_vgroup_calc_from_armature(C, ob, ob_arm, mode, ratio, decay);
596 
597  /* notifiers */
600 
601  return OPERATOR_FINISHED;
602 }
603 
604 /* Dynamically populate an enum of Armatures */
607  PropertyRNA *UNUSED(prop),
608  bool *r_free)
609 {
610  ViewLayer *view_layer = CTX_data_view_layer(C);
611  EnumPropertyItem *item = NULL, item_tmp = {0};
612  int totitem = 0;
613  int i = 0;
614 
615  if (C == NULL) {
616  return DummyRNA_DEFAULT_items;
617  }
618 
619  /* add default */
620  item_tmp.identifier = "DEFAULT";
621  item_tmp.name = "Default";
622  item_tmp.value = 0;
623  RNA_enum_item_add(&item, &totitem, &item_tmp);
624  i++;
625 
626  LISTBASE_FOREACH (Base *, base, &view_layer->object_bases) {
627  Object *ob = base->object;
628  if (ob->type == OB_ARMATURE) {
629  item_tmp.identifier = item_tmp.name = ob->id.name + 2;
630  item_tmp.value = i;
631  RNA_enum_item_add(&item, &totitem, &item_tmp);
632  }
633  i++;
634  }
635 
636  RNA_enum_item_end(&item, &totitem);
637  *r_free = true;
638 
639  return item;
640 }
641 
643 {
644  static const EnumPropertyItem mode_type[] = {
645  {GP_ARMATURE_NAME, "NAME", 0, "Empty Groups", ""},
646  {GP_ARMATURE_AUTO, "AUTO", 0, "Automatic Weights", ""},
647  {0, NULL, 0, NULL, NULL},
648  };
649 
650  PropertyRNA *prop;
651 
652  /* identifiers */
653  ot->name = "Generate Automatic Weights";
654  ot->idname = "GPENCIL_OT_generate_weights";
655  ot->description = "Generate automatic weights for armatures (requires armature modifier)";
656 
658 
659  /* callbacks */
662 
663  ot->prop = RNA_def_enum(ot->srna, "mode", mode_type, 0, "Mode", "");
664 
665  prop = RNA_def_enum(
666  ot->srna, "armature", DummyRNA_DEFAULT_items, 0, "Armature", "Armature to use");
668 
670  "ratio",
672  0.0f,
673  2.0f,
674  "Ratio",
675  "Ratio between bone length and influence radius",
676  0.001f,
677  1.0f);
678 
680  "decay",
682  0.0f,
683  1.0f,
684  "Decay",
685  "Factor to reduce influence depending of distance to bone axis",
686  0.0f,
687  1.0f);
688 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
#define MAX_BBONE_SUBDIV
Definition: BKE_armature.h:461
void BKE_pchan_bbone_spline_setup(struct bPoseChannel *pchan, bool rest, bool for_deform, Mat4 *result_array)
Definition: armature.c:1178
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct ViewLayer * CTX_data_view_layer(const bContext *C)
Definition: context.c:1100
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1353
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
support for deformation groups and hooks.
struct MDeformWeight * BKE_defvert_ensure_index(struct MDeformVert *dv, int defgroup)
Definition: deform.c:748
struct bDeformGroup * BKE_object_defgroup_find_name(const struct Object *ob, const char *name)
int BKE_object_defgroup_count(const struct Object *ob)
void BKE_gpencil_dvert_ensure(struct bGPDstroke *gps)
Definition: gpencil.c:1891
struct GpencilModifierData * BKE_gpencil_modifiers_findby_type(struct Object *ob, GpencilModifierType type)
Functions for dealing with objects and deform verts, used by painting and tools.
struct bDeformGroup * BKE_object_defgroup_add_name(struct Object *ob, const char *name)
Definition: object_deform.c:95
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE float interpf(float a, float b, float t)
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
Definition: math_geom.c:485
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define ELEM(...)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ BONE_HIDDEN_P
@ BONE_NO_DEFORM
@ eGpencilModifierType_Armature
#define GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)
@ GP_FRAME_SELECT
@ OB_ARMATURE
@ OB_GPENCIL
#define DG_LOCK_WEIGHT
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_vgroup_data_clamp_range(struct ID *id, int total)
struct GpencilModifierData * ED_object_gpencil_modifier_add(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, const char *name, int type)
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define ND_DATA
Definition: WM_types.h:456
#define NA_EDITED
Definition: WM_types.h:523
#define NC_GPENCIL
Definition: WM_types.h:349
Scene scene
const Depsgraph * depsgraph
static float verts[][3]
static void gpencil_object_vgroup_calc_from_armature(const bContext *C, Object *ob, Object *ob_arm, const int mode, const float ratio, const float decay)
static int gpencil_bone_looper(Object *ob, Bone *bone, void *data, int(*bone_func)(Object *, Bone *, void *))
static int gpencil_generate_weights_exec(bContext *C, wmOperator *op)
static float get_weight(float dist, float decay_rad, float dif_rad)
#define DEFAULT_RATIO
static void gpencil_add_verts_to_dgroups(const bContext *C, Object *ob, Object *ob_arm, const float ratio, const float decay)
static int dgroup_skinnable_cb(Object *ob, Bone *bone, void *datap)
bool ED_gpencil_add_armature_weights(const bContext *C, ReportList *reports, Object *ob, Object *ob_arm, int mode)
void GPENCIL_OT_generate_weights(wmOperatorType *ot)
static const EnumPropertyItem * gpencil_armatures_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
bool ED_gpencil_add_armature(const bContext *C, ReportList *reports, Object *ob, Object *ob_arm)
#define DEFAULT_DECAY
static bool gpencil_generate_weights_poll(bContext *C)
@ GP_ARMATURE_AUTO
@ GP_ARMATURE_NAME
static int vgroup_add_unique_bone_cb(Object *ob, Bone *bone, void *UNUSED(ptr))
static int gpencil_bone_skinnable_cb(Object *UNUSED(ob), Bone *bone, void *datap)
bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
static unsigned a[3]
Definition: RandGen.cpp:78
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4487
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
Definition: rna_define.c:4436
void RNA_def_enum_funcs(PropertyRNA *prop, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3830
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const EnumPropertyItem DummyRNA_DEFAULT_items[]
Definition: rna_rna.c:31
struct Object * object
float arm_head[3]
char name[64]
float arm_tail[3]
short segments
float arm_mat[4][4]
struct Bone * next
ListBase childbase
const char * identifier
Definition: RNA_types.h:461
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
float mat[4][4]
Definition: BKE_armature.h:464
ustring name
Definition: graph/node.h:174
struct bPose * pose
float obmat[4][4]
void * data
ListBase object_bases
ListBase bonebase
unsigned int layer
struct bGPDframe * next
ListBase vertex_group_names
ListBase layers
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479