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 NOT a regression since 2.79, but a regression since 2.79a-rc1.
This commit is contained in:
Sergey Sharybin 2018-02-06 15:36:49 +01:00
parent bac2541ffa
commit e5917d624e
4 changed files with 91 additions and 20 deletions

View File

@ -696,6 +696,19 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
NULL,
DEG_OPCODE_PSYS_EVAL,
psys->name);
/* Visualization of particle system. */
switch (part->ren_as) {
case PART_DRAW_OB:
if (part->dup_ob != NULL) {
build_object(scene, NULL, part->dup_ob);
}
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
build_group(scene, NULL, part->dup_group);
}
break;
}
}
/* pointcache */

View File

@ -419,15 +419,17 @@ void DepsgraphRelationBuilder::build_group(Main *bmain,
{
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);
LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
if (!group_done) {
build_object(bmain, scene, 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;
}
@ -568,7 +570,7 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
/* Particle systems. */
if (ob->particlesystem.first != NULL) {
build_particles(scene, ob);
build_particles(bmain, scene, ob);
}
/* Grease pencil. */
@ -1272,7 +1274,7 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
}
}
void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
void DepsgraphRelationBuilder::build_particles(Main *bmain, Scene *scene, Object *ob)
{
TimeSourceKey time_src_key;
OperationKey obdata_ubereval_key(&ob->id,
@ -1292,10 +1294,6 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
/* this particle system */
OperationKey psys_key(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name);
/* XXX: if particle system is later re-enabled, we must do full rebuild? */
if (!psys_check_enabled(ob, psys, G.is_rendering))
continue;
add_relation(eval_init_key, psys_key, "Init -> PSys");
/* TODO(sergey): Currently particle update is just a placeholder,
@ -1333,16 +1331,27 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
}
}
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(psys_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(bmain, scene, part->dup_ob);
/* Build relation for the particle visualization. */
build_particles_visualization_object(ob,
psys,
part->dup_ob);
}
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
build_group(bmain, scene, NULL, part->dup_group);
LINKLIST_FOREACH (GroupObject *, go, &part->dup_group->gobject) {
build_particles_visualization_object(ob,
psys,
go->ob);
}
}
break;
}
}
@ -1359,6 +1368,28 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
// 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_PSYS_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(Scene * /*scene*/,
Object *object,
ModifierData * /*md*/)

View File

@ -197,7 +197,10 @@ struct DepsgraphRelationBuilder
void build_driver(ID *id, FCurve *fcurve);
void build_world(World *world);
void build_rigidbody(Scene *scene);
void build_particles(Scene *scene, Object *ob);
void build_particles(Main *bmain, Scene *scene, Object *ob);
void build_particles_visualization_object(Object *object,
ParticleSystem *psys,
Object *draw_object);
void build_cloth(Scene *scene, Object *object, ModifierData *md);
void build_ik_pose(Object *ob,
bPoseChannel *pchan,

View File

@ -37,9 +37,11 @@
#include <errno.h>
#include "DNA_anim_types.h"
#include "DNA_group_types.h"
#include "DNA_image_types.h"
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_userdef_types.h"
@ -2059,6 +2061,28 @@ static void tag_dependend_objects_for_render(Scene *scene, int renderlay)
DAG_id_tag_update(&smd->target->id, OB_RECALC_DATA);
}
}
else if (md->type == eModifierType_ParticleSystem) {
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
ParticleSystem *psys = psmd->psys;
ParticleSettings *part = psys->part;
switch (part->ren_as) {
case PART_DRAW_OB:
if (part->dup_ob != NULL) {
DAG_id_tag_update(&part->dup_ob->id, OB_RECALC_DATA);
}
break;
case PART_DRAW_GR:
if (part->dup_group != NULL) {
for (GroupObject *go = part->dup_group->gobject.first;
go != NULL;
go = go->next)
{
DAG_id_tag_update(&go->ob->id, OB_RECALC_DATA);
}
}
break;
}
}
}
}
}