From 37beac8eb823bd81b411426bfc8718639577b179 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 2 Feb 2018 12:00:25 +0100 Subject: Fix missing group duplicated by hair in render Was happening when viewport visibility on the particle system is disabled. This became an issue after c45afcf, but the actual issue goes a bit deeper and the following aspects were involved: - Relations builder for particle system was ignoring particle system if it's visibility is not enabled for viewport. This is something what shouldn't have been done -- depsgraph relations are supposed to be the same no matter if it's viewport or render. - Relation builder was only dealing with duplication set to object, but was ignoring group duplication. This is technically a regression in 2.79a-RC as well, so would need to backport this fix to the branch after extra testing is done here in the studio. --- .../depsgraph/intern/builder/deg_builder_nodes.cc | 26 +++-- .../intern/builder/deg_builder_relations.cc | 128 ++++++++++++++------- .../intern/builder/deg_builder_relations.h | 5 +- 3 files changed, 110 insertions(+), 49 deletions(-) (limited to 'source/blender/depsgraph/intern') diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 8d20a671202..1d18d6def8d 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -661,32 +661,40 @@ void DepsgraphNodeBuilder::build_particles(Object *object) * blackbox evaluation step for one particle system referenced by * the particle systems stack. All dependencies link to this operation. */ - - /* component for all particle systems */ + /* Component for all particle systems. */ ComponentDepsNode *psys_comp = add_component_node(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES); - add_operation_node(psys_comp, function_bind(BKE_particle_system_eval_init, _1, scene_, object), DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); - - /* particle systems */ + /* Build all particle systems. */ BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { ParticleSettings *part = psys->part; - - /* particle settings */ + /* Particle settings. */ // XXX: what if this is used more than once! build_animdata(&part->id); - - /* this particle system */ + /* This particle system evaluation. */ // TODO: for now, this will just be a placeholder "ubereval" node add_operation_node(psys_comp, NULL, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name); + /* Visualization of particle system. */ + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + build_object(NULL, part->dup_ob); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + build_group(NULL, part->dup_group); + } + break; + } } /* pointcache */ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 85ea2c0a8e4..c30d3fecdd5 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -193,6 +193,7 @@ static bool particle_system_depends_on_time(ParticleSystem *psys) static bool object_particles_depends_on_time(Object *object) { + return true; BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { if (particle_system_depends_on_time(psys)) { return true; @@ -426,15 +427,17 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group) { ID *group_id = &group->id; bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0; - OperationKey object_local_transform_key(&object->id, + OperationKey object_local_transform_key(object != NULL ? &object->id : NULL, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL); BLI_LISTBASE_FOREACH (GroupObject *, go, &group->gobject) { if (!group_done) { build_object(go->ob); } - ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); + if (object != NULL) { + ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup"); + } } group_id->tag |= LIB_TAG_DOIT; } @@ -1360,67 +1363,92 @@ void DepsgraphRelationBuilder::build_particles(Object *object) DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL_INIT); - /* particle systems */ + /* Particle systems. */ BLI_LISTBASE_FOREACH (ParticleSystem *, psys, &object->particlesystem) { ParticleSettings *part = psys->part; - - /* particle settings */ + /* Animation of particle settings, */ build_animdata(&part->id); - - /* this particle system */ - OperationKey psys_key(&object->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PARTICLE_SYSTEM_EVAL, psys->name); - - /* XXX: if particle system is later re-enabled, we must do full rebuild? */ - if (!psys_check_enabled(object, psys, G.is_rendering)) - continue; - + /* This particle system. */ + OperationKey psys_key(&object->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + psys->name); add_relation(eval_init_key, psys_key, "Init -> PSys"); - /* TODO(sergey): Currently particle update is just a placeholder, * hook it to the ubereval node so particle system is getting updated * on playback. */ add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval"); - - /* collisions */ + /* Collisions */ if (part->type != PART_HAIR) { - add_collision_relations(psys_key, scene_, object, part->collision_group, object->lay, true, "Particle Collision"); + add_collision_relations(psys_key, + scene_, + object, + part->collision_group, + object->lay, + true, + "Particle Collision"); } - else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) { - add_collision_relations(psys_key, scene_, object, psys->clmd->coll_parms->group, object->lay | scene_->lay, true, "Hair Collision"); + else if ((psys->flag & PSYS_HAIR_DYNAMICS) && + psys->clmd && psys->clmd->coll_parms) + { + add_collision_relations(psys_key, + scene_, + object, + psys->clmd->coll_parms->group, + object->lay | scene_->lay, + true, + "Hair Collision"); } - - /* effectors */ - add_forcefield_relations(psys_key, scene_, object, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field"); - - /* boids */ + /* Effectors. */ + add_forcefield_relations(psys_key, + scene_, + object, + psys, + part->effector_weights, + part->type == PART_HAIR, + "Particle Field"); + /* Boids. */ if (part->boids) { BLI_LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { BLI_LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { Object *ruleob = NULL; - if (rule->type == eBoidRuleType_Avoid) + if (rule->type == eBoidRuleType_Avoid) { ruleob = ((BoidRuleGoalAvoid *)rule)->ob; - else if (rule->type == eBoidRuleType_FollowLeader) + } + else if (rule->type == eBoidRuleType_FollowLeader) { ruleob = ((BoidRuleFollowLeader *)rule)->ob; - + } if (ruleob) { - ComponentKey ruleob_key(&ruleob->id, DEG_NODE_TYPE_TRANSFORM); + ComponentKey ruleob_key(&ruleob->id, + DEG_NODE_TYPE_TRANSFORM); add_relation(ruleob_key, psys_key, "Boid Rule"); } } } } - if (part->ren_as == PART_DRAW_OB && part->dup_ob) { - ComponentKey dup_ob_key(&part->dup_ob->id, DEG_NODE_TYPE_TRANSFORM); - add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); - if (part->dup_ob->type == OB_MBALL) { - ComponentKey dup_geometry_key(&part->dup_ob->id, - DEG_NODE_TYPE_GEOMETRY); - add_relation(obdata_ubereval_key, - dup_geometry_key, - "Particle MBall Visualization"); - } + switch (part->ren_as) { + case PART_DRAW_OB: + if (part->dup_ob != NULL) { + /* Make sure object's relations are all built. */ + build_object(part->dup_ob); + /* Build relation for the particle visualization. */ + build_particles_visualization_object(object, + psys, + part->dup_ob); + } + break; + case PART_DRAW_GR: + if (part->dup_group != NULL) { + build_group(NULL, part->dup_group); + BLI_LISTBASE_FOREACH (GroupObject *, go, &part->dup_group->gobject) { + build_particles_visualization_object(object, + psys, + go->ob); + } + } + break; } } @@ -1437,6 +1465,28 @@ void DepsgraphRelationBuilder::build_particles(Object *object) // TODO... } +void DepsgraphRelationBuilder::build_particles_visualization_object( + Object *object, + ParticleSystem *psys, + Object *draw_object) +{ + OperationKey psys_key(&object->id, + DEG_NODE_TYPE_EVAL_PARTICLES, + DEG_OPCODE_PARTICLE_SYSTEM_EVAL, + psys->name); + OperationKey obdata_ubereval_key(&object->id, + DEG_NODE_TYPE_GEOMETRY, + DEG_OPCODE_GEOMETRY_UBEREVAL); + ComponentKey dup_ob_key(&draw_object->id, DEG_NODE_TYPE_TRANSFORM); + add_relation(dup_ob_key, psys_key, "Particle Object Visualization"); + if (draw_object->type == OB_MBALL) { + ComponentKey dup_geometry_key(&draw_object->id, DEG_NODE_TYPE_GEOMETRY); + add_relation(obdata_ubereval_key, + dup_geometry_key, + "Particle MBall Visualization"); + } +} + void DepsgraphRelationBuilder::build_cloth(Object *object, ModifierData * /*md*/) { diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index aa55b9f66ae..aa8dc2a4982 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -66,11 +66,11 @@ struct bNodeTree; struct Object; struct bPoseChannel; struct bConstraint; +struct ParticleSystem; struct Scene; struct Tex; struct World; struct EffectorWeights; -struct ParticleSystem; struct PropertyRNA; @@ -216,6 +216,9 @@ struct DepsgraphRelationBuilder void build_world(World *world); void build_rigidbody(Scene *scene); void build_particles(Object *object); + void build_particles_visualization_object(Object *object, + ParticleSystem *psys, + Object *draw_object); void build_cloth(Object *object, ModifierData *md); void build_ik_pose(Object *object, bPoseChannel *pchan, -- cgit v1.2.3