Blender  V3.3
object_constraint.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <stdio.h>
9 #include <string.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_blenlib.h"
14 #include "BLI_dynstr.h"
15 #include "BLI_math.h"
16 #include "BLI_utildefines.h"
17 
18 #include "BLT_translation.h"
19 
20 #include "DNA_anim_types.h"
21 #include "DNA_armature_types.h"
22 #include "DNA_constraint_types.h"
23 #include "DNA_curve_types.h"
24 #include "DNA_object_types.h"
25 #include "DNA_scene_types.h"
26 #include "DNA_text_types.h"
27 
28 #include "BIK_api.h"
29 #include "BKE_action.h"
30 #include "BKE_armature.h"
31 #include "BKE_constraint.h"
32 #include "BKE_context.h"
33 #include "BKE_fcurve.h"
34 #include "BKE_main.h"
35 #include "BKE_object.h"
36 #include "BKE_report.h"
37 #include "BKE_tracking.h"
38 
39 #include "DEG_depsgraph.h"
40 #include "DEG_depsgraph_build.h"
41 #include "DEG_depsgraph_query.h"
42 
43 #ifdef WITH_PYTHON
44 # include "BPY_extern.h"
45 #endif
46 
47 #include "WM_api.h"
48 #include "WM_types.h"
49 
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 #include "RNA_enum_types.h"
53 #include "RNA_path.h"
54 #include "RNA_prototypes.h"
55 
56 #include "ED_keyframing.h"
57 #include "ED_object.h"
58 #include "ED_screen.h"
59 
60 #include "UI_interface.h"
61 #include "UI_resources.h"
62 
63 #include "object_intern.h"
64 
65 /* ------------------------------------------------------------------- */
70 {
71  if (ob == NULL) {
72  return NULL;
73  }
74 
75  if (ob->mode & OB_MODE_POSE) {
76  bPoseChannel *pchan;
77 
79  if (pchan) {
80  return &pchan->constraints;
81  }
82  }
83  else {
84  return &ob->constraints;
85  }
86 
87  return NULL;
88 }
89 
91 {
92  bPoseChannel *pose_bone = CTX_data_pointer_get(C, "pose_bone").data;
93  if (pose_bone == NULL) {
94  pose_bone = CTX_data_pointer_get(C, "active_pose_bone").data;
95  if (pose_bone == NULL) {
96  return NULL;
97  }
98  }
99 
100  return &pose_bone->constraints;
101 }
102 
104  bConstraint *con,
105  bPoseChannel **r_pchan)
106 {
107  if (r_pchan) {
108  *r_pchan = NULL;
109  }
110 
111  if (ELEM(NULL, ob, con)) {
112  return NULL;
113  }
114 
115  /* try object constraints first */
116  if ((BLI_findindex(&ob->constraints, con) != -1)) {
117  return &ob->constraints;
118  }
119 
120  /* if armature, try pose bones too */
121  if (ob->pose) {
122  bPoseChannel *pchan;
123 
124  /* try each bone in order
125  * NOTE: it's not possible to directly look up the active bone yet, so this will have to do
126  */
127  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
128  if ((BLI_findindex(&pchan->constraints, con) != -1)) {
129 
130  if (r_pchan) {
131  *r_pchan = pchan;
132  }
133 
134  return &pchan->constraints;
135  }
136  }
137  }
138 
139  /* done */
140  return NULL;
141 }
142 
144 {
146 }
147 
150 /* ------------------------------------------------------------------- */
154 #ifdef WITH_PYTHON
155 
156 /* this callback sets the text-file to be used for selected menu item */
157 static void validate_pyconstraint_cb(Main *bmain, void *arg1, void *arg2)
158 {
159  bPythonConstraint *data = arg1;
160  Text *text = NULL;
161  int index = *((int *)arg2);
162  int i;
163 
164  /* exception for no script */
165  if (index) {
166  /* innovative use of a for...loop to search */
167  for (text = bmain->texts.first, i = 1; text && index != i; i++, text = text->id.next) {
168  /* pass */
169  }
170  }
171  data->text = text;
172 }
173 
174 /* this returns a string for the list of usable pyconstraint script names */
175 static char *buildmenu_pyconstraints(Main *bmain, Text *con_text, int *pyconindex)
176 {
177  DynStr *pupds = BLI_dynstr_new();
178  Text *text;
179  char *str;
180  char buf[64];
181  int i;
182 
183  /* add title first */
184  sprintf(buf, "Scripts: %%t|[None]%%x0|");
185  BLI_dynstr_append(pupds, buf);
186 
187  /* init active-index first */
188  if (con_text == NULL) {
189  *pyconindex = 0;
190  }
191 
192  /* loop through markers, adding them */
193  for (text = bmain->texts.first, i = 1; text; i++, text = text->id.next) {
194  /* this is important to ensure that right script is shown as active */
195  if (text == con_text) {
196  *pyconindex = i;
197  }
198 
199  /* only include valid pyconstraint scripts */
200  if (BPY_is_pyconstraint(text)) {
201  BLI_dynstr_append(pupds, text->id.name + 2);
202 
203  sprintf(buf, "%%x%d", i);
204  BLI_dynstr_append(pupds, buf);
205 
206  if (text->id.next) {
207  BLI_dynstr_append(pupds, "|");
208  }
209  }
210  }
211 
212  /* convert to normal MEM_malloc'd string */
213  str = BLI_dynstr_get_cstring(pupds);
214  BLI_dynstr_free(pupds);
215 
216  return str;
217 }
218 #endif /* WITH_PYTHON */
219 
220 #if 0 /* UNUSED, until pyconstraints are added back. */
221 /* this callback gets called when the 'refresh' button of a pyconstraint gets pressed */
222 static void update_pyconstraint_cb(void *arg1, void *arg2)
223 {
224 # ifndef WITH_PYTHON
225  (void)arg1; /* unused */
226  (void)arg2; /* unused */
227 # else
228  Object *owner = (Object *)arg1;
229  bConstraint *con = (bConstraint *)arg2;
230  if (owner && con) {
231  BPY_pyconstraint_update(owner, con);
232  }
233 # endif
234 }
235 #endif /* UNUSED */
236 
239 /* ------------------------------------------------------------------- */
243 /* helper function for add_constriant - sets the last target for the active constraint */
245  Object *target,
246  const char subtarget[],
247  int index)
248 {
249  ListBase targets = {NULL, NULL};
250  bConstraintTarget *ct;
251  int num_targets, i;
252 
253  if (BKE_constraint_targets_get(con, &targets)) {
254  num_targets = BLI_listbase_count(&targets);
255 
256  if (index < 0) {
257  if (abs(index) < num_targets) {
258  index = num_targets - abs(index);
259  }
260  else {
261  index = num_targets - 1;
262  }
263  }
264  else if (index >= num_targets) {
265  index = num_targets - 1;
266  }
267 
268  for (ct = targets.first, i = 0; ct; ct = ct->next, i++) {
269  if (i == index) {
270  ct->tar = target;
271  BLI_strncpy(ct->subtarget, subtarget, sizeof(ct->subtarget));
272  break;
273  }
274  }
275 
276  BKE_constraint_targets_flush(con, &targets, 0);
277  }
278 }
279 
282 /* ------------------------------------------------------------------- */
286 static void test_constraint(
287  Main *bmain, Object *owner, bPoseChannel *pchan, bConstraint *con, int type)
288 {
289  ListBase targets = {NULL, NULL};
290  bConstraintTarget *ct;
291  bool check_targets = true;
292 
293  /* clear disabled-flag first */
294  con->flag &= ~CONSTRAINT_DISABLE;
295 
296  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
298 
299  /* bad: we need a separate set of checks here as poletarget is
300  * optional... otherwise poletarget must exist too or else
301  * the constraint is deemed invalid
302  */
303  /* default IK check ... */
304  if (BKE_object_exists_check(bmain, data->tar) == 0) {
305  data->tar = NULL;
306  con->flag |= CONSTRAINT_DISABLE;
307  }
308  else if (data->tar == owner) {
309  if (!BKE_armature_find_bone_name(BKE_armature_from_object(owner), data->subtarget)) {
310  con->flag |= CONSTRAINT_DISABLE;
311  }
312  }
313 
314  if (data->poletar) {
315  if (BKE_object_exists_check(bmain, data->poletar) == 0) {
316  data->poletar = NULL;
317  con->flag |= CONSTRAINT_DISABLE;
318  }
319  else if (data->poletar == owner) {
320  if (!BKE_armature_find_bone_name(BKE_armature_from_object(owner), data->polesubtarget)) {
321  con->flag |= CONSTRAINT_DISABLE;
322  }
323  }
324  }
325  /* ... can be overwritten here */
326  BIK_test_constraint(owner, con);
327  /* targets have already been checked for this */
328  check_targets = false;
329  }
330  else if (con->type == CONSTRAINT_TYPE_PIVOT) {
331  bPivotConstraint *data = con->data;
332 
333  /* target doesn't have to exist, but if it is non-null, it must exist! */
334  if (data->tar && BKE_object_exists_check(bmain, data->tar) == 0) {
335  data->tar = NULL;
336  con->flag |= CONSTRAINT_DISABLE;
337  }
338  else if (data->tar == owner) {
339  if (!BKE_armature_find_bone_name(BKE_armature_from_object(owner), data->subtarget)) {
340  con->flag |= CONSTRAINT_DISABLE;
341  }
342  }
343 
344  /* targets have already been checked for this */
345  check_targets = false;
346  }
347  else if (con->type == CONSTRAINT_TYPE_ACTION) {
348  bActionConstraint *data = con->data;
349 
350  /* validate action */
351  if (data->act == NULL) {
352  /* must have action */
353  con->flag |= CONSTRAINT_DISABLE;
354  }
355  else if (data->act->idroot != ID_OB) {
356  /* only object-rooted actions can be used */
357  data->act = NULL;
358  con->flag |= CONSTRAINT_DISABLE;
359  }
360 
361  /* Skip target checking if we're not using it */
362  if (data->flag & ACTCON_USE_EVAL_TIME) {
363  check_targets = false;
364  }
365  }
366  else if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
368 
369  /* don't allow track/up axes to be the same */
370  if (data->upflag == data->trackflag) {
371  con->flag |= CONSTRAINT_DISABLE;
372  }
373  if (data->upflag + 3 == data->trackflag) {
374  con->flag |= CONSTRAINT_DISABLE;
375  }
376  }
377  else if (con->type == CONSTRAINT_TYPE_TRACKTO) {
378  bTrackToConstraint *data = con->data;
379 
380  /* don't allow track/up axes to be the same */
381  if (data->reserved2 == data->reserved1) {
382  con->flag |= CONSTRAINT_DISABLE;
383  }
384  if (data->reserved2 + 3 == data->reserved1) {
385  con->flag |= CONSTRAINT_DISABLE;
386  }
387  }
388  else if (con->type == CONSTRAINT_TYPE_LOCKTRACK) {
390 
391  if (data->lockflag == data->trackflag) {
392  con->flag |= CONSTRAINT_DISABLE;
393  }
394  if (data->lockflag + 3 == data->trackflag) {
395  con->flag |= CONSTRAINT_DISABLE;
396  }
397  }
398  else if (con->type == CONSTRAINT_TYPE_SPLINEIK) {
399  bSplineIKConstraint *data = con->data;
400 
401  /* if the number of points does not match the amount required by the chain length,
402  * free the points array and request a rebind...
403  */
404  if ((data->points == NULL) || (data->numpoints != data->chainlen + 1)) {
405  MEM_SAFE_FREE(data->points);
406  data->numpoints = 0;
407 
408  /* clear the bound flag, forcing a rebind next time this is evaluated */
410  }
411  }
412  else if (con->type == CONSTRAINT_TYPE_FOLLOWTRACK) {
414 
415  if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0) {
416  if (data->clip != NULL && data->track[0]) {
417  MovieTracking *tracking = &data->clip->tracking;
418  MovieTrackingObject *tracking_object;
419 
420  if (data->object[0]) {
421  tracking_object = BKE_tracking_object_get_named(tracking, data->object);
422  }
423  else {
424  tracking_object = BKE_tracking_object_get_camera(tracking);
425  }
426 
427  if (!tracking_object) {
428  con->flag |= CONSTRAINT_DISABLE;
429  }
430  else {
431  if (!BKE_tracking_track_get_named(tracking, tracking_object, data->track)) {
432  con->flag |= CONSTRAINT_DISABLE;
433  }
434  }
435  }
436  else {
437  con->flag |= CONSTRAINT_DISABLE;
438  }
439  }
440  }
441  else if (con->type == CONSTRAINT_TYPE_CAMERASOLVER) {
443 
444  if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL)) {
445  con->flag |= CONSTRAINT_DISABLE;
446  }
447  }
448  else if (con->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
450 
451  if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL)) {
452  con->flag |= CONSTRAINT_DISABLE;
453  }
454  }
455  else if (con->type == CONSTRAINT_TYPE_TRANSFORM_CACHE) {
457 
458  if ((data->cache_file == NULL) || (data->object_path[0] == '\0')) {
459  con->flag |= CONSTRAINT_DISABLE;
460  }
461  }
462 
463  /* Check targets for constraints */
464  if (check_targets && BKE_constraint_targets_get(con, &targets)) {
465  /* disable and clear constraints targets that are incorrect */
466  for (ct = targets.first; ct; ct = ct->next) {
467  /* general validity checks (for those constraints that need this) */
468  if (BKE_object_exists_check(bmain, ct->tar) == 0) {
469  /* object doesn't exist, but constraint requires target */
470  ct->tar = NULL;
471  con->flag |= CONSTRAINT_DISABLE;
472  }
473  else if (ct->tar == owner) {
474  if (type == CONSTRAINT_OBTYPE_BONE) {
476  /* bone must exist in armature... */
477  /* TODO: clear subtarget? */
478  con->flag |= CONSTRAINT_DISABLE;
479  }
480  else if (STREQ(pchan->name, ct->subtarget)) {
481  /* cannot target self */
482  ct->subtarget[0] = '\0';
483  con->flag |= CONSTRAINT_DISABLE;
484  }
485  }
486  else {
487  /* cannot use self as target */
488  ct->tar = NULL;
489  con->flag |= CONSTRAINT_DISABLE;
490  }
491  }
492 
493  /* target checks for specific constraints */
494  if (ELEM(con->type,
498  if (ct->tar) {
499  /* The object type check is only needed here in case we have a placeholder
500  * object assigned (because the library containing the curve is missing).
501  *
502  * In other cases it should be impossible to have a type mismatch.
503  */
504  if (ct->tar->type != OB_CURVES_LEGACY) {
505  con->flag |= CONSTRAINT_DISABLE;
506  }
507  else {
508  Curve *cu = ct->tar->data;
509 
510  /* auto-set 'Path' setting on curve so this works. */
511  cu->flag |= CU_PATH;
512  }
513  }
514  }
515  else if (con->type == CONSTRAINT_TYPE_ARMATURE) {
516  if (ct->tar) {
517  /* The object type check is only needed here in case we have a placeholder
518  * object assigned (because the library containing the armature is missing).
519  *
520  * In other cases it should be impossible to have a type mismatch.
521  */
522  if (ct->tar->type != OB_ARMATURE) {
523  con->flag |= CONSTRAINT_DISABLE;
524  }
526  ct->subtarget)) {
527  /* bone must exist in armature... */
528  con->flag |= CONSTRAINT_DISABLE;
529  }
530  }
531  }
532  }
533 
534  /* free any temporary targets */
535  BKE_constraint_targets_flush(con, &targets, 0);
536  }
537  else if (check_targets) {
538  /* constraints with empty target list that actually require targets */
539  if (ELEM(con->type, CONSTRAINT_TYPE_ARMATURE)) {
540  con->flag |= CONSTRAINT_DISABLE;
541  }
542  }
543 }
544 
545 static int constraint_type_get(Object *owner, bPoseChannel *pchan)
546 {
547  int type;
548  /* Check parents */
549  if (pchan) {
550  switch (owner->type) {
551  case OB_ARMATURE:
553  break;
554  default:
556  break;
557  }
558  }
559  else {
561  }
562  return type;
563 }
564 
565 /* checks validity of object pointers, and NULLs,
566  * if Bone doesn't exist it sets the CONSTRAINT_DISABLE flag.
567  */
568 static void test_constraints(Main *bmain, Object *ob, bPoseChannel *pchan)
569 {
570  bConstraint *curcon;
571  ListBase *conlist = NULL;
572  int type;
573 
574  if (ob == NULL) {
575  return;
576  }
577 
578  type = constraint_type_get(ob, pchan);
579 
580  /* Get the constraint list for this object */
581  switch (type) {
583  conlist = &ob->constraints;
584  break;
586  conlist = &pchan->constraints;
587  break;
588  }
589 
590  /* Check all constraints - is constraint valid? */
591  if (conlist) {
592  for (curcon = conlist->first; curcon; curcon = curcon->next) {
593  test_constraint(bmain, ob, pchan, curcon, type);
594  }
595  }
596 }
597 
599 {
600  if (ob->constraints.first) {
601  test_constraints(bmain, ob, NULL);
602  }
603 
604  if (ob->type == OB_ARMATURE && ob->pose) {
605  bPoseChannel *pchan;
606 
607  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
608  if (pchan->constraints.first) {
609  test_constraints(bmain, ob, pchan);
610  }
611  }
612  }
613 }
614 
615 static void object_test_constraint(Main *bmain, Object *ob, bConstraint *con)
616 {
617  if (ob->type == OB_ARMATURE && ob->pose) {
618  if (BLI_findindex(&ob->constraints, con) != -1) {
620  }
621  else {
622  bPoseChannel *pchan;
623  for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
624  if (BLI_findindex(&pchan->constraints, con) != -1) {
625  test_constraint(bmain, ob, pchan, con, CONSTRAINT_OBTYPE_BONE);
626  break;
627  }
628  }
629  }
630  }
631  else {
633  }
634 }
635 
638 /* ------------------------------------------------------------------- */
642 #define EDIT_CONSTRAINT_OWNER_OBJECT 0
643 #define EDIT_CONSTRAINT_OWNER_BONE 1
644 
647  "OBJECT",
648  0,
649  "Object",
650  "Edit a constraint on the active object"},
651  {EDIT_CONSTRAINT_OWNER_BONE, "BONE", 0, "Bone", "Edit a constraint on the active bone"},
652  {0, NULL, 0, NULL, NULL},
653 };
654 
656  StructRNA *rna_type,
657  const bool is_liboverride_allowed)
658 {
659  PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type);
661  bConstraint *con = ptr.data;
662 
664  return false;
665  }
666 
667  if (ptr.owner_id != NULL && ID_IS_LINKED(ptr.owner_id)) {
668  CTX_wm_operator_poll_msg_set(C, "Cannot edit library data");
669  return false;
670  }
671 
674  C, "Cannot edit constraints coming from linked data in a library override");
675  return false;
676  }
677 
678  return true;
679 }
680 
682 {
683  return edit_constraint_poll_generic(C, &RNA_Constraint, false);
684 }
685 
686 /* Used by operators performing actions allowed also on constraints from the overridden linked
687  * object (not only from added 'local' ones). */
689 {
690  return edit_constraint_poll_generic(C, &RNA_Constraint, true);
691 }
692 
694 {
695  PropertyRNA *prop;
696  prop = RNA_def_string(
697  ot->srna, "constraint", NULL, MAX_NAME, "Constraint", "Name of the constraint to edit");
699  prop = RNA_def_enum(
700  ot->srna, "owner", constraint_owner_items, 0, "Owner", "The owner of this constraint");
702 }
703 
705 {
707  ot->srna, "report", false, "Report", "Create a notification after the operation");
709 }
710 
712  wmOperator *op,
713  const wmEvent *event,
714  int *r_retval)
715 {
716  PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
718  bConstraint *con;
719  ListBase *list;
720 
721  if (RNA_struct_property_is_set(op->ptr, "constraint") &&
722  RNA_struct_property_is_set(op->ptr, "owner")) {
723  return true;
724  }
725 
726  if (ptr.data) {
727  con = ptr.data;
728  RNA_string_set(op->ptr, "constraint", con->name);
729 
731 
732  if (&ob->constraints == list) {
734  }
735  else {
737  }
738 
739  return true;
740  }
741 
742  /* Check the custom data of panels under the mouse for a modifier. */
743  if (event != NULL) {
745 
746  if (!(panel_ptr == NULL || RNA_pointer_is_null(panel_ptr))) {
747  if (RNA_struct_is_a(panel_ptr->type, &RNA_Constraint)) {
748  con = panel_ptr->data;
749  RNA_string_set(op->ptr, "constraint", con->name);
751  RNA_enum_set(op->ptr,
752  "owner",
753  (&ob->constraints == list) ? EDIT_CONSTRAINT_OWNER_OBJECT :
755 
756  return true;
757  }
758 
759  BLI_assert(r_retval != NULL); /* We need the return value in this case. */
760  if (r_retval != NULL) {
762  }
763  return false;
764  }
765  }
766 
767  return false;
768 }
769 
771 {
772  char constraint_name[MAX_NAME];
773  int owner = RNA_enum_get(op->ptr, "owner");
774  bConstraint *con;
775  ListBase *list = NULL;
776 
777  RNA_string_get(op->ptr, "constraint", constraint_name);
778 
779  if (owner == EDIT_CONSTRAINT_OWNER_BONE) {
781  if (!list) {
782  return NULL;
783  }
784  }
785  else {
786  list = &ob->constraints;
787  }
788 
789  con = BKE_constraints_find_name(list, constraint_name);
790 #if 0
791  if (G.debug & G_DEBUG) {
792  printf("constraint found = %p, %s\n", (void *)con, (con) ? con->name : "<Not found>");
793  }
794 #endif
795 
796  if (con && (type != 0) && (con->type != type)) {
797  con = NULL;
798  }
799 
800  return con;
801 }
802 
805 /* ------------------------------------------------------------------- */
812 {
813  Main *bmain = CTX_data_main(C);
817 
818  /* despite 3 layers of checks, we may still not be able to find a constraint */
819  if (data == NULL) {
820  return OPERATOR_CANCELLED;
821  }
822 
823  /* just set original length to 0.0, which will cause a reset on next recalc */
824  data->orglength = 0.0f;
825  ED_object_constraint_update(bmain, ob);
826 
828  return OPERATOR_FINISHED;
829 }
830 
831 static int stretchto_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
832 {
834  return stretchto_reset_exec(C, op);
835  }
836  return OPERATOR_CANCELLED;
837 }
838 
840 {
841  /* identifiers */
842  ot->name = "Reset Original Length";
843  ot->idname = "CONSTRAINT_OT_stretchto_reset";
844  ot->description = "Reset original length of bone for Stretch To Constraint";
845 
846  /* callbacks */
850 
851  /* flags */
853 
854  /* properties */
856 }
857 
860 /* ------------------------------------------------------------------- */
867 {
868  Main *bmain = CTX_data_main(C);
872 
873  /* despite 3 layers of checks, we may still not be able to find a constraint */
874  if (data == NULL) {
875  return OPERATOR_CANCELLED;
876  }
877 
878  /* just set original length to 0.0, which will cause a reset on next recalc */
879  data->dist = 0.0f;
880  ED_object_constraint_update(bmain, ob);
881 
883  return OPERATOR_FINISHED;
884 }
885 
887 {
889  return limitdistance_reset_exec(C, op);
890  }
891  return OPERATOR_CANCELLED;
892 }
893 
895 {
896  /* identifiers */
897  ot->name = "Reset Distance";
898  ot->idname = "CONSTRAINT_OT_limitdistance_reset";
899  ot->description = "Reset limiting distance for Limit Distance Constraint";
900 
901  /* callbacks */
905 
906  /* flags */
908 
909  /* properties */
911 }
912 
915 /* ------------------------------------------------------------------- */
919 /* Force evaluation so that the 'set inverse' flag is handled.
920  * No-op when the constraint is enabled, as in such cases the evaluation will happen anyway.
921  */
923 {
924  if ((con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) == 0) {
925  return;
926  }
927 
930 
931  short flag_backup = con->flag;
934  con->flag = flag_backup;
935 }
936 
937 /* ChildOf Constraint - set inverse callback */
939 {
940  Main *bmain = CTX_data_main(C);
943  bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
944 
945  /* despite 3 layers of checks, we may still not be able to find a constraint */
946  if (data == NULL) {
947  printf("DEBUG: Child-Of Set Inverse - object = '%s'\n", (ob) ? ob->id.name + 2 : "<None>");
948  BKE_report(op->reports, RPT_ERROR, "Could not find constraint data for Child-Of Set Inverse");
949  return OPERATOR_CANCELLED;
950  }
951 
952  /* Set a flag to request recalculation on next update. */
953  data->flag |= CHILDOF_SET_INVERSE;
954 
955  /* Force constraint to run, it will perform the recalculation. */
957 
958  ED_object_constraint_update(bmain, ob);
960 
961  return OPERATOR_FINISHED;
962 }
963 
965 {
967  return childof_set_inverse_exec(C, op);
968  }
969  return OPERATOR_CANCELLED;
970 }
971 
973 {
974  /* identifiers */
975  ot->name = "Set Inverse";
976  ot->idname = "CONSTRAINT_OT_childof_set_inverse";
977  ot->description = "Set inverse correction for Child Of constraint";
978 
979  /* callbacks */
983 
984  /* flags */
986 
987  /* properties */
989 }
990 
991 /* ChildOf Constraint - clear inverse callback */
993 {
994  Main *bmain = CTX_data_main(C);
997  bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL;
998 
999  if (data == NULL) {
1000  BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found");
1001  return OPERATOR_CANCELLED;
1002  }
1003 
1004  /* simply clear the matrix */
1005  unit_m4(data->invmat);
1006 
1007  ED_object_constraint_update(bmain, ob);
1009 
1010  return OPERATOR_FINISHED;
1011 }
1012 
1014 {
1016  return childof_clear_inverse_exec(C, op);
1017  }
1018  return OPERATOR_CANCELLED;
1019 }
1020 
1022 {
1023  /* identifiers */
1024  ot->name = "Clear Inverse";
1025  ot->idname = "CONSTRAINT_OT_childof_clear_inverse";
1026  ot->description = "Clear inverse correction for Child Of constraint";
1027 
1028  /* callbacks */
1032 
1033  /* flags */
1035 
1036  /* properties */
1038 }
1039 
1042 /* ------------------------------------------------------------------- */
1047 {
1048  Main *bmain = CTX_data_main(C);
1052 
1053  bAction *act = NULL;
1054  FCurve *fcu = NULL;
1055  int sfra = RNA_int_get(op->ptr, "frame_start");
1056  int len = RNA_int_get(op->ptr, "length");
1057  float standardRange = 1.0;
1058 
1059  /* nearly impossible sanity check */
1060  if (data == NULL) {
1061  BKE_report(op->reports, RPT_ERROR, "Follow Path constraint not found");
1062  return OPERATOR_CANCELLED;
1063  }
1064 
1065  /* add F-Curve as appropriate */
1066  if (data->tar) {
1067  Curve *cu = (Curve *)data->tar->data;
1068 
1069  if (ELEM(NULL, cu->adt, cu->adt->action) ||
1070  (BKE_fcurve_find(&cu->adt->action->curves, "eval_time", 0) == NULL)) {
1071  /* create F-Curve for path animation */
1072  act = ED_id_action_ensure(bmain, &cu->id);
1073  fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, "eval_time", 0);
1074 
1075  /* standard vertical range - 1:1 = 100 frames */
1076  standardRange = 100.0f;
1077  }
1078  else {
1079  /* path anim exists already - abort for now as this may well be what was intended */
1080  BKE_report(op->reports, RPT_WARNING, "Path is already animated");
1081  return OPERATOR_CANCELLED;
1082  }
1083  }
1084  else {
1085  /* animate constraint's "fixed offset" */
1086  PointerRNA ptr;
1087  PropertyRNA *prop;
1088  char *path;
1089 
1090  /* get RNA pointer to constraint's "offset_factor" property - to build RNA path */
1091  RNA_pointer_create(&ob->id, &RNA_FollowPathConstraint, con, &ptr);
1092  prop = RNA_struct_find_property(&ptr, "offset_factor");
1093 
1094  path = RNA_path_from_ID_to_property(&ptr, prop);
1095 
1096  /* create F-Curve for constraint */
1097  act = ED_id_action_ensure(bmain, &ob->id);
1098  fcu = ED_action_fcurve_ensure(bmain, act, NULL, NULL, path, 0);
1099 
1100  /* standard vertical range - 0.0 to 1.0 */
1101  standardRange = 1.0f;
1102 
1103  /* enable "Use Fixed Position" so that animating this has effect */
1104  data->followflag |= FOLLOWPATH_STATIC;
1105 
1106  /* path needs to be freed */
1107  if (path) {
1108  MEM_freeN(path);
1109  }
1110  }
1111 
1112  /* setup dummy 'generator' modifier here to get 1-1 correspondence still working
1113  * and define basic slope of this curve based on the properties
1114  */
1115  if (!fcu->bezt && !fcu->fpt && !fcu->modifiers.first) {
1117  FMod_Generator *gen = fcm->data;
1118 
1119  /* Assume that we have the following equation:
1120  * y = Ax + B
1121  * 1 0 <-- coefficients array indices
1122  */
1123  float A = standardRange / (float)(len);
1124  float B = (float)(-sfra) * A;
1125 
1126  gen->coefficients[1] = A;
1127  gen->coefficients[0] = B;
1128  }
1129 
1130  /* updates... */
1132  return OPERATOR_FINISHED;
1133 }
1134 
1136  wmOperator *op,
1137  const wmEvent *UNUSED(event))
1138 {
1139  /* hook up invoke properties for figuring out which constraint we're dealing with */
1141  return followpath_path_animate_exec(C, op);
1142  }
1143  return OPERATOR_CANCELLED;
1144 }
1145 
1147 {
1148  /* identifiers */
1149  ot->name = "Auto Animate Path";
1150  ot->idname = "CONSTRAINT_OT_followpath_path_animate";
1151  ot->description =
1152  "Add default animation for path used by constraint if it isn't animated already";
1153 
1154  /* callbacks */
1158 
1159  /* flags */
1161 
1162  /* props */
1164  RNA_def_int(ot->srna,
1165  "frame_start",
1166  1,
1167  MINAFRAME,
1168  MAXFRAME,
1169  "Start Frame",
1170  "First frame of path animation",
1171  MINAFRAME,
1172  MAXFRAME);
1173  RNA_def_int(ot->srna,
1174  "length",
1175  100,
1176  0,
1177  MAXFRAME,
1178  "Length",
1179  "Number of frames that path animation should take",
1180  0,
1181  MAXFRAME);
1182 }
1183 
1186 /* ------------------------------------------------------------------- */
1191 {
1192  Main *bmain = CTX_data_main(C);
1196 
1197  /* despite 3 layers of checks, we may still not be able to find a constraint */
1198  if (data == NULL) {
1199  printf("DEBUG: ObjectSolver Set Inverse - object = '%s'\n", (ob) ? ob->id.name + 2 : "<None>");
1200  BKE_report(
1201  op->reports, RPT_ERROR, "Could not find constraint data for ObjectSolver Set Inverse");
1202  return OPERATOR_CANCELLED;
1203  }
1204 
1205  /* Set a flag to request recalculation on next update. */
1206  data->flag |= OBJECTSOLVER_SET_INVERSE;
1207 
1208  /* Force constraint to run, it will perform the recalculation. */
1210 
1211  ED_object_constraint_update(bmain, ob);
1213 
1214  return OPERATOR_FINISHED;
1215 }
1216 
1218  wmOperator *op,
1219  const wmEvent *UNUSED(event))
1220 {
1222  return objectsolver_set_inverse_exec(C, op);
1223  }
1224  return OPERATOR_CANCELLED;
1225 }
1226 
1228 {
1229  /* identifiers */
1230  ot->name = "Set Inverse";
1231  ot->idname = "CONSTRAINT_OT_objectsolver_set_inverse";
1232  ot->description = "Set inverse correction for Object Solver constraint";
1233 
1234  /* callbacks */
1238 
1239  /* flags */
1241 
1242  /* properties */
1244 }
1245 
1248 /* ------------------------------------------------------------------- */
1253 {
1254  Main *bmain = CTX_data_main(C);
1258 
1259  if (data == NULL) {
1260  BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found");
1261  return OPERATOR_CANCELLED;
1262  }
1263 
1264  /* simply clear the matrix */
1265  unit_m4(data->invmat);
1266 
1267  ED_object_constraint_update(bmain, ob);
1269 
1270  return OPERATOR_FINISHED;
1271 }
1272 
1274  wmOperator *op,
1275  const wmEvent *UNUSED(event))
1276 {
1278  return objectsolver_clear_inverse_exec(C, op);
1279  }
1280  return OPERATOR_CANCELLED;
1281 }
1282 
1284 {
1285  /* identifiers */
1286  ot->name = "Clear Inverse";
1287  ot->idname = "CONSTRAINT_OT_objectsolver_clear_inverse";
1288  ot->description = "Clear inverse correction for Object Solver constraint";
1289 
1290  /* callbacks */
1294 
1295  /* flags */
1297 
1298  /* properties */
1300 }
1301 
1304 /* ------------------------------------------------------------------- */
1309 {
1311 
1312  /* lets be nice and escape if its active already */
1313  /* NOTE: this assumes that the stack doesn't have other active ones set... */
1314  if ((lb && con) && (con->flag & CONSTRAINT_ACTIVE)) {
1315  return;
1316  }
1317 
1318  BKE_constraints_active_set(lb, con);
1319 }
1320 
1322 {
1323  if (ob->pose) {
1325  }
1326 
1327  object_test_constraints(bmain, ob);
1328 
1329  if (ob->type == OB_ARMATURE) {
1331  }
1332  else {
1334  }
1335 }
1336 
1337 static void object_pose_tag_update(Main *bmain, Object *ob)
1338 {
1339  BKE_pose_tag_recalc(bmain, ob->pose); /* Checks & sort pose channels. */
1340 }
1341 
1343 {
1344  ED_object_constraint_update(bmain, ob);
1345 
1346  if (ob->pose) {
1347  object_pose_tag_update(bmain, ob);
1348  }
1349  DEG_relations_tag_update(bmain);
1350 }
1351 
1353 {
1354  if (ob->pose) {
1356  }
1357 
1358  if (con) {
1359  object_test_constraint(bmain, ob, con);
1360  }
1361 
1362  if (ob->type == OB_ARMATURE) {
1364  }
1365  else {
1367  }
1368 
1369  /* Do Copy-on-Write tag here too, otherwise constraint
1370  * influence/mute buttons in UI have no effect
1371  */
1373 }
1374 
1376 {
1377  ED_object_constraint_tag_update(bmain, ob, con);
1378 
1379  if (ob->pose) {
1380  object_pose_tag_update(bmain, ob);
1381  }
1382  DEG_relations_tag_update(bmain);
1383 }
1384 
1386 {
1387  BLI_assert(con != NULL);
1388  BLI_assert(index >= 0);
1389 
1391  int current_index = BLI_findindex(conlist, con);
1392  BLI_assert(current_index >= 0);
1393 
1394  BLI_listbase_link_move(conlist, con, index - current_index);
1395 
1397 
1398  return true;
1399 }
1400 
1402 {
1403  BKE_constraints_free(dst);
1404  BKE_constraints_copy(dst, src, true);
1405  LISTBASE_FOREACH (bConstraint *, con, dst) {
1406  ED_object_constraint_dependency_tag_update(bmain, ob_dst, con);
1407  }
1409 }
1410 
1412 {
1413  bConstraint *copy_con = BKE_constraint_copy_for_object(ob_dst, con);
1415 
1416  ED_object_constraint_dependency_tag_update(bmain, ob_dst, con);
1418 }
1419 
1421  Object *ob_dst,
1422  bPoseChannel *pchan,
1423  bConstraint *con)
1424 {
1425  bConstraint *copy_con = BKE_constraint_copy_for_pose(ob_dst, pchan, con);
1427 
1428  ED_object_constraint_dependency_tag_update(bmain, ob_dst, con);
1430 }
1431 
1434 /* ------------------------------------------------------------------- */
1439 {
1440  Main *bmain = CTX_data_main(C);
1442  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1443 
1444  if (con == NULL) {
1445  return OPERATOR_CANCELLED;
1446  }
1447 
1449 
1450  /* Store name temporarily for report. */
1451  char name[MAX_NAME];
1452  strcpy(name, con->name);
1453 
1454  /* free the constraint */
1455  if (BKE_constraint_remove_ex(lb, ob, con, true)) {
1456  /* needed to set the flags on posebones correctly */
1457  ED_object_constraint_update(bmain, ob);
1458 
1459  /* relations */
1460  DEG_relations_tag_update(bmain);
1461 
1462  /* notifiers */
1464 
1465  if (RNA_boolean_get(op->ptr, "report")) {
1466  BKE_reportf(op->reports, RPT_INFO, "Removed constraint: %s", name);
1467  }
1468 
1469  return OPERATOR_FINISHED;
1470  }
1471  /* couldn't remove due to some invalid data */
1472  return OPERATOR_CANCELLED;
1473 }
1474 
1475 static int constraint_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1476 {
1477  int retval;
1478  if (!edit_constraint_invoke_properties(C, op, event, &retval)) {
1479  return OPERATOR_CANCELLED;
1480  }
1481  return constraint_delete_exec(C, op);
1482 }
1483 
1485 {
1486  /* identifiers */
1487  ot->name = "Delete Constraint";
1488  ot->idname = "CONSTRAINT_OT_delete";
1489  ot->description = "Remove constraint from constraint stack";
1490 
1491  /* callbacks */
1495 
1496  /* flags */
1500 }
1501 
1504 /* ------------------------------------------------------------------- */
1509 {
1512  Main *bmain = CTX_data_main(C);
1514  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1515 
1516  if (con == NULL) {
1517  return OPERATOR_CANCELLED;
1518  }
1519 
1520  bPoseChannel *pchan;
1522 
1523  /* Store name temporarily for report. */
1524  char name[MAX_NAME];
1525  strcpy(name, con->name);
1526  const bool is_first_constraint = con != constraints->first;
1527 
1528  /* Copy the constraint. */
1529  bool success;
1530  if (pchan) {
1532  depsgraph, scene, constraints, ob, con, pchan);
1533  }
1534  else {
1536  }
1537 
1538  if (!success) {
1539  /* Couldn't remove due to some invalid data. */
1540  return OPERATOR_CANCELLED;
1541  }
1542 
1543  /* Update for any children that may get moved. */
1545 
1546  /* Needed to set the flags on posebones correctly. */
1547  ED_object_constraint_update(bmain, ob);
1548 
1549  DEG_relations_tag_update(bmain);
1551  if (pchan) {
1553  }
1554  else {
1556  }
1557 
1558  if (RNA_boolean_get(op->ptr, "report")) {
1559  if (is_first_constraint) {
1560  BKE_report(op->reports,
1561  RPT_INFO,
1562  "Applied constraint was not first, result may not be as expected");
1563  }
1564  else {
1565  /* Only add this report if the operator didn't cause another one. The purpose here is
1566  * to alert that something happened, and the previous report will do that anyway. */
1567  BKE_reportf(op->reports, RPT_INFO, "Applied constraint: %s", name);
1568  }
1569  }
1570 
1571  return OPERATOR_FINISHED;
1572 }
1573 
1574 static int constraint_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1575 {
1576  int retval;
1577  if (!edit_constraint_invoke_properties(C, op, event, &retval)) {
1578  return OPERATOR_CANCELLED;
1579  }
1580  return constraint_apply_exec(C, op);
1581 }
1582 
1584 {
1585  /* identifiers */
1586  ot->name = "Apply Constraint";
1587  ot->idname = "CONSTRAINT_OT_apply";
1588  ot->description = "Apply constraint and remove from the stack";
1589 
1590  /* callbacks */
1594 
1595  /* flags */
1599 }
1600 
1603 /* ------------------------------------------------------------------- */
1608 {
1609  Main *bmain = CTX_data_main(C);
1611  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1612 
1613  if (con == NULL) {
1614  return OPERATOR_CANCELLED;
1615  }
1616 
1617  bPoseChannel *pchan;
1619 
1620  /* Store name temporarily for report. */
1621  char name[MAX_NAME];
1622  strcpy(name, con->name);
1623 
1624  /* Copy the constraint. */
1625  bConstraint *copy_con;
1626  if (pchan) {
1627  copy_con = BKE_constraint_copy_for_pose(ob, pchan, con);
1628  }
1629  else {
1630  copy_con = BKE_constraint_copy_for_object(ob, con);
1631  }
1632 
1633  if (!copy_con) {
1634  /* Couldn't remove due to some invalid data. */
1635  return OPERATOR_CANCELLED;
1636  }
1638 
1639  /* Move constraint to correct position. */
1640  const int new_index = BLI_findindex(constraints, con) + 1;
1641  const int current_index = BLI_findindex(constraints, copy_con);
1642  BLI_assert(new_index >= 0);
1643  BLI_assert(current_index >= 0);
1644  BLI_listbase_link_move(constraints, copy_con, new_index - current_index);
1645 
1646  /* Needed to set the flags on posebones correctly. */
1647  ED_object_constraint_update(bmain, ob);
1648 
1649  DEG_relations_tag_update(bmain);
1651 
1652  if (RNA_boolean_get(op->ptr, "report")) {
1653  BKE_reportf(op->reports, RPT_INFO, "Copied constraint: %s", name);
1654  }
1655 
1656  return OPERATOR_FINISHED;
1657 }
1658 
1659 static int constraint_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1660 {
1661  int retval;
1662  if (!edit_constraint_invoke_properties(C, op, event, &retval)) {
1663  return OPERATOR_CANCELLED;
1664  }
1665  return constraint_copy_exec(C, op);
1666 }
1667 
1669 {
1670  /* identifiers */
1671  ot->name = "Duplicate Constraint";
1672  ot->idname = "CONSTRAINT_OT_copy";
1673  ot->description = "Duplicate constraint at the same position in the stack";
1674 
1675  /* callbacks */
1679 
1680  /* flags */
1684 }
1685 
1688 /* ------------------------------------------------------------------- */
1693 {
1694  Main *bmain = CTX_data_main(C);
1695  Object *obact = ED_object_active_context(C);
1696  bConstraint *con = edit_constraint_property_get(C, op, obact, 0);
1697 
1698  if (con == NULL) {
1699  return OPERATOR_CANCELLED;
1700  }
1701 
1702  bPoseChannel *pchan;
1703  ED_object_constraint_list_from_constraint(obact, con, &pchan);
1704 
1705  if (pchan) {
1706  /* Don't do anything if bone doesn't exist or doesn't have any constraints. */
1707  if (pchan->constraints.first == NULL) {
1708  BKE_report(op->reports, RPT_ERROR, "No constraints for copying");
1709  return OPERATOR_CANCELLED;
1710  }
1711 
1712  Object *prev_ob = NULL;
1713 
1714  /* Copy all constraints from active pose-bone to all selected pose-bones. */
1715  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, chan, selected_pose_bones, Object *, ob) {
1716  /* If we're not handling the object we're copying from, copy all constraints over. */
1717  if (pchan == chan) {
1718  continue;
1719  }
1720 
1721  bConstraint *copy_con = BKE_constraint_copy_for_pose(ob, chan, con);
1723 
1724  /* Update flags (need to add here, not just copy). */
1725  chan->constflag |= pchan->constflag;
1726 
1727  if (prev_ob == ob) {
1728  continue;
1729  }
1730 
1731  BKE_pose_tag_recalc(bmain, ob->pose);
1733  prev_ob = ob;
1734  }
1735  CTX_DATA_END;
1736  }
1737  else {
1738  /* Copy all constraints from active object to all selected objects. */
1739  CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
1740  /* If we're not handling the object we're copying from, copy all constraints over. */
1741  if (obact == ob) {
1742  continue;
1743  }
1744 
1745  bConstraint *copy_con = BKE_constraint_copy_for_object(ob, con);
1747 
1749  }
1750  CTX_DATA_END;
1751  }
1752 
1753  /* Force depsgraph to get recalculated since new relationships added. */
1754  DEG_relations_tag_update(bmain);
1755 
1757 
1758  return OPERATOR_FINISHED;
1759 }
1760 
1762 {
1763  int retval;
1764  if (!edit_constraint_invoke_properties(C, op, event, &retval)) {
1765  return retval;
1766  }
1767  return constraint_copy_to_selected_exec(C, op);
1768 }
1769 
1771 {
1772  PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", &RNA_Constraint);
1774  bConstraint *con = ptr.data;
1775  bPoseChannel *pchan;
1776  ED_object_constraint_list_from_constraint(obact, con, &pchan);
1777 
1778  if (pchan) {
1779  bool found = false;
1780  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, chan, selected_pose_bones, Object *, ob) {
1781  UNUSED_VARS(ob);
1782  if (pchan != chan) {
1785  found = true;
1786  break;
1787  }
1788  }
1789  CTX_DATA_END;
1790  if (found) {
1791  return true;
1792  }
1793 
1794  CTX_wm_operator_poll_msg_set(C, "No other bones are selected");
1795  return false;
1796  }
1797 
1798  if (!obact) {
1799  CTX_wm_operator_poll_msg_set(C, "No selected object to copy from");
1800  return false;
1801  }
1802 
1803  bool found = false;
1804  CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
1805  if (ob != obact) {
1808  found = true;
1809  break;
1810  }
1811  }
1812  CTX_DATA_END;
1813  if (found) {
1814  return true;
1815  }
1816 
1817  CTX_wm_operator_poll_msg_set(C, "No other objects are selected");
1818  return false;
1819 }
1820 
1822 {
1823  /* identifiers */
1824  ot->name = "Copy Constraint To Selected";
1825  ot->idname = "CONSTRAINT_OT_copy_to_selected";
1826  ot->description = "Copy constraint to other selected objects/bones";
1827 
1828  /* api callbacks */
1832 
1833  /* flags */
1836 }
1837 
1840 /* ------------------------------------------------------------------- */
1845 {
1847  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1848 
1849  if (con && con->next) {
1851  bConstraint *nextCon = con->next;
1852 
1853  /* insert the nominated constraint after the one that used to be after it */
1854  BLI_remlink(conlist, con);
1855  BLI_insertlinkafter(conlist, nextCon, con);
1856 
1859 
1860  return OPERATOR_FINISHED;
1861  }
1862 
1863  return OPERATOR_CANCELLED;
1864 }
1865 
1867 {
1868  int retval;
1869  if (edit_constraint_invoke_properties(C, op, event, &retval)) {
1870  return constraint_move_down_exec(C, op);
1871  }
1872  return retval;
1873 }
1874 
1876 {
1877  /* identifiers */
1878  ot->name = "Move Constraint Down";
1879  ot->idname = "CONSTRAINT_OT_move_down";
1880  ot->description = "Move constraint down in constraint stack";
1881 
1882  /* callbacks */
1886 
1887  /* flags */
1889 
1890  /* properties */
1892 }
1893 
1896 /* ------------------------------------------------------------------- */
1901 {
1903  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1904 
1905  if (con && con->prev) {
1907  bConstraint *prevCon = con->prev;
1908 
1909  /* insert the nominated constraint before the one that used to be before it */
1910  BLI_remlink(conlist, con);
1911  BLI_insertlinkbefore(conlist, prevCon, con);
1912 
1915 
1916  return OPERATOR_FINISHED;
1917  }
1918 
1919  return OPERATOR_CANCELLED;
1920 }
1921 
1922 static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
1923 {
1924  int retval;
1925  if (edit_constraint_invoke_properties(C, op, event, &retval)) {
1926  return constraint_move_up_exec(C, op);
1927  }
1928  return retval;
1929 }
1930 
1932 {
1933  /* identifiers */
1934  ot->name = "Move Constraint Up";
1935  ot->idname = "CONSTRAINT_OT_move_up";
1936  ot->description = "Move constraint up in constraint stack";
1937 
1938  /* callbacks */
1942 
1943  /* flags */
1946 }
1947 
1950 /* ------------------------------------------------------------------- */
1955 {
1957  bConstraint *con = edit_constraint_property_get(C, op, ob, 0);
1958 
1959  int new_index = RNA_int_get(op->ptr, "index");
1960  if (new_index < 0) {
1961  new_index = 0;
1962  }
1963 
1964  if (con) {
1965  ED_object_constraint_move_to_index(ob, con, new_index);
1966 
1968 
1969  return OPERATOR_FINISHED;
1970  }
1971 
1972  return OPERATOR_CANCELLED;
1973 }
1974 
1976 {
1977  int retval;
1978  if (edit_constraint_invoke_properties(C, op, event, &retval)) {
1979  return constraint_move_to_index_exec(C, op);
1980  }
1981  return retval;
1982 }
1983 
1985 {
1986  /* identifiers */
1987  ot->name = "Move Constraint to Index";
1988  ot->idname = "CONSTRAINT_OT_move_to_index";
1989  ot->description =
1990  "Change the constraint's position in the list so it evaluates after the set number of "
1991  "others";
1992 
1993  /* callbacks */
1997 
1998  /* flags */
2001  RNA_def_int(ot->srna,
2002  "index",
2003  0,
2004  0,
2005  INT_MAX,
2006  "Index",
2007  "The index to move the constraint to",
2008  0,
2009  INT_MAX);
2010 }
2011 
2014 /* ------------------------------------------------------------------- */
2019 {
2020  Main *bmain = CTX_data_main(C);
2021  Object *prev_ob = NULL;
2022 
2023  /* free constraints for all selected bones */
2024  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
2025  BKE_constraints_free(&pchan->constraints);
2026  pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_SPLINEIK | PCHAN_HAS_CONST);
2027 
2028  if (prev_ob != ob) {
2031  prev_ob = ob;
2032  }
2033  }
2034  CTX_DATA_END;
2035 
2036  /* force depsgraph to get recalculated since relationships removed */
2037  DEG_relations_tag_update(bmain);
2038 
2039  /* NOTE: calling BIK_clear_data() isn't needed here. */
2040 
2041  return OPERATOR_FINISHED;
2042 }
2043 
2045 {
2046  /* identifiers */
2047  ot->name = "Clear Pose Constraints";
2048  ot->idname = "POSE_OT_constraints_clear";
2049  ot->description = "Clear all the constraints for the selected bones";
2050 
2051  /* callbacks */
2053  /* XXX: do we want to ensure there are selected bones too? */
2055 }
2056 
2058 {
2059  Main *bmain = CTX_data_main(C);
2060 
2061  /* do freeing */
2062  CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
2063  BKE_constraints_free(&ob->constraints);
2065  }
2066  CTX_DATA_END;
2067 
2068  /* force depsgraph to get recalculated since relationships removed */
2069  DEG_relations_tag_update(bmain);
2070 
2071  /* do updates */
2073 
2074  return OPERATOR_FINISHED;
2075 }
2076 
2079 /* ------------------------------------------------------------------- */
2084 {
2085  /* identifiers */
2086  ot->name = "Clear Object Constraints";
2087  ot->idname = "OBJECT_OT_constraints_clear";
2088  ot->description = "Clear all the constraints for the active object only";
2089 
2090  /* callbacks */
2093 }
2094 
2097 /* ------------------------------------------------------------------- */
2102 {
2103  Main *bmain = CTX_data_main(C);
2105 
2106  /* don't do anything if bone doesn't exist or doesn't have any constraints */
2107  if (ELEM(NULL, pchan, pchan->constraints.first)) {
2108  BKE_report(op->reports, RPT_ERROR, "No active bone with constraints for copying");
2109  return OPERATOR_CANCELLED;
2110  }
2111 
2112  Object *prev_ob = NULL;
2113 
2114  /* Copy all constraints from active pose-bone to all selected pose-bones. */
2115  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, chan, selected_pose_bones, Object *, ob) {
2116  /* if we're not handling the object we're copying from, copy all constraints over */
2117  if (pchan != chan) {
2118  BKE_constraints_copy(&chan->constraints, &pchan->constraints, true);
2119  /* update flags (need to add here, not just copy) */
2120  chan->constflag |= pchan->constflag;
2121 
2122  if (prev_ob != ob) {
2123  BKE_pose_tag_recalc(bmain, ob->pose);
2125  prev_ob = ob;
2126  }
2127  }
2128  }
2129  CTX_DATA_END;
2130 
2131  /* force depsgraph to get recalculated since new relationships added */
2132  DEG_relations_tag_update(bmain);
2133 
2135 
2136  return OPERATOR_FINISHED;
2137 }
2138 
2140 {
2141  /* identifiers */
2142  ot->name = "Copy Constraints to Selected Bones";
2143  ot->idname = "POSE_OT_constraints_copy";
2144  ot->description = "Copy constraints to other selected bones";
2145 
2146  /* api callbacks */
2149 
2150  /* flags */
2152 }
2153 
2156 /* ------------------------------------------------------------------- */
2161 {
2162  Main *bmain = CTX_data_main(C);
2163  Object *obact = ED_object_active_context(C);
2164 
2165  /* copy all constraints from active object to all selected objects */
2166  CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) {
2167  /* if we're not handling the object we're copying from, copy all constraints over */
2168  if (obact != ob) {
2169  BKE_constraints_copy(&ob->constraints, &obact->constraints, true);
2171  }
2172  }
2173  CTX_DATA_END;
2174 
2175  /* force depsgraph to get recalculated since new relationships added */
2176  DEG_relations_tag_update(bmain);
2177 
2178  /* notifiers for updates */
2180 
2181  return OPERATOR_FINISHED;
2182 }
2183 
2185 {
2186  /* identifiers */
2187  ot->name = "Copy Constraints to Selected Objects";
2188  ot->idname = "OBJECT_OT_constraints_copy";
2189  ot->description = "Copy constraints to other selected objects";
2190 
2191  /* api callbacks */
2194 
2195  /* flags */
2197 }
2198 
2201 /* ------------------------------------------------------------------- */
2205 /* get the Object and/or PoseChannel to use as target */
2207  bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, bool add)
2208 {
2209  Object *obact = ED_object_active_context(C);
2211  bool only_curve = false, only_mesh = false, only_ob = false;
2212  bool found = false;
2213 
2214  /* clear tar_ob and tar_pchan fields before use
2215  * - assume for now that both always exist...
2216  */
2217  *tar_ob = NULL;
2218  *tar_pchan = NULL;
2219 
2220  /* check if constraint type doesn't requires a target
2221  * - if so, no need to get any targets
2222  */
2223  switch (con_type) {
2224  /* no-target constraints --------------------------- */
2225  /* null constraint - shouldn't even be added! */
2226  case CONSTRAINT_TYPE_NULL:
2227  /* limit constraints - no targets needed */
2232  return false;
2233 
2234  /* restricted target-type constraints -------------- */
2235  /* NOTE: for these, we cannot try to add a target object if no valid ones are found,
2236  * since that doesn't work */
2237  /* curve-based constraints - set the only_curve and only_ob flags */
2241  only_curve = true;
2242  only_ob = true;
2243  add = false;
2244  break;
2245 
2246  /* mesh only? */
2248  only_mesh = true;
2249  only_ob = true;
2250  add = false;
2251  break;
2252  }
2253 
2254  /* if the active Object is Armature, and we can search for bones, do so... */
2255  if ((obact->type == OB_ARMATURE) && (only_ob == false)) {
2256  /* search in list of selected Pose-Channels for target */
2257  CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones_from_active_object) {
2258  /* just use the first one that we encounter, as long as it is not the active one */
2259  if (pchan != pchanact) {
2260  *tar_ob = obact;
2261  *tar_pchan = pchan;
2262  found = true;
2263 
2264  break;
2265  }
2266  }
2267  CTX_DATA_END;
2268  }
2269 
2270  /* if not yet found, try selected Objects... */
2271  if (found == false) {
2272  /* search in selected objects context */
2273  CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
2274  /* just use the first object we encounter (that isn't the active object)
2275  * and which fulfills the criteria for the object-target that we've got
2276  */
2277  if (ob != obact) {
2278  /* for armatures in pose mode, look inside the armature for the active bone
2279  * so that we set up cross-armature constraints with less effort
2280  */
2281  if ((ob->type == OB_ARMATURE) && (ob->mode & OB_MODE_POSE) &&
2282  (!only_curve && !only_mesh)) {
2283 
2284  /* Only use the object & bone if the bone is visible & selected
2285  * since we may have multiple objects in pose mode at once. */
2287  if (pchan != NULL) {
2288  *tar_pchan = pchan;
2289  *tar_ob = ob;
2290  found = true;
2291  }
2292 
2293  break;
2294  }
2295  if (((!only_curve) || (ob->type == OB_CURVES_LEGACY)) &&
2296  ((!only_mesh) || (ob->type == OB_MESH))) {
2297  /* set target */
2298  *tar_ob = ob;
2299  found = true;
2300 
2301  /* perform some special operations on the target */
2302  if (only_curve) {
2303  /* Curve-Path option must be enabled for follow-path constraints to be able to work
2304  */
2305  Curve *cu = (Curve *)ob->data;
2306  cu->flag |= CU_PATH;
2307  }
2308 
2309  break;
2310  }
2311  }
2312  }
2313  CTX_DATA_END;
2314  }
2315 
2316  /* if still not found, add a new empty to act as a target (if allowed) */
2317  if ((found == false) && (add)) {
2318  Main *bmain = CTX_data_main(C);
2319  ViewLayer *view_layer = CTX_data_view_layer(C);
2320  Base *base = BASACT(view_layer);
2321  Object *obt;
2322 
2323  /* add new target object */
2324  obt = BKE_object_add(bmain, view_layer, OB_EMPTY, NULL);
2325 
2326  /* transform cent to global coords for loc */
2327  if (pchanact) {
2328  /* Since by default, IK targets the tip of the last bone,
2329  * use the tip of the active PoseChannel if adding a target for an IK Constraint. */
2330  if (con_type == CONSTRAINT_TYPE_KINEMATIC) {
2331  mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_tail);
2332  }
2333  else {
2334  mul_v3_m4v3(obt->loc, obact->obmat, pchanact->pose_head);
2335  }
2336  }
2337  else {
2338  copy_v3_v3(obt->loc, obact->obmat[3]);
2339  }
2340 
2341  /* restore, BKE_object_add sets active */
2342  BASACT(view_layer) = base;
2344 
2345  /* make our new target the new object */
2346  *tar_ob = obt;
2347  found = true;
2348  }
2349 
2350  /* return whether there's any target */
2351  return found;
2352 }
2353 
2354 /* used by add constraint operators to add the constraint required */
2356  bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, const bool setTarget)
2357 {
2358  Main *bmain = CTX_data_main(C);
2359  bPoseChannel *pchan;
2360  bConstraint *con;
2361 
2362  if (list == &ob->constraints) {
2363  pchan = NULL;
2364  }
2365  else {
2367 
2368  /* ensure not to confuse object/pose adding */
2369  if (pchan == NULL) {
2370  BKE_report(op->reports, RPT_ERROR, "No active pose bone to add a constraint to");
2371  return OPERATOR_CANCELLED;
2372  }
2373  }
2374  /* check if constraint to be added is valid for the given constraints stack */
2375  if (type == CONSTRAINT_TYPE_NULL) {
2376  return OPERATOR_CANCELLED;
2377  }
2378 
2379  /* Create a new constraint of the type required,
2380  * and add it to the active/given constraints list. */
2381  if (pchan) {
2382  con = BKE_constraint_add_for_pose(ob, pchan, NULL, type);
2383  }
2384  else {
2386  }
2387 
2388  /* get the first selected object/bone, and make that the target
2389  * - apart from the buttons-window add buttons, we shouldn't add in this way
2390  */
2391  if (setTarget) {
2392  Object *tar_ob = NULL;
2393  bPoseChannel *tar_pchan = NULL;
2394 
2395  /* get the target objects, adding them as need be */
2396  if (get_new_constraint_target(C, type, &tar_ob, &tar_pchan, 1)) {
2397  /* Method of setting target depends on the type of target we've got - by default,
2398  * just set the first target (distinction here is only for multiple-targeted constraints).
2399  */
2400  if (tar_pchan) {
2401  set_constraint_nth_target(con, tar_ob, tar_pchan->name, 0);
2402  }
2403  else {
2404  set_constraint_nth_target(con, tar_ob, "", 0);
2405  }
2406  }
2407  }
2408 
2409  /* Do type-specific tweaking to the constraint settings. */
2410  switch (type) {
2411  case CONSTRAINT_TYPE_PYTHON: /* FIXME: this code is not really valid anymore */
2412  {
2413 #ifdef WITH_PYTHON
2414  char *menustr;
2415  int scriptint = 0;
2416  /* popup a list of usable scripts */
2417  menustr = buildmenu_pyconstraints(bmain, NULL, &scriptint);
2418  /* XXX scriptint = pupmenu(menustr); */
2419  MEM_freeN(menustr);
2420 
2421  /* only add constraint if a script was chosen */
2422  if (scriptint) {
2423  /* add constraint */
2424  validate_pyconstraint_cb(bmain, con->data, &scriptint);
2425 
2426  /* make sure target allowance is set correctly */
2427  BPY_pyconstraint_update(ob, con);
2428  }
2429 #endif
2430  break;
2431  }
2432 
2433  default:
2434  break;
2435  }
2436 
2437  /* make sure all settings are valid - similar to above checks, but sometimes can be wrong */
2438  object_test_constraints(bmain, ob);
2439 
2440  if (pchan) {
2442  }
2443 
2444  /* force depsgraph to get recalculated since new relationships added */
2445  DEG_relations_tag_update(bmain);
2446 
2447  if ((ob->type == OB_ARMATURE) && (pchan)) {
2448  BKE_pose_tag_recalc(bmain, ob->pose); /* sort pose channels */
2450  }
2451  else {
2453  }
2454 
2455  /* notifiers for updates */
2457 
2458  return OPERATOR_FINISHED;
2459 }
2460 
2461 /* ------------------ */
2462 
2463 /* dummy operator callback */
2465 {
2467  int type = RNA_enum_get(op->ptr, "type");
2468  short with_targets = 0;
2469 
2470  if (!ob) {
2471  BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
2472  return OPERATOR_CANCELLED;
2473  }
2474 
2475  /* hack: set constraint targets from selected objects in context is allowed when
2476  * operator name included 'with_targets', since the menu doesn't allow multiple properties
2477  */
2478  if (strstr(op->idname, "with_targets")) {
2479  with_targets = 1;
2480  }
2481 
2482  return constraint_add_exec(C, op, ob, &ob->constraints, type, with_targets);
2483 }
2484 
2485 /* dummy operator callback */
2487 {
2489  int type = RNA_enum_get(op->ptr, "type");
2490  short with_targets = 0;
2491 
2492  if (!ob) {
2493  BKE_report(op->reports, RPT_ERROR, "No active object to add constraint to");
2494  return OPERATOR_CANCELLED;
2495  }
2496 
2497  /* hack: set constraint targets from selected objects in context is allowed when
2498  * operator name included 'with_targets', since the menu doesn't allow multiple properties
2499  */
2500  if (strstr(op->idname, "with_targets")) {
2501  with_targets = 1;
2502  }
2503 
2504  return constraint_add_exec(C, op, ob, ED_object_constraint_active_list(ob), type, with_targets);
2505 }
2506 
2507 /* ------------------ */
2508 
2509 /* Filters constraints that are only compatible with bones */
2511  PointerRNA *UNUSED(ptr),
2512  PropertyRNA *UNUSED(prop),
2513  bool *r_free)
2514 {
2516  EnumPropertyItem *object_constraint_items = NULL;
2517  int totitem = 0;
2518 
2519  while (item->identifier) {
2521  RNA_enum_item_add(&object_constraint_items, &totitem, item);
2522  }
2523  item++;
2524  }
2525 
2526  RNA_enum_item_end(&object_constraint_items, &totitem);
2527  *r_free = true;
2528 
2529  return object_constraint_items;
2530 }
2531 
2533 {
2534  PropertyRNA *prop;
2535 
2536  /* identifiers */
2537  ot->name = "Add Constraint";
2538  ot->description = "Add a constraint to the active object";
2539  ot->idname = "OBJECT_OT_constraint_add";
2540 
2541  /* api callbacks */
2545 
2546  /* flags */
2548 
2549  /* properties */
2550  prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "");
2552  ot->prop = prop;
2553 }
2554 
2557 /* ------------------------------------------------------------------- */
2562 {
2563  PropertyRNA *prop;
2564 
2565  /* identifiers */
2566  ot->name = "Add Constraint (with Targets)";
2567  ot->description =
2568  "Add a constraint to the active object, with target (where applicable) set to the "
2569  "selected objects/bones";
2570  ot->idname = "OBJECT_OT_constraint_add_with_targets";
2571 
2572  /* api callbacks */
2576 
2577  /* flags */
2579 
2580  /* properties */
2581  prop = RNA_def_enum(ot->srna, "type", DummyRNA_NULL_items, 0, "Type", "");
2583  ot->prop = prop;
2584 }
2585 
2587 {
2588  /* identifiers */
2589  ot->name = "Add Constraint";
2590  ot->description = "Add a constraint to the active bone";
2591  ot->idname = "POSE_OT_constraint_add";
2592 
2593  /* api callbacks */
2597 
2598  /* flags */
2600 
2601  /* properties */
2602  ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
2603 }
2604 
2606 {
2607  /* identifiers */
2608  ot->name = "Add Constraint (with Targets)";
2609  ot->description =
2610  "Add a constraint to the active bone, with target (where applicable) set to the selected "
2611  "Objects/Bones";
2612  ot->idname = "POSE_OT_constraint_add_with_targets";
2613 
2614  /* api callbacks */
2618 
2619  /* flags */
2621 
2622  /* properties */
2623  ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_constraint_type_items, 0, "Type", "");
2624 }
2625 
2628 /* ------------------------------------------------------------------- */
2634 /* TODO: should these be here, or back in editors/armature/poseobject.c again? */
2635 
2636 /* present menu with options + validation for targets to use */
2637 static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
2638 {
2641  bConstraint *con = NULL;
2642 
2643  uiPopupMenu *pup;
2644  uiLayout *layout;
2645  Object *tar_ob = NULL;
2646  bPoseChannel *tar_pchan = NULL;
2647 
2648  /* must have active bone */
2649  if (ELEM(NULL, ob, pchan)) {
2650  BKE_report(op->reports, RPT_ERROR, "Must have an active bone to add IK constraint to");
2651  return OPERATOR_CANCELLED;
2652  }
2653 
2654  /* bone must not have any constraints already */
2655  for (con = pchan->constraints.first; con; con = con->next) {
2656  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2657  break;
2658  }
2659  }
2660  if (con) {
2661  BKE_report(op->reports, RPT_ERROR, "Bone already has an IK constraint");
2662  return OPERATOR_CANCELLED;
2663  }
2664 
2665  /* prepare popup menu to choose targeting options */
2666  pup = UI_popup_menu_begin(C, IFACE_("Add IK"), ICON_NONE);
2667  layout = UI_popup_menu_layout(pup);
2668 
2669  /* the type of targets we'll set determines the menu entries to show... */
2670  if (get_new_constraint_target(C, CONSTRAINT_TYPE_KINEMATIC, &tar_ob, &tar_pchan, 0)) {
2671  /* bone target, or object target?
2672  * - the only thing that matters is that we want a target...
2673  */
2674  if (tar_pchan) {
2676  layout, IFACE_("To Active Bone"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
2677  }
2678  else {
2680  layout, IFACE_("To Active Object"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
2681  }
2682  }
2683  else {
2684  /* we have a choice of adding to a new empty, or not setting any target (targetless IK) */
2686  layout, IFACE_("To New Empty Object"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 1);
2688  layout, IFACE_("Without Targets"), ICON_NONE, "POSE_OT_ik_add", "with_targets", 0);
2689  }
2690 
2691  /* finish building the menu, and process it (should result in calling self again) */
2692  UI_popup_menu_end(C, pup);
2693 
2694  return OPERATOR_INTERFACE;
2695 }
2696 
2697 /* call constraint_add_exec() to add the IK constraint */
2699 {
2701  const bool with_targets = RNA_boolean_get(op->ptr, "with_targets");
2702 
2703  /* add the constraint - all necessary checks should have
2704  * been done by the invoke() callback already... */
2705  return constraint_add_exec(
2706  C, op, ob, ED_object_constraint_active_list(ob), CONSTRAINT_TYPE_KINEMATIC, with_targets);
2707 }
2708 
2710 {
2711  /* identifiers */
2712  ot->name = "Add IK to Bone";
2713  ot->description = "Add IK Constraint to the active Bone";
2714  ot->idname = "POSE_OT_ik_add";
2715 
2716  /* api callbacks */
2720 
2721  /* flags */
2723 
2724  /* properties */
2726  "with_targets",
2727  1,
2728  "With Targets",
2729  "Assign IK Constraint with targets derived from the select bones/objects");
2730 }
2731 
2734 /* ------------------------------------------------------------------- */
2741 {
2742  Object *prev_ob = NULL;
2743 
2744  /* only remove IK Constraints */
2745  CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob) {
2746  bConstraint *con, *next;
2747 
2748  /* TODO: should we be checking if these constraints were local
2749  * before we try and remove them? */
2750  for (con = pchan->constraints.first; con; con = next) {
2751  next = con->next;
2752  if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
2753  BKE_constraint_remove(&pchan->constraints, con);
2754  }
2755  }
2756  pchan->constflag &= ~(PCHAN_HAS_IK | PCHAN_HAS_TARGET);
2757 
2758  if (prev_ob != ob) {
2759  prev_ob = ob;
2760 
2761  /* Refresh depsgraph. */
2763 
2764  /* NOTE: notifier might evolve. */
2766  }
2767  }
2768  CTX_DATA_END;
2769 
2770  return OPERATOR_FINISHED;
2771 }
2772 
2774 {
2775  /* identifiers */
2776  ot->name = "Remove IK";
2777  ot->description = "Remove all IK Constraints from selected bones";
2778  ot->idname = "POSE_OT_ik_clear";
2779 
2780  /* api callbacks */
2783 
2784  /* flags */
2786 }
2787 
typedef float(TangentPoint)[2]
void BIK_test_constraint(struct Object *ob, struct bConstraint *cons)
Definition: ikplugin_api.c:121
Blender kernel action and pose functionality.
void BKE_pose_tag_recalc(struct Main *bmain, struct bPose *pose)
Definition: action.c:1719
struct bPoseChannel * BKE_pose_channel_active_or_first_selected(struct Object *ob)
Definition: action.c:725
struct bPoseChannel * BKE_pose_channel_active_if_layer_visible(struct Object *ob)
Definition: action.c:720
void BKE_pose_tag_update_constraint_flags(struct bPose *pose)
Definition: action.c:1259
void BKE_pose_update_constraint_flags(struct bPose *pose)
Definition: action.c:1192
struct Bone * BKE_armature_find_bone_name(struct bArmature *arm, const char *name)
Definition: armature.c:594
struct bArmature * BKE_armature_from_object(struct Object *ob)
Definition: armature.c:342
bool BKE_constraint_remove(ListBase *list, struct bConstraint *con)
Definition: constraint.c:5592
struct bConstraint * BKE_constraint_copy_for_object(struct Object *ob, struct bConstraint *src)
Definition: constraint.c:5966
void BKE_constraints_free(struct ListBase *list)
Definition: constraint.c:5587
void BKE_constraint_targets_flush(struct bConstraint *con, struct ListBase *targets, bool no_copy)
Definition: constraint.c:6186
struct bConstraint * BKE_constraint_add_for_object(struct Object *ob, const char *name, short type)
Definition: constraint.c:5870
struct bConstraint * BKE_constraints_find_name(struct ListBase *list, const char *name)
Definition: constraint.c:5996
int BKE_constraint_targets_get(struct bConstraint *con, struct ListBase *r_targets)
Definition: constraint.c:6157
void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern)
bool BKE_constraint_remove_ex(ListBase *list, struct Object *ob, struct bConstraint *con, bool clear_dep)
Definition: constraint.c:5603
bool BKE_constraint_apply_and_remove_for_pose(struct Depsgraph *depsgraph, struct Scene *scene, ListBase *constraints, struct Object *ob, struct bConstraint *con, struct bPoseChannel *pchan)
Definition: constraint.c:5720
bool BKE_constraint_is_nonlocal_in_liboverride(const struct Object *ob, const struct bConstraint *con)
bool BKE_constraint_apply_and_remove_for_object(struct Depsgraph *depsgraph, struct Scene *scene, ListBase *constraints, struct Object *ob, struct bConstraint *con)
Definition: constraint.c:5658
struct bConstraint * BKE_constraints_active_get(struct ListBase *list)
Definition: constraint.c:6001
struct bConstraint * BKE_constraint_copy_for_pose(struct Object *ob, struct bPoseChannel *pchan, struct bConstraint *src)
Definition: constraint.c:5955
void BKE_constraints_active_set(ListBase *list, struct bConstraint *con)
Definition: constraint.c:6017
struct bConstraint * BKE_constraint_add_for_pose(struct Object *ob, struct bPoseChannel *pchan, const char *name, short type)
Definition: constraint.c:5858
#define CTX_DATA_BEGIN_WITH_ID(C, Type, instance, member, Type_id, instance_id)
Definition: BKE_context.h:284
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
Definition: context.c:462
#define CTX_DATA_BEGIN(C, Type, instance, member)
Definition: BKE_context.h:269
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
Definition: context.c:473
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
void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg)
Definition: context.c:1042
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
#define CTX_DATA_END
Definition: BKE_context.h:278
struct bPoseChannel * CTX_data_active_pose_bone(const bContext *C)
Definition: context.c:1425
struct FModifier * add_fmodifier(ListBase *modifiers, int type, struct FCurve *owner_fcu)
Definition: fmodifier.c:1087
struct FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], int array_index)
Definition: fcurve.c:249
@ G_DEBUG
Definition: BKE_global.h:174
General operations, lookup, etc. for blender objects.
void BKE_object_eval_constraints(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
Definition: object_update.c:99
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.cc:2511
struct Object * BKE_object_add(struct Main *bmain, struct ViewLayer *view_layer, int type, const char *name) ATTR_NONNULL(1
bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
struct MovieTrackingTrack * BKE_tracking_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, const char *name)
Definition: tracking.c:1038
struct MovieTrackingObject * BKE_tracking_object_get_named(struct MovieTracking *tracking, const char *name)
Definition: tracking.c:2077
struct MovieTrackingObject * BKE_tracking_object_get_camera(struct MovieTracking *tracking)
Definition: tracking.c:2097
#define BLI_assert(a)
Definition: BLI_assert.h:46
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:50
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:256
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition: BLI_dynstr.c:281
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition: BLI_dynstr.c:75
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void void void bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) ATTR_NONNULL()
Definition: listbase.c:405
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:340
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void unit_m4(float m[4][4])
Definition: rct.c:1090
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
MINLINE void copy_v3_v3(float r[3], const float a[3])
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
#define UNUSED_VARS(...)
#define UNUSED(x)
#define ELEM(...)
#define STREQ(a, b)
#define IFACE_(msgid)
int BPY_is_pyconstraint(struct Text *text)
void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con)
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 Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ ID_OB
Definition: DNA_ID_enums.h:47
@ PCHAN_HAS_CONST
@ PCHAN_HAS_IK
@ PCHAN_HAS_TARGET
@ PCHAN_HAS_SPLINEIK
@ FMODIFIER_TYPE_GENERATOR
@ CONSTRAINT_OFF
@ CONSTRAINT_OVERRIDE_LIBRARY_LOCAL
@ CONSTRAINT_ACTIVE
@ CONSTRAINT_DISABLE
@ CONSTRAINT_TYPE_TRACKTO
@ CONSTRAINT_TYPE_PIVOT
@ CONSTRAINT_TYPE_CHILDOF
@ CONSTRAINT_TYPE_FOLLOWTRACK
@ CONSTRAINT_TYPE_OBJECTSOLVER
@ CONSTRAINT_TYPE_ARMATURE
@ CONSTRAINT_TYPE_SHRINKWRAP
@ CONSTRAINT_TYPE_ROTLIMIT
@ CONSTRAINT_TYPE_CAMERASOLVER
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_TYPE_PYTHON
@ CONSTRAINT_TYPE_KINEMATIC
@ CONSTRAINT_TYPE_NULL
@ CONSTRAINT_TYPE_DISTLIMIT
@ CONSTRAINT_TYPE_LOCLIMIT
@ CONSTRAINT_TYPE_CLAMPTO
@ CONSTRAINT_TYPE_LOCKTRACK
@ CONSTRAINT_TYPE_SIZELIMIT
@ CONSTRAINT_TYPE_ACTION
@ CONSTRAINT_TYPE_FOLLOWPATH
@ CONSTRAINT_TYPE_STRETCHTO
@ CONSTRAINT_TYPE_SAMEVOL
@ CONSTRAINT_TYPE_TRANSFORM_CACHE
@ CONSTRAINT_OBTYPE_OBJECT
@ CONSTRAINT_OBTYPE_BONE
@ CAMERASOLVER_ACTIVECLIP
@ ACTCON_USE_EVAL_TIME
@ FOLLOWPATH_STATIC
@ CONSTRAINT_SPLINEIK_BOUND
@ OBJECTSOLVER_SET_INVERSE
@ CHILDOF_SET_INVERSE
@ CU_PATH
#define MAX_NAME
Definition: DNA_defs.h:48
@ OB_MODE_POSE
Object is a sort of wrapper for general info.
@ OB_EMPTY
@ OB_ARMATURE
@ OB_MESH
@ OB_CURVES_LEGACY
#define MINAFRAME
#define BASACT(_view_layer)
#define MAXFRAME
@ OPERATOR_CANCELLED
@ OPERATOR_INTERFACE
@ OPERATOR_FINISHED
@ OPERATOR_PASS_THROUGH
void ED_object_base_select(struct Base *base, eObjectSelect_Mode mode)
Definition: object_select.c:76
struct Object * ED_object_active_context(const struct bContext *C)
@ BA_SELECT
Definition: ED_object.h:155
bool ED_operator_object_active_local_editable(struct bContext *C)
Definition: screen_ops.c:407
bool ED_operator_object_active_editable_ex(struct bContext *C, const Object *ob)
Definition: screen_ops.c:376
bool ED_operator_object_active_local_editable_posemode_exclusive(struct bContext *C)
Definition: screen_ops.c:501
bool ED_operator_object_active_editable(struct bContext *C)
Definition: screen_ops.c:396
bool ED_operator_posemode_exclusive(struct bContext *C)
Definition: screen_ops.c:494
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
@ PROP_HIDDEN
Definition: RNA_types.h:216
#define C
Definition: RandGen.cpp:25
void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value)
struct uiLayout * UI_popup_menu_layout(uiPopupMenu *pup)
struct PointerRNA * UI_region_panel_custom_data_under_cursor(const struct bContext *C, const struct wmEvent *event)
void UI_popup_menu_end(struct bContext *C, struct uiPopupMenu *pup)
uiPopupMenu * UI_popup_menu_begin(struct bContext *C, const char *title, int icon) ATTR_NONNULL()
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NA_ADDED
Definition: WM_types.h:525
#define ND_POSE
Definition: WM_types.h:407
#define ND_CONSTRAINT
Definition: WM_types.h:413
#define NA_REMOVED
Definition: WM_types.h:526
#define ND_TRANSFORM
Definition: WM_types.h:405
#define NC_OBJECT
Definition: WM_types.h:329
#define A
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint ** constraints
Scene scene
const Depsgraph * depsgraph
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
int len
Definition: draw_manager.c:108
#define str(s)
bAction * ED_id_action_ensure(Main *bmain, ID *id)
Definition: keyframing.c:123
FCurve * ED_action_fcurve_ensure(struct Main *bmain, struct bAction *act, const char group[], struct PointerRNA *ptr, const char rna_path[], const int array_index)
Definition: keyframing.c:173
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
static ulong * next
#define B
#define G(x, y, z)
bool add(void *owner, const AttributeIDRef &attribute_id, eAttrDomain domain, eCustomDataType data_type, const AttributeInit &initializer)
T abs(const T &a)
void CONSTRAINT_OT_move_to_index(wmOperatorType *ot)
static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase *list, int type, const bool setTarget)
static int followpath_path_animate_exec(bContext *C, wmOperator *op)
static int followpath_path_animate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static const EnumPropertyItem constraint_owner_items[]
static bool edit_constraint_invoke_properties(bContext *C, wmOperator *op, const wmEvent *event, int *r_retval)
static int stretchto_reset_exec(bContext *C, wmOperator *op)
void ED_object_constraint_active_set(Object *ob, bConstraint *con)
void ED_object_constraint_update(Main *bmain, Object *ob)
static void set_constraint_nth_target(bConstraint *con, Object *target, const char subtarget[], int index)
void OBJECT_OT_constraints_copy(wmOperatorType *ot)
void ED_object_constraint_tag_update(Main *bmain, Object *ob, bConstraint *con)
static bool constraint_copy_to_selected_poll(bContext *C)
void ED_object_constraint_copy_for_pose(Main *bmain, Object *ob_dst, bPoseChannel *pchan, bConstraint *con)
static int constraint_move_to_index_exec(bContext *C, wmOperator *op)
void CONSTRAINT_OT_copy(wmOperatorType *ot)
static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
void ED_object_constraint_copy_for_object(Main *bmain, Object *ob_dst, bConstraint *con)
static void force_evaluation_if_constraint_disabled(bContext *C, Object *ob, bConstraint *con)
static int constraint_copy_to_selected_exec(bContext *C, wmOperator *op)
void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot)
static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
static bool edit_constraint_liboverride_allowed_poll(bContext *C)
static int object_constraint_add_exec(bContext *C, wmOperator *op)
void CONSTRAINT_OT_delete(wmOperatorType *ot)
void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot)
static int stretchto_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type, const bool is_liboverride_allowed)
static void object_test_constraint(Main *bmain, Object *ob, bConstraint *con)
bool ED_object_constraint_move_to_index(Object *ob, bConstraint *con, const int index)
void POSE_OT_constraints_copy(wmOperatorType *ot)
#define EDIT_CONSTRAINT_OWNER_BONE
static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void CONSTRAINT_OT_copy_to_selected(wmOperatorType *ot)
static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
#define EDIT_CONSTRAINT_OWNER_OBJECT
static int constraint_move_down_exec(bContext *C, wmOperator *op)
void CONSTRAINT_OT_objectsolver_set_inverse(wmOperatorType *ot)
void OBJECT_OT_constraints_clear(wmOperatorType *ot)
void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot)
static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void CONSTRAINT_OT_move_down(wmOperatorType *ot)
static int childof_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static const EnumPropertyItem * object_constraint_add_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
bConstraint * ED_object_constraint_active_get(Object *ob)
static void object_pose_tag_update(Main *bmain, Object *ob)
void POSE_OT_constraints_clear(wmOperatorType *ot)
static int pose_constraint_add_exec(bContext *C, wmOperator *op)
static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
void OBJECT_OT_constraint_add(wmOperatorType *ot)
static int constraint_move_to_index_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void ED_object_constraint_dependency_update(Main *bmain, Object *ob)
void CONSTRAINT_OT_apply(wmOperatorType *ot)
static int constraint_apply_exec(bContext *C, wmOperator *op)
static void edit_constraint_report_property(wmOperatorType *ot)
static int pose_ik_clear_exec(bContext *C, wmOperator *UNUSED(op))
void ED_object_constraint_link(Main *bmain, Object *ob_dst, ListBase *dst, ListBase *src)
static int limitdistance_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static void test_constraint(Main *bmain, Object *owner, bPoseChannel *pchan, bConstraint *con, int type)
void CONSTRAINT_OT_move_up(wmOperatorType *ot)
static int object_constraint_copy_exec(bContext *C, wmOperator *UNUSED(op))
static bool edit_constraint_poll(bContext *C)
static void test_constraints(Main *bmain, Object *ob, bPoseChannel *pchan)
void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstraint *con)
static int limitdistance_reset_exec(bContext *C, wmOperator *op)
static int pose_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op))
static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob, bPoseChannel **tar_pchan, bool add)
static int constraint_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
static int childof_set_inverse_exec(bContext *C, wmOperator *op)
static int pose_constraint_copy_exec(bContext *C, wmOperator *op)
static int pose_ik_add_exec(bContext *C, wmOperator *op)
void POSE_OT_constraint_add(wmOperatorType *ot)
void POSE_OT_ik_add(wmOperatorType *ot)
static int constraint_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ListBase * ED_object_constraint_active_list(Object *ob)
ListBase * ED_object_constraint_list_from_constraint(Object *ob, bConstraint *con, bPoseChannel **r_pchan)
static void edit_constraint_properties(wmOperatorType *ot)
void POSE_OT_ik_clear(wmOperatorType *ot)
ListBase * ED_object_pose_constraint_list(const bContext *C)
static int constraint_copy_exec(bContext *C, wmOperator *op)
static int constraint_move_up_exec(bContext *C, wmOperator *op)
void object_test_constraints(Main *bmain, Object *ob)
static int constraint_delete_exec(bContext *C, wmOperator *op)
void CONSTRAINT_OT_followpath_path_animate(wmOperatorType *ot)
void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot)
static int constraint_type_get(Object *owner, bPoseChannel *pchan)
void CONSTRAINT_OT_objectsolver_clear_inverse(wmOperatorType *ot)
static bConstraint * edit_constraint_property_get(bContext *C, wmOperator *op, Object *ob, int type)
void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot)
static int constraint_apply_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int constraint_copy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int constraint_copy_to_selected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
bool is_liboverride_allowed
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
Definition: rna_access.c:695
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:136
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:5116
int RNA_int_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4910
bool RNA_pointer_is_null(const PointerRNA *ptr)
Definition: rna_access.c:164
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:5301
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
Definition: rna_access.c:5015
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
const EnumPropertyItem rna_enum_constraint_type_items[]
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
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
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, int maxlen, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3687
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
Definition: rna_define.c:3597
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
char * RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_path.cc:1127
const EnumPropertyItem DummyRNA_NULL_items[]
Definition: rna_rna.c:26
bAction * action
struct AnimData * adt
const char * identifier
Definition: RNA_types.h:461
FPoint * fpt
BezTriple * bezt
ListBase modifiers
float * coefficients
void * data
Definition: DNA_ID.h:368
void * next
Definition: DNA_ID.h:369
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ListBase texts
Definition: BKE_main.h:185
ListBase constraints
struct bPose * pose
float loc[3]
float obmat[4][4]
void * data
struct StructRNA * type
Definition: RNA_types.h:37
void * data
Definition: RNA_types.h:38
struct ID * owner_id
Definition: RNA_types.h:36
ListBase curves
struct bConstraintTarget * next
struct bConstraint * prev
struct bConstraint * next
ListBase constraints
float pose_head[3]
float pose_tail[3]
struct bPoseChannel * next
ListBase chanbase
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
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_main_add_notifier(unsigned int type, void *reference)
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
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))