Blender  V3.3
deg_builder_nodes_rig.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2013 Blender Foundation. All rights reserved. */
3 
11 
12 #include <cstdio>
13 #include <cstdlib>
14 
15 #include "MEM_guardedalloc.h"
16 
17 #include "BLI_blenlib.h"
18 #include "BLI_string.h"
19 #include "BLI_utildefines.h"
20 
21 #include "DNA_anim_types.h"
22 #include "DNA_armature_types.h"
23 #include "DNA_constraint_types.h"
24 #include "DNA_object_types.h"
25 #include "DNA_scene_types.h"
26 
27 #include "BKE_action.h"
28 #include "BKE_armature.h"
29 #include "BKE_constraint.h"
30 
31 #include "DEG_depsgraph.h"
32 #include "DEG_depsgraph_build.h"
33 
35 #include "intern/depsgraph_type.h"
37 #include "intern/node/deg_node.h"
40 
41 namespace blender::deg {
42 
44  bPoseChannel *pchan,
45  int pchan_index)
46 {
47  /* Pull indirect dependencies via constraints. */
49  data.builder = this;
51 
52  /* Create node for constraint stack. */
53  Scene *scene_cow = get_cow_datablock(scene_);
54  Object *object_cow = get_cow_datablock(object);
55  add_operation_node(&object->id,
57  pchan->name,
59  [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
60  BKE_pose_constraints_evaluate(
61  depsgraph, scene_cow, object_cow, pchan_index);
62  });
63 }
64 
65 /* IK Solver Eval Steps */
67 {
69 
70  /* Find the chain's root. */
72  if (rootchan == nullptr) {
73  return;
74  }
75 
77  &object->id, NodeType::EVAL_POSE, rootchan->name, OperationCode::POSE_IK_SOLVER)) {
78  return;
79  }
80 
81  int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
82  BLI_assert(rootchan_index != -1);
83 
84  /* Operation node for evaluating/running IK Solver. */
85  Scene *scene_cow = get_cow_datablock(scene_);
86  Object *object_cow = get_cow_datablock(object);
87  add_operation_node(&object->id,
89  rootchan->name,
91  [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
92  BKE_pose_iktree_evaluate(depsgraph, scene_cow, object_cow, rootchan_index);
93  });
94 }
95 
96 /* Spline IK Eval Steps */
98  bPoseChannel *pchan,
99  bConstraint *con)
100 {
102 
103  /* Find the chain's root. */
105 
106  if (has_operation_node(&object->id,
108  rootchan->name,
110  return;
111  }
112 
113  /* Operation node for evaluating/running Spline IK Solver.
114  * Store the "root bone" of this chain in the solver, so it knows where to
115  * start. */
116  int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
117  BLI_assert(rootchan_index != -1);
118 
119  Scene *scene_cow = get_cow_datablock(scene_);
120  Object *object_cow = get_cow_datablock(object);
121  add_operation_node(&object->id,
123  rootchan->name,
125  [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
126  BKE_pose_splineik_evaluate(
127  depsgraph, scene_cow, object_cow, rootchan_index);
128  });
129 }
130 
131 /* Pose/Armature Bones Graph */
133 {
134  bArmature *armature = (bArmature *)object->data;
135  Scene *scene_cow = get_cow_datablock(scene_);
136  Object *object_cow = get_cow_datablock(object);
137  OperationNode *op_node;
138  /* Animation and/or drivers linking pose-bones to base-armature used to define them.
139  *
140  * NOTE: AnimData here is really used to control animated deform properties,
141  * which ideally should be able to be unique across different
142  * instances. Eventually, we need some type of proxy/isolation
143  * mechanism in-between here to ensure that we can use same rig
144  * multiple times in same scene. */
145  /* Armature. */
146  build_armature(armature);
147  /* Rebuild pose if not up to date. */
148  if (object->pose == nullptr || (object->pose->flag & POSE_RECALC)) {
149  /* By definition, no need to tag depsgraph as dirty from here, so we can pass nullptr bmain. */
150  BKE_pose_rebuild(nullptr, object, armature, true);
151  }
152  /* Speed optimization for animation lookups. */
153  if (object->pose != nullptr) {
157  }
158  }
179  /* Pose eval context. */
180  op_node = add_operation_node(&object->id,
183  [scene_cow, object_cow](::Depsgraph *depsgraph) {
184  BKE_pose_eval_init(depsgraph, scene_cow, object_cow);
185  });
186  op_node->set_as_entry();
187 
188  op_node = add_operation_node(&object->id,
191  [scene_cow, object_cow](::Depsgraph *depsgraph) {
192  BKE_pose_eval_init_ik(depsgraph, scene_cow, object_cow);
193  });
194 
195  add_operation_node(&object->id,
198  [scene_cow, object_cow](::Depsgraph *depsgraph) {
199  BKE_pose_eval_cleanup(depsgraph, scene_cow, object_cow);
200  });
201 
202  op_node = add_operation_node(
203  &object->id,
206  [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_done(depsgraph, object_cow); });
207  op_node->set_as_exit();
208  /* Bones. */
209  int pchan_index = 0;
210  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
211  /* Node for bone evaluation. */
212  op_node = add_operation_node(
213  &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
214  op_node->set_as_entry();
215 
216  add_operation_node(&object->id,
218  pchan->name,
220  [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
221  BKE_pose_eval_bone(depsgraph, scene_cow, object_cow, pchan_index);
222  });
223 
224  /* NOTE: Dedicated noop for easier relationship construction. */
226 
227  op_node = add_operation_node(&object->id,
229  pchan->name,
231  [object_cow, pchan_index](::Depsgraph *depsgraph) {
232  BKE_pose_bone_done(depsgraph, object_cow, pchan_index);
233  });
234 
235  /* B-Bone shape computation - the real last step if present. */
236  if (check_pchan_has_bbone(object, pchan)) {
237  op_node = add_operation_node(&object->id,
239  pchan->name,
241  [object_cow, pchan_index](::Depsgraph *depsgraph) {
242  BKE_pose_eval_bbone_segments(
243  depsgraph, object_cow, pchan_index);
244  });
245  }
246 
247  op_node->set_as_exit();
248 
249  /* Custom properties. */
250  if (pchan->prop != nullptr) {
251  build_idproperties(pchan->prop);
253  &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
254  }
255  /* Build constraints. */
256  if (pchan->constraints.first != nullptr) {
257  build_pose_constraints(object, pchan, pchan_index);
258  }
270  LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
271  switch (con->type) {
273  build_ik_pose(object, pchan, con);
274  break;
275 
277  build_splineik_pose(object, pchan, con);
278  break;
279 
280  default:
281  break;
282  }
283  }
284  /* Custom shape. */
285  if (pchan->custom != nullptr) {
286  /* NOTE: The relation builder will ensure visibility of the custom shape object. */
287  build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY, false);
288  }
289  pchan_index++;
290  }
291 }
292 
293 } // namespace blender::deg
Blender kernel action and pose functionality.
void BKE_pose_channels_hash_ensure(struct bPose *pose)
Definition: action.c:925
void BKE_pose_update_constraint_flags(struct bPose *pose)
Definition: action.c:1192
struct bPoseChannel * BKE_armature_ik_solver_find_root(struct bPoseChannel *pchan, struct bKinematicConstraint *data)
Definition: armature.c:2740
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, bool do_id_user)
Definition: armature.c:2362
struct bPoseChannel * BKE_armature_splineik_solver_find_root(struct bPoseChannel *pchan, struct bSplineIKConstraint *data)
Definition: armature.c:2761
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata)
Definition: constraint.c:5877
#define BLI_assert(a)
Definition: BLI_assert.h:46
#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)
@ POSE_CONSTRAINTS_NEED_UPDATE_FLAGS
@ POSE_RECALC
@ CONSTRAINT_TYPE_SPLINEIK
@ CONSTRAINT_TYPE_KINEMATIC
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
virtual bool check_pchan_has_bbone(const Object *object, const bPoseChannel *pchan)
Definition: deg_builder.cc:98
virtual void build_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index)
virtual void build_object(int base_index, Object *object, eDepsNode_LinkedState_Type linked_state, bool is_visible)
OperationNode * add_operation_node(ComponentNode *comp_node, OperationCode opcode, const DepsEvalOperationCb &op=nullptr, const char *name="", int name_tag=-1)
static void constraint_walk(bConstraint *constraint, ID **idpoin, bool is_reference, void *user_data)
virtual void build_armature(bArmature *armature)
virtual void build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
virtual void build_rig(Object *object)
virtual void build_splineik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
virtual void build_idproperties(IDProperty *id_property)
bool has_operation_node(ID *id, NodeType comp_type, const char *comp_name, OperationCode opcode, const char *name="", int name_tag=-1)
T * get_cow_datablock(const T *orig) const
const Depsgraph * depsgraph
@ DEG_ID_LINKED_INDIRECTLY
Definition: deg_node_id.h:25
struct bPose * pose
void * data
ListBase constraints
ListBase chanbase
short flag