Blender V4.3
deg_builder_nodes_rig.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2013 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
12
13#include <cstdio>
14#include <cstdlib>
15
16#include "MEM_guardedalloc.h"
17
18#include "BLI_blenlib.h"
19#include "BLI_string.h"
20#include "BLI_utildefines.h"
21
22#include "DNA_anim_types.h"
23#include "DNA_armature_types.h"
25#include "DNA_object_types.h"
26#include "DNA_scene_types.h"
27
28#include "BKE_action.hh"
29#include "BKE_armature.hh"
30#include "BKE_constraint.h"
31#include "BKE_lib_query.hh"
32
33#include "DEG_depsgraph.hh"
35
42
43namespace blender::deg {
44
46 bPoseChannel *pchan,
47 int pchan_index)
48{
49 /* Pull indirect dependencies via constraints. */
51 data.builder = this;
53
54 /* Create node for constraint stack. */
55 Scene *scene_cow = get_cow_datablock(scene_);
56 Object *object_cow = get_cow_datablock(object);
57 add_operation_node(&object->id,
59 pchan->name,
61 [scene_cow, object_cow, pchan_index](::Depsgraph *depsgraph) {
62 BKE_pose_constraints_evaluate(
63 depsgraph, scene_cow, object_cow, pchan_index);
64 });
65}
66
68{
70
71 /* Find the chain's root. */
72 bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
73 if (rootchan == nullptr) {
74 return;
75 }
76
79 {
80 return;
81 }
82
83 int rootchan_index = BLI_findindex(&object->pose->chanbase, rootchan);
84 BLI_assert(rootchan_index != -1);
85
86 /* Operation node for evaluating/running IK Solver. */
87 Scene *scene_cow = get_cow_datablock(scene_);
88 Object *object_cow = get_cow_datablock(object);
89 add_operation_node(&object->id,
91 rootchan->name,
93 [scene_cow, object_cow, rootchan_index](::Depsgraph *depsgraph) {
94 BKE_pose_iktree_evaluate(depsgraph, scene_cow, object_cow, rootchan_index);
95 });
96}
97
99 bPoseChannel *pchan,
100 bConstraint *con)
101{
103
104 /* Find the chain's root. */
106
109 {
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) {
154 BKE_pose_channels_hash_ensure(object->pose);
155 if (object->pose->flag & POSE_CONSTRAINTS_NEED_UPDATE_FLAGS) {
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_update_constraint_flags(bPose *pose) ATTR_NONNULL(1)
void BKE_pose_channels_hash_ensure(bPose *pose) ATTR_NONNULL(1)
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, bool do_id_user)
Definition armature.cc:2767
bPoseChannel * BKE_armature_ik_solver_find_root(bPoseChannel *pchan, bKinematicConstraint *data)
Definition armature.cc:3132
bPoseChannel * BKE_armature_splineik_solver_find_root(bPoseChannel *pchan, bSplineIKConstraint *data)
Definition armature.cc:3153
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, const int flag, void *userdata)
@ IDWALK_NOP
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
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)
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)
T * get_cow_datablock(const T *orig) const
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)
const Depsgraph * depsgraph
@ DEG_ID_LINKED_INDIRECTLY