Blender  V2.93
deg_builder_nodes_rig.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2013 Blender Foundation.
17  * All rights reserved.
18  */
19 
27 
28 #include <cstdio>
29 #include <cstdlib>
30 
31 #include "MEM_guardedalloc.h"
32 
33 #include "BLI_blenlib.h"
34 #include "BLI_string.h"
35 #include "BLI_utildefines.h"
36 
37 #include "DNA_anim_types.h"
38 #include "DNA_armature_types.h"
39 #include "DNA_constraint_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42 
43 #include "BKE_action.h"
44 #include "BKE_armature.h"
45 #include "BKE_constraint.h"
46 
47 #include "DEG_depsgraph.h"
48 #include "DEG_depsgraph_build.h"
49 
51 #include "intern/depsgraph_type.h"
53 #include "intern/node/deg_node.h"
56 
57 namespace blender::deg {
58 
60  bPoseChannel *pchan,
61  int pchan_index,
62  bool is_object_visible)
63 {
64  /* Pull indirect dependencies via constraints. */
66  data.builder = this;
67  data.is_parent_visible = is_object_visible;
69 
70  /* Create node for constraint stack. */
71  Scene *scene_cow = get_cow_datablock(scene_);
72  Object *object_cow = get_cow_datablock(object);
73  add_operation_node(&object->id,
75  pchan->name,
77  [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
78  BKE_pose_constraints_evaluate(
79  depsgraph, scene_cow, object_cow, pchan_index);
80  });
81 }
82 
83 /* IK Solver Eval Steps */
85 {
87 
88  /* Find the chain's root. */
90  if (rootchan == nullptr) {
91  return;
92  }
93 
95  &object->id, NodeType::EVAL_POSE, rootchan->name, OperationCode::POSE_IK_SOLVER)) {
96  return;
97  }
98 
99  int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
100  BLI_assert(rootchan_index != -1);
101 
102  /* Operation node for evaluating/running IK Solver. */
103  Scene *scene_cow = get_cow_datablock(scene_);
104  Object *object_cow = get_cow_datablock(object);
105  add_operation_node(&object->id,
107  rootchan->name,
109  [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
110  BKE_pose_iktree_evaluate(depsgraph, scene_cow, object_cow, rootchan_index);
111  });
112 }
113 
114 /* Spline IK Eval Steps */
116  bPoseChannel *pchan,
117  bConstraint *con)
118 {
120 
121  /* Find the chain's root. */
123 
124  if (has_operation_node(&object->id,
126  rootchan->name,
128  return;
129  }
130 
131  /* Operation node for evaluating/running Spline IK Solver.
132  * Store the "root bone" of this chain in the solver, so it knows where to
133  * start. */
134  int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
135  BLI_assert(rootchan_index != -1);
136 
137  Scene *scene_cow = get_cow_datablock(scene_);
138  Object *object_cow = get_cow_datablock(object);
139  add_operation_node(&object->id,
141  rootchan->name,
143  [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
144  BKE_pose_splineik_evaluate(
145  depsgraph, scene_cow, object_cow, rootchan_index);
146  });
147 }
148 
149 /* Pose/Armature Bones Graph */
150 void DepsgraphNodeBuilder::build_rig(Object *object, bool is_object_visible)
151 {
152  bArmature *armature = (bArmature *)object->data;
153  Scene *scene_cow = get_cow_datablock(scene_);
154  Object *object_cow = get_cow_datablock(object);
155  OperationNode *op_node;
156  /* Animation and/or drivers linking pose-bones to base-armature used to define them.
157  *
158  * NOTE: AnimData here is really used to control animated deform properties,
159  * which ideally should be able to be unique across different
160  * instances. Eventually, we need some type of proxy/isolation
161  * mechanism in-between here to ensure that we can use same rig
162  * multiple times in same scene. */
163  /* Armature. */
164  build_armature(armature);
165  /* Rebuild pose if not up to date. */
166  if (object->pose == nullptr || (object->pose->flag & POSE_RECALC)) {
167  /* By definition, no need to tag depsgraph as dirty from here, so we can pass nullptr bmain. */
168  BKE_pose_rebuild(nullptr, object, armature, true);
169  }
170  /* Speed optimization for animation lookups. */
171  if (object->pose != nullptr) {
175  }
176  }
197  /* Pose eval context. */
198  op_node = add_operation_node(&object->id,
201  [scene_cow, object_cow](::Depsgraph *depsgraph) {
202  BKE_pose_eval_init(depsgraph, scene_cow, object_cow);
203  });
204  op_node->set_as_entry();
205 
206  op_node = add_operation_node(&object->id,
209  [scene_cow, object_cow](::Depsgraph *depsgraph) {
210  BKE_pose_eval_init_ik(depsgraph, scene_cow, object_cow);
211  });
212 
213  add_operation_node(&object->id,
216  [scene_cow, object_cow](::Depsgraph *depsgraph) {
217  BKE_pose_eval_cleanup(depsgraph, scene_cow, object_cow);
218  });
219 
220  op_node = add_operation_node(
221  &object->id,
224  [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_done(depsgraph, object_cow); });
225  op_node->set_as_exit();
226  /* Bones. */
227  int pchan_index = 0;
228  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
229  /* Node for bone evaluation. */
230  op_node = add_operation_node(
231  &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
232  op_node->set_as_entry();
233 
234  add_operation_node(&object->id,
236  pchan->name,
238  [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
239  BKE_pose_eval_bone(depsgraph, scene_cow, object_cow, pchan_index);
240  });
241 
242  /* NOTE: Dedicated noop for easier relationship construction. */
244 
245  op_node = add_operation_node(&object->id,
247  pchan->name,
249  [object_cow, pchan_index](::Depsgraph *depsgraph) {
250  BKE_pose_bone_done(depsgraph, object_cow, pchan_index);
251  });
252 
253  /* B-Bone shape computation - the real last step if present. */
254  if (check_pchan_has_bbone(object, pchan)) {
255  op_node = add_operation_node(&object->id,
257  pchan->name,
259  [object_cow, pchan_index](::Depsgraph *depsgraph) {
260  BKE_pose_eval_bbone_segments(
261  depsgraph, object_cow, pchan_index);
262  });
263  }
264 
265  op_node->set_as_exit();
266 
267  /* Custom properties. */
268  if (pchan->prop != nullptr) {
269  build_idproperties(pchan->prop);
271  &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
272  }
273  /* Build constraints. */
274  if (pchan->constraints.first != nullptr) {
275  build_pose_constraints(object, pchan, pchan_index, is_object_visible);
276  }
288  LISTBASE_FOREACH (bConstraint *, con, &pchan->constraints) {
289  switch (con->type) {
291  build_ik_pose(object, pchan, con);
292  break;
293 
295  build_splineik_pose(object, pchan, con);
296  break;
297 
298  default:
299  break;
300  }
301  }
302  /* Custom shape. */
303  if (pchan->custom != nullptr) {
304  /* TODO(sergey): Use own visibility. */
305  build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
306  }
307  pchan_index++;
308  }
309 }
310 
311 void DepsgraphNodeBuilder::build_proxy_rig(Object *object, bool is_object_visible)
312 {
313  bArmature *armature = (bArmature *)object->data;
314  OperationNode *op_node;
315  Object *object_cow = get_cow_datablock(object);
316  /* Sanity check. */
317  BLI_assert(object->pose != nullptr);
318  /* Armature. */
319  build_armature(armature);
320  /* speed optimization for animation lookups */
324  }
325  op_node = add_operation_node(
326  &object->id,
329  [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_init(depsgraph, object_cow); });
330  op_node->set_as_entry();
331 
332  int pchan_index = 0;
333  LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
334  op_node = add_operation_node(
335  &object->id, NodeType::BONE, pchan->name, OperationCode::BONE_LOCAL);
336  op_node->set_as_entry();
337  /* Bone is ready for solvers. */
339  /* Bone is fully evaluated. */
340  op_node = add_operation_node(&object->id,
342  pchan->name,
344  [object_cow, pchan_index](::Depsgraph *depsgraph) {
345  BKE_pose_eval_proxy_copy_bone(
346  depsgraph, object_cow, pchan_index);
347  });
348  op_node->set_as_exit();
349 
350  /* Custom properties. */
351  if (pchan->prop != nullptr) {
352  build_idproperties(pchan->prop);
354  &object->id, NodeType::PARAMETERS, OperationCode::PARAMETERS_EVAL, nullptr, pchan->name);
355  }
356 
357  /* Custom shape. */
358  if (pchan->custom != nullptr) {
359  build_object(-1, pchan->custom, DEG_ID_LINKED_INDIRECTLY, is_object_visible);
360  }
361 
362  pchan_index++;
363  }
364  op_node = add_operation_node(&object->id,
367  [object_cow](::Depsgraph *depsgraph) {
368  BKE_pose_eval_proxy_cleanup(depsgraph, object_cow);
369  });
370  op_node = add_operation_node(
371  &object->id,
374  [object_cow](::Depsgraph *depsgraph) { BKE_pose_eval_proxy_done(depsgraph, object_cow); });
375  op_node->set_as_exit();
376 }
377 
378 } // namespace blender::deg
Blender kernel action and pose functionality.
void BKE_pose_channels_hash_make(struct bPose *pose)
Definition: action.c:948
void BKE_pose_update_constraint_flags(struct bPose *pose)
Definition: action.c:1247
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, const bool do_id_user)
Definition: armature.c:2536
struct bPoseChannel * BKE_armature_ik_solver_find_root(struct bPoseChannel *pchan, struct bKinematicConstraint *data)
Definition: armature.c:2910
struct bPoseChannel * BKE_armature_splineik_solver_find_root(struct bPoseChannel *pchan, struct bSplineIKConstraint *data)
Definition: armature.c:2931
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata)
Definition: constraint.c:5680
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
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(Object *object, const bPoseChannel *pchan)
Definition: deg_builder.cc:106
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_pose_constraints(Object *object, bPoseChannel *pchan, int pchan_index, bool is_object_visible)
virtual void build_proxy_rig(Object *object, bool is_object_visible)
virtual void build_rig(Object *object, bool is_object_visible)
virtual void build_ik_pose(Object *object, bPoseChannel *pchan, bConstraint *con)
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:42
struct bPose * pose
void * data
ListBase constraints
ListBase chanbase
short flag