Merge branch 'master' into blender2.8
This commit is contained in:
@@ -80,6 +80,7 @@ set(SRC
|
||||
intern/builder/deg_builder_nodes.h
|
||||
intern/builder/deg_builder_pchanmap.h
|
||||
intern/builder/deg_builder_relations.h
|
||||
intern/builder/deg_builder_relations_impl.h
|
||||
intern/builder/deg_builder_transitive.h
|
||||
intern/eval/deg_eval.h
|
||||
intern/eval/deg_eval_copy_on_write.h
|
||||
|
||||
@@ -359,6 +359,15 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *object)
|
||||
NULL,
|
||||
DEG_OPCODE_BONE_DONE);
|
||||
op_node->set_as_exit();
|
||||
|
||||
/* Custom properties. */
|
||||
if (pchan->prop != NULL) {
|
||||
add_operation_node(&object->id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
NULL,
|
||||
DEG_OPCODE_PARAMETERS_EVAL,
|
||||
pchan->name);
|
||||
}
|
||||
}
|
||||
op_node = add_operation_node(&object->id,
|
||||
DEG_NODE_TYPE_EVAL_POSE,
|
||||
|
||||
@@ -120,10 +120,10 @@ struct BuilderWalkUserData {
|
||||
DepsgraphRelationBuilder *builder;
|
||||
};
|
||||
|
||||
static void modifier_walk(void *user_data,
|
||||
struct Object * /*object*/,
|
||||
struct Object **obpoin,
|
||||
int /*cb_flag*/)
|
||||
void modifier_walk(void *user_data,
|
||||
struct Object * /*object*/,
|
||||
struct Object **obpoin,
|
||||
int /*cb_flag*/)
|
||||
{
|
||||
BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
|
||||
if (*obpoin) {
|
||||
@@ -275,10 +275,11 @@ bool DepsgraphRelationBuilder::has_node(const OperationKey &key) const
|
||||
|
||||
void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
if (timesrc && node_to) {
|
||||
graph_->add_new_relation(timesrc, node_to, description);
|
||||
graph_->add_new_relation(timesrc, node_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
DEG_DEBUG_PRINTF("add_time_relation(%p = %s, %p = %s, %s) Failed\n",
|
||||
@@ -291,10 +292,11 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
void DepsgraphRelationBuilder::add_operation_relation(
|
||||
OperationDepsNode *node_from,
|
||||
OperationDepsNode *node_to,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
if (node_from && node_to) {
|
||||
graph_->add_new_relation(node_from, node_to, description);
|
||||
graph_->add_new_relation(node_from, node_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
|
||||
@@ -304,13 +306,22 @@ void DepsgraphRelationBuilder::add_operation_relation(
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key, Scene *scene, Object *object, Group *group, bool dupli, const char *name)
|
||||
void DepsgraphRelationBuilder::add_collision_relations(
|
||||
const OperationKey &key,
|
||||
Scene *scene,
|
||||
Object *object,
|
||||
Group *group,
|
||||
bool dupli,
|
||||
const char *name)
|
||||
{
|
||||
unsigned int numcollobj;
|
||||
Object **collobjs = get_collisionobjects_ext(scene, object, group, &numcollobj, eModifierType_Collision, dupli);
|
||||
|
||||
for (unsigned int i = 0; i < numcollobj; i++)
|
||||
{
|
||||
Object **collobjs = get_collisionobjects_ext(scene,
|
||||
object,
|
||||
group,
|
||||
&numcollobj,
|
||||
eModifierType_Collision,
|
||||
dupli);
|
||||
for (unsigned int i = 0; i < numcollobj; i++) {
|
||||
Object *ob1 = collobjs[i];
|
||||
|
||||
ComponentKey trf_key(&ob1->id, DEG_NODE_TYPE_TRANSFORM);
|
||||
@@ -319,47 +330,62 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key,
|
||||
ComponentKey coll_key(&ob1->id, DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(coll_key, key, name);
|
||||
}
|
||||
|
||||
if (collobjs)
|
||||
if (collobjs != NULL) {
|
||||
MEM_freeN(collobjs);
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *object, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
|
||||
void DepsgraphRelationBuilder::add_forcefield_relations(
|
||||
const OperationKey &key,
|
||||
Scene *scene,
|
||||
Object *object,
|
||||
ParticleSystem *psys,
|
||||
EffectorWeights *eff,
|
||||
bool add_absorption,
|
||||
const char *name)
|
||||
{
|
||||
ListBase *effectors = pdInitEffectors(NULL, scene, object, psys, eff, false);
|
||||
|
||||
if (effectors) {
|
||||
for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
|
||||
if (effectors != NULL) {
|
||||
LINKLIST_FOREACH(EffectorCache *, eff, effectors) {
|
||||
if (eff->ob != object) {
|
||||
ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM);
|
||||
add_relation(eff_key, key, name);
|
||||
}
|
||||
|
||||
if (eff->psys) {
|
||||
if (eff->psys != NULL) {
|
||||
if (eff->ob != object) {
|
||||
ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES);
|
||||
add_relation(eff_key, key, name);
|
||||
|
||||
/* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */
|
||||
/* TODO: remove this when/if EVAL_PARTICLES is sufficient
|
||||
* for up to date particles.
|
||||
*/
|
||||
ComponentKey mod_key(&eff->ob->id, DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(mod_key, key, name);
|
||||
}
|
||||
else if (eff->psys != psys) {
|
||||
OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, eff->psys->name);
|
||||
OperationKey eff_key(&eff->ob->id,
|
||||
DEG_NODE_TYPE_EVAL_PARTICLES,
|
||||
DEG_OPCODE_PARTICLE_SYSTEM_EVAL,
|
||||
eff->psys->name);
|
||||
add_relation(eff_key, key, name);
|
||||
}
|
||||
}
|
||||
|
||||
if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
|
||||
ComponentKey trf_key(&eff->pd->f_source->id, DEG_NODE_TYPE_TRANSFORM);
|
||||
ComponentKey trf_key(&eff->pd->f_source->id,
|
||||
DEG_NODE_TYPE_TRANSFORM);
|
||||
add_relation(trf_key, key, "Smoke Force Domain");
|
||||
|
||||
ComponentKey eff_key(&eff->pd->f_source->id, DEG_NODE_TYPE_GEOMETRY);
|
||||
ComponentKey eff_key(&eff->pd->f_source->id,
|
||||
DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(eff_key, key, "Smoke Force Domain");
|
||||
}
|
||||
|
||||
if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
|
||||
add_collision_relations(key, scene, object, NULL, true, "Force Absorption");
|
||||
add_collision_relations(key,
|
||||
scene,
|
||||
object,
|
||||
NULL,
|
||||
true,
|
||||
"Force Absorption");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -496,11 +522,6 @@ void DepsgraphRelationBuilder::build_object(Base *base, Object *object)
|
||||
}
|
||||
/* Animation data */
|
||||
build_animdata(&object->id);
|
||||
// XXX: This should be hooked up by the build_animdata code
|
||||
if (needs_animdata_node(&object->id)) {
|
||||
ComponentKey adt_key(&object->id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(adt_key, local_transform_key, "Object Animation");
|
||||
}
|
||||
/* Object data. */
|
||||
build_object_data(object);
|
||||
/* Particle systems. */
|
||||
@@ -899,26 +920,86 @@ void DepsgraphRelationBuilder::build_constraints(ID *id,
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_animdata(ID *id)
|
||||
{
|
||||
/* Animation curves and NLA. */
|
||||
build_animdata_curves(id);
|
||||
/* Drivers. */
|
||||
build_animdata_drievrs(id);
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_animdata_curves(ID *id)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
|
||||
if (adt == NULL)
|
||||
if (adt == NULL) {
|
||||
return;
|
||||
|
||||
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
|
||||
|
||||
/* animation */
|
||||
if (adt->action || adt->nla_tracks.first) {
|
||||
/* wire up dependency to time source */
|
||||
TimeSourceKey time_src_key;
|
||||
add_relation(time_src_key, adt_key, "TimeSrc -> Animation");
|
||||
|
||||
// XXX: Hook up specific update callbacks for special properties which may need it...
|
||||
|
||||
// XXX: animdata "hierarchy" - top-level overrides need to go after lower-down
|
||||
}
|
||||
if (adt->action == NULL && adt->nla_tracks.first == NULL) {
|
||||
return;
|
||||
}
|
||||
/* Wire up dependency to time source. */
|
||||
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
|
||||
TimeSourceKey time_src_key;
|
||||
add_relation(time_src_key, adt_key, "TimeSrc -> Animation");
|
||||
/* Build relations from animation operation to properties it changes. */
|
||||
build_animdata_curves_targets(id);
|
||||
}
|
||||
|
||||
/* drivers */
|
||||
void DepsgraphRelationBuilder::build_animdata_curves_targets(ID *id)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt == NULL || adt->action == NULL) {
|
||||
return;
|
||||
}
|
||||
/* Get source operation. */
|
||||
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
|
||||
DepsNode *node_from = get_node(adt_key);
|
||||
BLI_assert(node_from != NULL);
|
||||
if (node_from == NULL) {
|
||||
return;
|
||||
}
|
||||
OperationDepsNode *operation_from = node_from->get_exit_operation();
|
||||
BLI_assert(operation_from != NULL);
|
||||
/* Iterate over all curves and build relations. */
|
||||
PointerRNA id_ptr;
|
||||
RNA_id_pointer_create(id, &id_ptr);
|
||||
LINKLIST_FOREACH(FCurve *, fcu, &adt->action->curves) {
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
int index;
|
||||
if (!RNA_path_resolve_full(&id_ptr, fcu->rna_path,
|
||||
&ptr, &prop, &index))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
DepsNode *node_to = graph_->find_node_from_pointer(&ptr, prop);
|
||||
if (node_to == NULL) {
|
||||
continue;
|
||||
}
|
||||
OperationDepsNode *operation_to = node_to->get_entry_operation();
|
||||
/* NOTE: Special case for bones, avoid relation from animation to
|
||||
* each of the bones. Bone evaluation could only start from pose
|
||||
* init anyway.
|
||||
*/
|
||||
if (operation_to->opcode == DEG_OPCODE_BONE_LOCAL) {
|
||||
OperationKey pose_init_key(id,
|
||||
DEG_NODE_TYPE_EVAL_POSE,
|
||||
DEG_OPCODE_POSE_INIT);
|
||||
add_relation(adt_key, pose_init_key, "Animation -> Prop", true);
|
||||
continue;
|
||||
}
|
||||
graph_->add_new_relation(operation_from, operation_to,
|
||||
"Animation -> Prop",
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_animdata_drievrs(ID *id)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt == NULL) {
|
||||
return;
|
||||
}
|
||||
ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
|
||||
LINKLIST_FOREACH (FCurve *, fcu, &adt->drivers) {
|
||||
OperationKey driver_key(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
@@ -990,45 +1071,34 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
DEG_OPCODE_DRIVER,
|
||||
fcu->rna_path ? fcu->rna_path : "",
|
||||
fcu->array_index);
|
||||
bPoseChannel *pchan = NULL;
|
||||
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
|
||||
const ID_Type id_type = GS(id->name);
|
||||
|
||||
/* Create dependency between driver and data affected by it. */
|
||||
/* - direct property relationship... */
|
||||
//RNAPathKey affected_key(id, fcu->rna_path);
|
||||
//add_relation(driver_key, affected_key, "Driver -> Data");
|
||||
|
||||
/* Driver -> data components (for interleaved evaluation
|
||||
* bones/constraints/modifiers).
|
||||
*/
|
||||
// XXX: this probably should probably be moved out into a separate function.
|
||||
if (strstr(rna_path, "pose.bones[") != NULL) {
|
||||
/* interleaved drivers during bone eval */
|
||||
/* TODO: ideally, if this is for a constraint, it goes to said
|
||||
* constraint.
|
||||
*/
|
||||
Object *object = (Object *)id;
|
||||
char *bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones[");
|
||||
pchan = BKE_pose_channel_find_name(object->pose, bone_name);
|
||||
if (bone_name != NULL) {
|
||||
MEM_freeN(bone_name);
|
||||
bone_name = NULL;
|
||||
}
|
||||
if (pchan != NULL) {
|
||||
OperationKey bone_key(id,
|
||||
DEG_NODE_TYPE_BONE,
|
||||
pchan->name,
|
||||
DEG_OPCODE_BONE_LOCAL);
|
||||
add_relation(driver_key, bone_key, "Driver -> Bone");
|
||||
}
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"Couldn't find bone name for driver path - '%s'\n",
|
||||
rna_path);
|
||||
}
|
||||
build_driver_data(id, fcu);
|
||||
/* Loop over variables to get the target relationships. */
|
||||
build_driver_variables(id, fcu);
|
||||
/* It's quite tricky to detect if the driver actually depends on time or
|
||||
* not, so for now we'll be quite conservative here about optimization and
|
||||
* consider all python drivers to be depending on time.
|
||||
*/
|
||||
if ((driver->type == DRIVER_TYPE_PYTHON) &&
|
||||
python_driver_depends_on_time(driver))
|
||||
{
|
||||
TimeSourceKey time_src_key;
|
||||
add_relation(time_src_key, driver_key, "TimeSrc -> Driver");
|
||||
}
|
||||
else if (id_type == ID_AR && strstr(rna_path, "bones[")) {
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu)
|
||||
{
|
||||
OperationKey driver_key(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
DEG_OPCODE_DRIVER,
|
||||
fcu->rna_path ? fcu->rna_path : "",
|
||||
fcu->array_index);
|
||||
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
|
||||
const RNAPathKey self_key(id, rna_path);
|
||||
if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) {
|
||||
/* Drivers on armature-level bone settings (i.e. bbone stuff),
|
||||
* which will affect the evaluation of corresponding pose bones.
|
||||
*/
|
||||
@@ -1067,55 +1137,23 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
rna_path);
|
||||
}
|
||||
}
|
||||
else if (id_type == ID_OB && strstr(rna_path, "modifiers[")) {
|
||||
OperationKey modifier_key(id,
|
||||
DEG_NODE_TYPE_GEOMETRY,
|
||||
DEG_OPCODE_GEOMETRY_UBEREVAL);
|
||||
if (has_node(modifier_key)) {
|
||||
add_relation(driver_key, modifier_key, "Driver -> Modifier");
|
||||
}
|
||||
else {
|
||||
printf("Unexisting driver RNA path: %s\n", rna_path);
|
||||
}
|
||||
}
|
||||
else if (id_type == ID_KE && strstr(rna_path, "key_blocks[")) {
|
||||
/* Shape key driver - hook into the base geometry operation. */
|
||||
// XXX: double check where this points
|
||||
Key *shape_key = (Key *)id;
|
||||
ComponentKey geometry_key(shape_key->from, DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(driver_key, geometry_key, "Driver -> ShapeKey Geom");
|
||||
}
|
||||
else if (strstr(rna_path, "key_blocks[")) {
|
||||
ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(driver_key, geometry_key, "Driver -> ShapeKey Geom");
|
||||
}
|
||||
else {
|
||||
if (GS(id->name) == ID_OB) {
|
||||
/* assume that driver affects a transform... */
|
||||
OperationKey local_transform_key(id,
|
||||
DEG_NODE_TYPE_TRANSFORM,
|
||||
DEG_OPCODE_TRANSFORM_LOCAL);
|
||||
add_relation(driver_key,
|
||||
local_transform_key,
|
||||
"Driver -> Transform");
|
||||
}
|
||||
else if (GS(id->name) == ID_KE) {
|
||||
ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY);
|
||||
add_relation(driver_key,
|
||||
geometry_key,
|
||||
"Driver -> Shapekey Geometry");
|
||||
}
|
||||
RNAPathKey target_key(id, rna_path);
|
||||
add_relation(driver_key, target_key, "Driver -> Target");
|
||||
}
|
||||
/* Ensure that affected prop's update callbacks will be triggered once
|
||||
* done.
|
||||
*/
|
||||
/* TODO: Implement this once the functionality to add these links exists
|
||||
* RNA.
|
||||
*/
|
||||
/* XXX: the data itself could also set this, if it were to be truly
|
||||
* initialised later?
|
||||
*/
|
||||
/* Loop over variables to get the target relationships. */
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_driver_variables(ID *id, FCurve *fcu)
|
||||
{
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
OperationKey driver_key(id,
|
||||
DEG_NODE_TYPE_PARAMETERS,
|
||||
DEG_OPCODE_DRIVER,
|
||||
fcu->rna_path ? fcu->rna_path : "",
|
||||
fcu->array_index);
|
||||
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
|
||||
const RNAPathKey self_key(id, rna_path);
|
||||
|
||||
LINKLIST_FOREACH (DriverVar *, dvar, &driver->variables) {
|
||||
/* Only used targets. */
|
||||
DRIVER_TARGETS_USED_LOOPER(dvar)
|
||||
@@ -1124,31 +1162,25 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
continue;
|
||||
}
|
||||
/* Special handling for directly-named bones. */
|
||||
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) {
|
||||
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) &&
|
||||
(((Object *)dtar->id)->type == OB_ARMATURE) &&
|
||||
(dtar->pchan_name[0]))
|
||||
{
|
||||
Object *object = (Object *)dtar->id;
|
||||
bPoseChannel *target_pchan =
|
||||
BKE_pose_channel_find_name(object->pose, dtar->pchan_name);
|
||||
if (target_pchan != NULL) {
|
||||
/* Get node associated with bone. */
|
||||
// XXX: watch the space!
|
||||
/* Some cases can't use final bone transform, for example:
|
||||
* - Driving the bone with itself (addressed here)
|
||||
* - Relations inside an IK chain (TODO?)
|
||||
*/
|
||||
if (dtar->id == id &&
|
||||
pchan != NULL &&
|
||||
STREQ(pchan->name, target_pchan->name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
OperationKey target_key(dtar->id,
|
||||
DEG_NODE_TYPE_BONE,
|
||||
target_pchan->name,
|
||||
DEG_OPCODE_BONE_DONE);
|
||||
add_relation(target_key,
|
||||
driver_key,
|
||||
"Bone Target -> Driver");
|
||||
BKE_pose_channel_find_name(object->pose,
|
||||
dtar->pchan_name);
|
||||
if (target_pchan == NULL) {
|
||||
continue;
|
||||
}
|
||||
OperationKey variable_key(dtar->id,
|
||||
DEG_NODE_TYPE_BONE,
|
||||
target_pchan->name,
|
||||
DEG_OPCODE_BONE_DONE);
|
||||
if (is_same_bone_dependency(variable_key, self_key)) {
|
||||
continue;
|
||||
}
|
||||
add_relation(variable_key, driver_key, "Bone Target -> Driver");
|
||||
}
|
||||
else if (dtar->flag & DTAR_FLAG_STRUCT_REF) {
|
||||
/* Get node associated with the object's transforms. */
|
||||
@@ -1164,32 +1196,15 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
DEG_OPCODE_TRANSFORM_FINAL);
|
||||
add_relation(target_key, driver_key, "Target -> Driver");
|
||||
}
|
||||
else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) {
|
||||
/* Workaround for ensuring that local bone transforms don't end
|
||||
* up having to wait for pose eval to finish (to prevent cycles).
|
||||
*/
|
||||
Object *object = (Object *)dtar->id;
|
||||
char *bone_name = BLI_str_quoted_substrN(dtar->rna_path,
|
||||
"pose.bones[");
|
||||
bPoseChannel *target_pchan =
|
||||
BKE_pose_channel_find_name(object->pose, bone_name);
|
||||
if (bone_name != NULL) {
|
||||
MEM_freeN(bone_name);
|
||||
bone_name = NULL;
|
||||
else if (dtar->rna_path) {
|
||||
RNAPathKey variable_key(dtar->id, dtar->rna_path);
|
||||
if (RNA_pointer_is_null(&variable_key.ptr)) {
|
||||
continue;
|
||||
}
|
||||
if (target_pchan != NULL) {
|
||||
if (dtar->id == id &&
|
||||
pchan != NULL &&
|
||||
STREQ(pchan->name, target_pchan->name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
OperationKey bone_key(dtar->id,
|
||||
DEG_NODE_TYPE_BONE,
|
||||
target_pchan->name,
|
||||
DEG_OPCODE_BONE_LOCAL);
|
||||
add_relation(bone_key, driver_key, "RNA Bone -> Driver");
|
||||
if (is_same_bone_dependency(variable_key, self_key)) {
|
||||
continue;
|
||||
}
|
||||
add_relation(variable_key, driver_key, "RNA Bone -> Driver");
|
||||
}
|
||||
else {
|
||||
if (dtar->id == id) {
|
||||
@@ -1207,16 +1222,6 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
}
|
||||
DRIVER_TARGETS_LOOPER_END
|
||||
}
|
||||
/* It's quite tricky to detect if the driver actually depends on time or
|
||||
* not, so for now we'll be quite conservative here about optimization and
|
||||
* consider all python drivers to be depending on time.
|
||||
*/
|
||||
if ((driver->type == DRIVER_TYPE_PYTHON) &&
|
||||
python_driver_depends_on_time(driver))
|
||||
{
|
||||
TimeSourceKey time_src_key;
|
||||
add_relation(time_src_key, driver_key, "TimeSrc -> Driver");
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_world(World *world)
|
||||
@@ -1574,7 +1579,6 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
|
||||
if (object->modifiers.first != NULL) {
|
||||
LINKLIST_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
|
||||
|
||||
if (mti->updateDepsgraph) {
|
||||
DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
|
||||
mti->updateDepsgraph(
|
||||
@@ -1584,23 +1588,10 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
|
||||
object,
|
||||
reinterpret_cast< ::DepsNodeHandle* >(&handle));
|
||||
}
|
||||
|
||||
if (BKE_object_modifier_use_time(object, md)) {
|
||||
TimeSourceKey time_src_key;
|
||||
add_relation(time_src_key, obdata_ubereval_key, "Time Source");
|
||||
|
||||
/* Hacky fix for T45633 (Animated modifiers aren't updated)
|
||||
*
|
||||
* This check works because BKE_object_modifier_use_time() tests
|
||||
* for either the modifier needing time, or that it is animated.
|
||||
*/
|
||||
/* XXX: Remove this hack when these links are added as part of build_animdata() instead */
|
||||
if (modifier_dependsOnTime(md) == false && needs_animdata_node(&object->id)) {
|
||||
ComponentKey animation_key(&object->id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(animation_key, obdata_ubereval_key, "Modifier Animation");
|
||||
}
|
||||
}
|
||||
|
||||
if (md->type == eModifierType_Cloth) {
|
||||
build_cloth(object, md);
|
||||
}
|
||||
@@ -1733,16 +1724,6 @@ void DepsgraphRelationBuilder::build_obdata_geom(Object *object)
|
||||
if (key) {
|
||||
build_shapekeys(obdata, key);
|
||||
}
|
||||
|
||||
if (needs_animdata_node(obdata)) {
|
||||
ComponentKey animation_key(obdata, DEG_NODE_TYPE_ANIMATION);
|
||||
ComponentKey parameters_key(obdata, DEG_NODE_TYPE_PARAMETERS);
|
||||
add_relation(animation_key, parameters_key, "Geom Parameters");
|
||||
/* Evaluation usually depends on animation.
|
||||
* TODO(sergey): Need to re-hook it after granular update is implemented..
|
||||
*/
|
||||
add_relation(animation_key, obdata_geom_eval_key, "Animation");
|
||||
}
|
||||
}
|
||||
|
||||
/* Cameras */
|
||||
@@ -1762,11 +1743,6 @@ void DepsgraphRelationBuilder::build_camera(Object *object)
|
||||
add_relation(camera_parameters_key, object_parameters_key,
|
||||
"Camera -> Object");
|
||||
|
||||
if (needs_animdata_node(camera_id)) {
|
||||
ComponentKey animation_key(camera_id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(animation_key, camera_parameters_key, "Camera Parameters");
|
||||
}
|
||||
|
||||
/* DOF */
|
||||
if (cam->dof_ob != NULL) {
|
||||
ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM);
|
||||
@@ -1790,18 +1766,12 @@ void DepsgraphRelationBuilder::build_lamp(Object *object)
|
||||
add_relation(lamp_parameters_key, object_parameters_key,
|
||||
"Lamp -> Object");
|
||||
|
||||
if (needs_animdata_node(lamp_id)) {
|
||||
ComponentKey animation_key(lamp_id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(animation_key, lamp_parameters_key, "Lamp Parameters");
|
||||
}
|
||||
|
||||
/* lamp's nodetree */
|
||||
if (la->nodetree) {
|
||||
if (la->nodetree != NULL) {
|
||||
build_nodetree(la->nodetree);
|
||||
ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_SHADING);
|
||||
add_relation(nodetree_key, lamp_parameters_key, "NTree->Lamp Parameters");
|
||||
}
|
||||
|
||||
/* textures */
|
||||
build_texture_stack(la->mtex);
|
||||
|
||||
@@ -1866,11 +1836,6 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_animdata_node(ntree_id)) {
|
||||
ComponentKey animation_key(ntree_id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(animation_key, shading_key, "NTree Parameters");
|
||||
}
|
||||
|
||||
OperationKey shading_update_key(ntree_id,
|
||||
DEG_NODE_TYPE_SHADING,
|
||||
DEG_OPCODE_MATERIAL_UPDATE);
|
||||
@@ -1951,15 +1916,6 @@ void DepsgraphRelationBuilder::build_gpencil(bGPdata *gpd)
|
||||
// TODO: parent object (when that feature is implemented)
|
||||
}
|
||||
|
||||
bool DepsgraphRelationBuilder::needs_animdata_node(ID *id)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt != NULL) {
|
||||
return (adt->action != NULL) || (adt->nla_tracks.first != NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_cachefile(CacheFile *cache_file) {
|
||||
/* Animation. */
|
||||
build_animdata(&cache_file->id);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "intern/depsgraph_types.h"
|
||||
|
||||
@@ -43,6 +44,7 @@
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "intern/nodes/deg_node.h"
|
||||
#include "intern/nodes/deg_node_component.h"
|
||||
#include "intern/nodes/deg_node_operation.h"
|
||||
|
||||
struct Base;
|
||||
@@ -175,17 +177,20 @@ struct DepsgraphRelationBuilder
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
void add_relation(const KeyFrom& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyTo>
|
||||
void add_relation(const TimeSourceKey& key_from,
|
||||
const KeyTo& key_to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyType>
|
||||
void add_node_handle_relation(const KeyType& key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
void build_view_layer(Scene *scene, ViewLayer *view_layer);
|
||||
void build_group(Object *object, Group *group);
|
||||
@@ -199,7 +204,12 @@ struct DepsgraphRelationBuilder
|
||||
ListBase *constraints,
|
||||
RootPChanMap *root_map);
|
||||
void build_animdata(ID *id);
|
||||
void build_animdata_curves(ID *id);
|
||||
void build_animdata_curves_targets(ID *id);
|
||||
void build_animdata_drievrs(ID *id);
|
||||
void build_driver(ID *id, FCurve *fcurve);
|
||||
void build_driver_data(ID *id, FCurve *fcurve);
|
||||
void build_driver_variables(ID *id, FCurve *fcurve);
|
||||
void build_world(World *world);
|
||||
void build_rigidbody(Scene *scene);
|
||||
void build_particles(Object *object);
|
||||
@@ -276,16 +286,19 @@ protected:
|
||||
|
||||
void add_time_relation(TimeSourceDepsNode *timesrc,
|
||||
DepsNode *node_to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
void add_operation_relation(OperationDepsNode *node_from,
|
||||
OperationDepsNode *node_to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
template <typename KeyType>
|
||||
DepsNodeHandle create_node_handle(const KeyType& key,
|
||||
const char *default_name = "");
|
||||
|
||||
bool needs_animdata_node(ID *id);
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
bool is_same_bone_dependency(const KeyFrom& key_from, const KeyTo& key_to);
|
||||
|
||||
private:
|
||||
/* State which never changes, same for the whole builder time. */
|
||||
@@ -298,10 +311,12 @@ private:
|
||||
|
||||
struct DepsNodeHandle
|
||||
{
|
||||
DepsNodeHandle(DepsgraphRelationBuilder *builder, OperationDepsNode *node, const char *default_name = "") :
|
||||
builder(builder),
|
||||
node(node),
|
||||
default_name(default_name)
|
||||
DepsNodeHandle(DepsgraphRelationBuilder *builder,
|
||||
OperationDepsNode *node,
|
||||
const char *default_name = "")
|
||||
: builder(builder),
|
||||
node(node),
|
||||
default_name(default_name)
|
||||
{
|
||||
BLI_assert(node != NULL);
|
||||
}
|
||||
@@ -311,92 +326,7 @@ struct DepsNodeHandle
|
||||
const char *default_name;
|
||||
};
|
||||
|
||||
/* Utilities for Builders ----------------------------------------------------- */
|
||||
|
||||
template <typename KeyType>
|
||||
OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& key)
|
||||
{
|
||||
DepsNode *node = get_node(key);
|
||||
return node != NULL ? node->get_exit_operation() : NULL;
|
||||
}
|
||||
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description)
|
||||
{
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (op_from && op_to) {
|
||||
add_operation_relation(op_from, op_to, description);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
/* XXX TODO handle as error or report if needed */
|
||||
fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
if (!op_to) {
|
||||
/* XXX TODO handle as error or report if needed */
|
||||
fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n",
|
||||
description, key_to.identifier().c_str());
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n",
|
||||
description, key_to.identifier().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description)
|
||||
{
|
||||
TimeSourceDepsNode *time_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (time_from != NULL && op_to != NULL) {
|
||||
add_time_relation(time_from, op_to, description);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
void DepsgraphRelationBuilder::add_node_handle_relation(
|
||||
const KeyType &key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description)
|
||||
{
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = handle->node->get_entry_operation();
|
||||
if (op_from != NULL && op_to != NULL) {
|
||||
add_operation_relation(op_from, op_to, description);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
if (!op_to) {
|
||||
fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
DepsNodeHandle DepsgraphRelationBuilder::create_node_handle(
|
||||
const KeyType &key,
|
||||
const char *default_name)
|
||||
{
|
||||
return DepsNodeHandle(this, get_node(key), default_name);
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
|
||||
|
||||
#include "intern/builder/deg_builder_relations_impl.h"
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2013 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Original Author: Lukas Toenne
|
||||
* Contributor(s): Sergey SHarybin
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file blender/depsgraph/intern/builder/deg_builder_relations_impl.h
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace DEG {
|
||||
|
||||
template <typename KeyType>
|
||||
OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType& key)
|
||||
{
|
||||
DepsNode *node = get_node(key);
|
||||
return node != NULL ? node->get_exit_operation() : NULL;
|
||||
}
|
||||
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (op_from && op_to) {
|
||||
add_operation_relation(op_from, op_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
/* XXX TODO handle as error or report if needed */
|
||||
fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
if (!op_to) {
|
||||
/* XXX TODO handle as error or report if needed */
|
||||
fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n",
|
||||
description, key_to.identifier().c_str());
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n",
|
||||
description, key_to.identifier().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyTo>
|
||||
void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
|
||||
const KeyTo &key_to,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
TimeSourceDepsNode *time_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
|
||||
if (time_from != NULL && op_to != NULL) {
|
||||
add_time_relation(time_from, op_to, description, check_unique);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
void DepsgraphRelationBuilder::add_node_handle_relation(
|
||||
const KeyType &key_from,
|
||||
const DepsNodeHandle *handle,
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
|
||||
OperationDepsNode *op_to = handle->node->get_entry_operation();
|
||||
if (op_from != NULL && op_to != NULL) {
|
||||
add_operation_relation(op_from, op_to, description, check_unique);
|
||||
}
|
||||
else {
|
||||
if (!op_from) {
|
||||
fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
if (!op_to) {
|
||||
fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n",
|
||||
description, key_from.identifier().c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename KeyType>
|
||||
DepsNodeHandle DepsgraphRelationBuilder::create_node_handle(
|
||||
const KeyType &key,
|
||||
const char *default_name)
|
||||
{
|
||||
return DepsNodeHandle(this, get_node(key), default_name);
|
||||
}
|
||||
|
||||
/* Rig compatibility: we check if bone is using local transform as a variable
|
||||
* for driver on itself and ignore those relations to avoid "false-positive"
|
||||
* dependency cycles.
|
||||
*/
|
||||
template <typename KeyFrom, typename KeyTo>
|
||||
bool DepsgraphRelationBuilder::is_same_bone_dependency(const KeyFrom& key_from,
|
||||
const KeyTo& key_to)
|
||||
{
|
||||
/* Get operations for requested keys. */
|
||||
DepsNode *node_from = get_node(key_from);
|
||||
DepsNode *node_to = get_node(key_to);
|
||||
if (node_from == NULL || node_to == NULL) {
|
||||
return false;
|
||||
}
|
||||
OperationDepsNode *op_from = node_from->get_exit_operation();
|
||||
OperationDepsNode *op_to = node_to->get_entry_operation();
|
||||
if (op_from == NULL || op_to == NULL) {
|
||||
return false;
|
||||
}
|
||||
/* We are only interested in relations like BONE_DONE -> BONE_LOCAL... */
|
||||
if (!(op_from->opcode == DEG_OPCODE_BONE_DONE &&
|
||||
op_to->opcode == DEG_OPCODE_BONE_LOCAL)) {
|
||||
return false;
|
||||
}
|
||||
/* ... BUT, we also need to check if it's same bone. */
|
||||
if (!STREQ(op_from->owner->name, op_to->owner->name)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace DEG
|
||||
@@ -324,11 +324,6 @@ void DepsgraphRelationBuilder::build_rig(Object *object)
|
||||
"Armature Eval");
|
||||
add_relation(armature_key, init_key, "Data dependency");
|
||||
|
||||
if (needs_animdata_node(&object->id)) {
|
||||
ComponentKey animation_key(&object->id, DEG_NODE_TYPE_ANIMATION);
|
||||
add_relation(animation_key, init_key, "Rig Animation");
|
||||
}
|
||||
|
||||
/* IK Solvers...
|
||||
* - These require separate processing steps are pose-level
|
||||
* to be executed between chains of bones (i.e. once the
|
||||
|
||||
@@ -103,41 +103,39 @@ Depsgraph::~Depsgraph()
|
||||
|
||||
/* Query Conditions from RNA ----------------------- */
|
||||
|
||||
static bool pointer_to_id_node_criteria(const PointerRNA *ptr,
|
||||
const PropertyRNA *prop,
|
||||
ID **id)
|
||||
{
|
||||
if (ptr->type == NULL) {
|
||||
return false;
|
||||
}
|
||||
if (prop != NULL) {
|
||||
if (RNA_struct_is_ID(ptr->type)) {
|
||||
*id = (ID *)ptr->data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
|
||||
const PropertyRNA *prop,
|
||||
ID **id,
|
||||
eDepsNode_Type *type,
|
||||
const char **subdata)
|
||||
static bool pointer_to_component_node_criteria(
|
||||
const PointerRNA *ptr,
|
||||
const PropertyRNA *prop,
|
||||
ID **id,
|
||||
eDepsNode_Type *type,
|
||||
const char **subdata,
|
||||
eDepsOperation_Code *operation_code,
|
||||
const char **operation_name,
|
||||
int *operation_name_tag)
|
||||
{
|
||||
if (ptr->type == NULL) {
|
||||
return false;
|
||||
}
|
||||
/* Set default values for returns. */
|
||||
*id = (ID *)ptr->id.data; /* For obvious reasons... */
|
||||
*subdata = ""; /* Default to no subdata (e.g. bone) name
|
||||
* lookup in most cases. */
|
||||
*id = (ID *)ptr->id.data;
|
||||
*subdata = "";
|
||||
*operation_code = DEG_OPCODE_OPERATION;
|
||||
*operation_name = "";
|
||||
*operation_name_tag = -1;
|
||||
/* Handling of commonly known scenarios. */
|
||||
if (ptr->type == &RNA_PoseBone) {
|
||||
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
|
||||
/* Bone - generally, we just want the bone component. */
|
||||
*type = DEG_NODE_TYPE_BONE;
|
||||
*subdata = pchan->name;
|
||||
if (prop != NULL && RNA_property_is_idprop(prop)) {
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*subdata = "";
|
||||
*operation_code = DEG_OPCODE_PARAMETERS_EVAL;
|
||||
*operation_name = pchan->name;;
|
||||
}
|
||||
else {
|
||||
/* Bone - generally, we just want the bone component. */
|
||||
*type = DEG_NODE_TYPE_BONE;
|
||||
*subdata = pchan->name;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else if (ptr->type == &RNA_Bone) {
|
||||
@@ -200,7 +198,12 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
|
||||
* owns it.
|
||||
*/
|
||||
*id = key->from;
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*type = DEG_NODE_TYPE_GEOMETRY;
|
||||
return true;
|
||||
}
|
||||
else if (ptr->type == &RNA_Key) {
|
||||
*id = (ID *)ptr->id.data;
|
||||
*type = DEG_NODE_TYPE_GEOMETRY;
|
||||
return true;
|
||||
}
|
||||
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
|
||||
@@ -213,6 +216,9 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
|
||||
if (prop != NULL) {
|
||||
/* All unknown data effectively falls under "parameter evaluation". */
|
||||
*type = DEG_NODE_TYPE_PARAMETERS;
|
||||
*operation_code = DEG_OPCODE_PARAMETERS_EVAL;
|
||||
*operation_name = "";
|
||||
*operation_name_tag = -1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -223,20 +229,32 @@ DepsNode *Depsgraph::find_node_from_pointer(const PointerRNA *ptr,
|
||||
const PropertyRNA *prop) const
|
||||
{
|
||||
ID *id;
|
||||
eDepsNode_Type type;
|
||||
const char *name;
|
||||
eDepsNode_Type node_type;
|
||||
const char *component_name, *operation_name;
|
||||
eDepsOperation_Code operation_code;
|
||||
int operation_name_tag;
|
||||
|
||||
/* Get querying conditions. */
|
||||
if (pointer_to_id_node_criteria(ptr, prop, &id)) {
|
||||
return find_id_node(id);
|
||||
}
|
||||
else if (pointer_to_component_node_criteria(ptr, prop, &id, &type, &name)) {
|
||||
if (pointer_to_component_node_criteria(
|
||||
ptr, prop,
|
||||
&id, &node_type, &component_name,
|
||||
&operation_code, &operation_name, &operation_name_tag))
|
||||
{
|
||||
IDDepsNode *id_node = find_id_node(id);
|
||||
if (id_node != NULL) {
|
||||
return id_node->find_component(type, name);
|
||||
if (id_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ComponentDepsNode *comp_node =
|
||||
id_node->find_component(node_type, component_name);
|
||||
if (comp_node == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (operation_code == DEG_OPCODE_OPERATION) {
|
||||
return comp_node;
|
||||
}
|
||||
return comp_node->find_operation(operation_code,
|
||||
operation_name,
|
||||
operation_name_tag);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -318,10 +336,18 @@ void Depsgraph::clear_id_nodes()
|
||||
/* Add new relationship between two nodes. */
|
||||
DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
|
||||
OperationDepsNode *to,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
DepsRelation *rel = NULL;
|
||||
if (check_unique) {
|
||||
rel = check_nodes_connected(from, to, description);
|
||||
}
|
||||
if (rel != NULL) {
|
||||
return rel;
|
||||
}
|
||||
/* Create new relation, and add it to the graph. */
|
||||
DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
|
||||
rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
|
||||
/* TODO(sergey): Find a better place for this. */
|
||||
#ifdef WITH_OPENSUBDIV
|
||||
ComponentDepsNode *comp_node = from->owner;
|
||||
@@ -341,13 +367,38 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
|
||||
|
||||
/* Add new relation between two nodes */
|
||||
DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
|
||||
const char *description)
|
||||
const char *description,
|
||||
bool check_unique)
|
||||
{
|
||||
DepsRelation *rel = NULL;
|
||||
if (check_unique) {
|
||||
rel = check_nodes_connected(from, to, description);
|
||||
}
|
||||
if (rel != NULL) {
|
||||
return rel;
|
||||
}
|
||||
/* Create new relation, and add it to the graph. */
|
||||
DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
|
||||
rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
|
||||
return rel;
|
||||
}
|
||||
|
||||
DepsRelation *Depsgraph::check_nodes_connected(const DepsNode *from,
|
||||
const DepsNode *to,
|
||||
const char *description)
|
||||
{
|
||||
foreach (DepsRelation *rel, from->outlinks) {
|
||||
BLI_assert(rel->from == from);
|
||||
if (rel->to != to) {
|
||||
continue;
|
||||
}
|
||||
if (description != NULL && !STREQ(rel->name, description)) {
|
||||
continue;
|
||||
}
|
||||
return rel;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ************************ */
|
||||
/* Relationships Management */
|
||||
|
||||
@@ -359,24 +410,6 @@ DepsRelation::DepsRelation(DepsNode *from,
|
||||
name(description),
|
||||
flag(0)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
for (OperationDepsNode::Relations::const_iterator it = from->outlinks.begin();
|
||||
it != from->outlinks.end();
|
||||
++it)
|
||||
{
|
||||
DepsRelation *rel = *it;
|
||||
if (rel->from == from &&
|
||||
rel->to == to &&
|
||||
rel->type == type &&
|
||||
rel->name == description)
|
||||
{
|
||||
BLI_assert(!"Duplicated relation, should not happen!");
|
||||
}
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* Hook it up to the nodes which use it.
|
||||
*
|
||||
* NOTE: We register relation in the nodes which this link connects to here
|
||||
|
||||
@@ -123,11 +123,21 @@ struct Depsgraph {
|
||||
/* Add new relationship between two nodes. */
|
||||
DepsRelation *add_new_relation(OperationDepsNode *from,
|
||||
OperationDepsNode *to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
DepsRelation *add_new_relation(DepsNode *from,
|
||||
DepsNode *to,
|
||||
const char *description);
|
||||
const char *description,
|
||||
bool check_unique = false);
|
||||
|
||||
/* Check whether two nodes are connected by relation with given
|
||||
* description. Description might be NULL to check ANY relation between
|
||||
* given nodes.
|
||||
*/
|
||||
DepsRelation *check_nodes_connected(const DepsNode *from,
|
||||
const DepsNode *to,
|
||||
const char *description);
|
||||
|
||||
/* Tag a specific node as needing updates. */
|
||||
void add_entry_tag(OperationDepsNode *node);
|
||||
|
||||
@@ -741,6 +741,7 @@ extern StructRNA RNA_XorController;
|
||||
void RNA_main_pointer_create(struct Main *main, PointerRNA *r_ptr);
|
||||
void RNA_id_pointer_create(struct ID *id, PointerRNA *r_ptr);
|
||||
void RNA_pointer_create(struct ID *id, StructRNA *type, void *data, PointerRNA *r_ptr);
|
||||
bool RNA_pointer_is_null(const PointerRNA *ptr);
|
||||
|
||||
bool RNA_path_resolved_create(
|
||||
PointerRNA *ptr, struct PropertyRNA *prop,
|
||||
|
||||
@@ -175,6 +175,11 @@ void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
bool RNA_pointer_is_null(const PointerRNA *ptr)
|
||||
{
|
||||
return !((ptr->data != NULL) && (ptr->id.data != NULL) && (ptr->type != NULL));
|
||||
}
|
||||
|
||||
static void rna_pointer_inherit_id(StructRNA *type, PointerRNA *parent, PointerRNA *ptr)
|
||||
{
|
||||
if (type && type->flag & STRUCT_ID) {
|
||||
|
||||
Reference in New Issue
Block a user