Fix inconsistent/broken Cycles object visibility for instances.

Object visibility is now handled by the depsgraph iterator, but this API
was incomplete as it made no distinction for visibility of the object itself,
particles and generated instances.

The depsgraph iterator API now includes information about which part of the
object is visible, and this is used by Cycles to replace the old custom logic.
Cycles and EEVEE visibility should now be consistent, which unfortunately does
means some subtle compatibility breakage for both.

Fixes T58956, T58202, T59284.

Differential Revision: https://developer.blender.org/D4109
This commit is contained in:
Brecht Van Lommel 2018-12-18 18:18:00 +01:00
parent adec52a8a8
commit 0edd93effb
Notes: blender-bot 2023-02-14 04:54:16 +01:00
Referenced by issue #59284, Object instancing won't render in Cycles
Referenced by issue #58956, DupliVerts do not render in Cycles
Referenced by issue #58202, Instanced children objects to parents are invisible in Cycles render
19 changed files with 169 additions and 173 deletions

View File

@ -979,7 +979,8 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
BL::Object& b_ob,
BL::Object& b_ob_instance,
bool object_updated,
bool hide_tris)
bool show_self,
bool show_particles)
{
/* test if we can instance or if the object is modified */
BL::ID b_ob_data = b_ob.data();
@ -1086,7 +1087,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
mesh->subdivision_type);
if(b_mesh) {
if(view_layer.use_surfaces && !hide_tris) {
if(view_layer.use_surfaces && show_self) {
if(mesh->subdivision_type != Mesh::SUBDIVISION_NONE)
create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders,
dicing_rate, max_subdivisions);
@ -1096,7 +1097,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph& b_depsgraph,
create_mesh_volume_attributes(scene, b_ob, mesh, b_scene.frame_current());
}
if(view_layer.use_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
if(view_layer.use_hair && show_particles && mesh->subdivision_type == Mesh::SUBDIVISION_NONE)
sync_curves(mesh, b_mesh, b_ob, false);
/* free derived mesh */

View File

@ -295,7 +295,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
BL::ViewLayer& b_view_layer,
BL::DepsgraphObjectInstance& b_instance,
float motion_time,
bool hide_tris,
bool show_self,
bool show_particles,
BlenderObjectCulling& culling,
bool *use_portal)
{
@ -403,7 +404,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
object_updated = true;
/* mesh sync */
object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, hide_tris);
object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, show_self, show_particles);
/* special case not tracked by object update flags */
@ -505,82 +506,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph& b_depsgraph,
return object;
}
static bool object_render_hide_original(BL::Object::type_enum ob_type,
BL::Object::instance_type_enum dupli_type)
{
/* metaball exception, they duplicate self */
if(ob_type == BL::Object::type_META)
return false;
return (dupli_type == BL::Object::instance_type_VERTS ||
dupli_type == BL::Object::instance_type_FACES ||
dupli_type == BL::Object::instance_type_FRAMES);
}
static bool object_render_hide(BL::Object& b_ob,
bool top_level,
bool parent_hide,
bool& hide_triangles,
BL::Depsgraph::mode_enum depsgraph_mode)
{
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
bool hair_present = false;
bool has_particles = false;
bool show_emitter = false;
bool hide_emitter = false;
bool hide_as_dupli_parent = false;
bool hide_as_dupli_child_original = false;
for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
if((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) &&
(b_psys->settings().type()==BL::ParticleSettings::type_HAIR))
hair_present = true;
has_particles = true;
}
/* Both mode_PREVIEW and mode_VIEWPORT are treated the same here.*/
const bool show_instancer = depsgraph_mode == BL::Depsgraph::mode_RENDER
? b_ob.show_instancer_for_render()
: b_ob.show_instancer_for_viewport();
if(has_particles) {
show_emitter = show_instancer;
hide_emitter = !show_emitter;
} else if(b_ob.is_instancer()) {
if(top_level || show_instancer) {
hide_as_dupli_parent = true;
}
}
/* hide original object for duplis */
BL::Object parent = b_ob.parent();
while(parent) {
if(object_render_hide_original(b_ob.type(),
parent.instance_type()))
{
if(parent_hide) {
hide_as_dupli_child_original = true;
break;
}
}
parent = parent.parent();
}
hide_triangles = hide_emitter;
if(show_emitter) {
return false;
}
else if(hair_present) {
return hide_as_dupli_child_original;
}
else {
return (hide_as_dupli_parent || hide_as_dupli_child_original);
}
}
/* Object Loop */
void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
@ -608,7 +533,6 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
bool use_portal = false;
BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval();
BL::Depsgraph::mode_enum depsgraph_mode = b_depsgraph.mode();
BL::Depsgraph::object_instances_iterator b_instance_iter;
for(b_depsgraph.object_instances.begin(b_instance_iter);
@ -624,15 +548,17 @@ void BlenderSync::sync_objects(BL::Depsgraph& b_depsgraph, float motion_time)
culling.init_object(scene, b_ob);
/* test if object needs to be hidden */
bool hide_tris;
const bool show_self = b_instance.show_self();
const bool show_particles = b_instance.show_particles();
if(!object_render_hide(b_ob, true, true, hide_tris, depsgraph_mode)) {
if(show_self || show_particles) {
/* object itself */
sync_object(b_depsgraph,
b_view_layer,
b_instance,
motion_time,
hide_tris,
show_self,
show_particles,
culling,
&use_portal);
}

View File

@ -117,7 +117,8 @@ private:
BL::Object& b_ob,
BL::Object& b_ob_instance,
bool object_updated,
bool hide_tris);
bool show_self,
bool show_particles);
void sync_curves(Mesh *mesh,
BL::Mesh& b_mesh,
BL::Object& b_ob,
@ -127,7 +128,8 @@ private:
BL::ViewLayer& b_view_layer,
BL::DepsgraphObjectInstance& b_instance,
float motion_time,
bool hide_tris,
bool show_self,
bool show_particles,
BlenderObjectCulling& culling,
bool *use_portal);
void sync_light(BL::Object& b_parent,

View File

@ -97,13 +97,14 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
bool BKE_object_data_is_in_editmode(const struct ID *id);
typedef enum eObjectVisibilityCheck {
OB_VISIBILITY_CHECK_FOR_VIEWPORT,
OB_VISIBILITY_CHECK_FOR_RENDER,
OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE,
} eObjectVisibilityCheck;
typedef enum eObjectVisibilityResult {
OB_VISIBLE_SELF = 1,
OB_VISIBLE_PARTICLES = 2,
OB_VISIBLE_INSTANCES = 4,
OB_VISIBLE_ALL = (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES),
} eObjectVisibilityResult;
bool BKE_object_is_visible(const struct Object *ob, const eObjectVisibilityCheck mode);
int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode);
void BKE_object_init(struct Object *ob);
struct Object *BKE_object_add_only_object(

View File

@ -714,33 +714,40 @@ bool BKE_object_is_mode_compat(const struct Object *ob, eObjectMode object_mode)
}
/**
* Return if the object is visible, as evaluated by depsgraph
* Return which parts of the object are visible, as evaluated by depsgraph
*/
bool BKE_object_is_visible(const Object *ob, const eObjectVisibilityCheck mode)
int BKE_object_visibility(const Object *ob, const int dag_eval_mode)
{
if ((ob->base_flag & BASE_VISIBLE) == 0) {
return false;
return 0;
}
if (mode == OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) {
return true;
/* Test which components the object has. */
int visibility = OB_VISIBLE_SELF;
if (ob->particlesystem.first) {
visibility |= OB_VISIBLE_INSTANCES | OB_VISIBLE_PARTICLES;
}
else if (ob->transflag & OB_DUPLI) {
visibility |= OB_VISIBLE_INSTANCES;
}
if (((ob->transflag & OB_DUPLI) == 0) &&
(ob->particlesystem.first == NULL))
{
return true;
/* Optional hiding of self if there are particles or instancers. */
if (visibility & (OB_VISIBLE_PARTICLES | OB_VISIBLE_INSTANCES)) {
switch ((eEvaluationMode)dag_eval_mode) {
case DAG_EVAL_VIEWPORT:
if (!(ob->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT)) {
visibility &= ~OB_VISIBLE_SELF;
}
break;
case DAG_EVAL_RENDER:
if (!(ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER)) {
visibility &= ~OB_VISIBLE_SELF;
}
break;
}
}
switch (mode) {
case OB_VISIBILITY_CHECK_FOR_VIEWPORT:
return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_VIEWPORT) != 0);
case OB_VISIBILITY_CHECK_FOR_RENDER:
return ((ob->duplicator_visibility_flag & OB_DUPLI_FLAG_RENDER) != 0);
default:
BLI_assert(!"Object visible test mode not supported.");
return false;
}
return visibility;
}
bool BKE_object_exists_check(Main *bmain, const Object *obtest)

View File

@ -118,7 +118,7 @@ typedef struct DEGObjectIterData {
struct Scene *scene;
int visibility_check; /* eObjectVisibilityCheck. */
eEvaluationMode eval_mode;
/* **** Iteration over dupli-list. *** */

View File

@ -107,6 +107,26 @@ void verify_id_properties_freed(DEGObjectIterData *data)
temp_dupli_object->id.properties = NULL;
}
static bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
{
/* Automatic hiding if this object is being instanced on verts/faces/frames
* by its parent. Ideally this should not be needed, but due to the wrong
* dependency direction in the data design there is no way to keep the object
* visible otherwise. The better solution eventually would be for objects
* to specify which object they instance, instead of through parenting. */
if (eval_mode == DAG_EVAL_RENDER || dob) {
const int hide_original_types = OB_DUPLIFRAMES | OB_DUPLIVERTS | OB_DUPLIFACES;
if (!dob || !(dob->type & hide_original_types)) {
if (ob->parent && (ob->parent->transflag & hide_original_types)) {
return true;
}
}
}
return false;
}
bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
{
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
@ -116,16 +136,15 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
data->dupli_object_next = data->dupli_object_next->next;
/* Group duplis need to set ob matrices correct, for deform. so no_draw
* is part handled.
*/
if ((obd->transflag & OB_RENDER_DUPLI) == 0 && dob->no_draw) {
if (dob->no_draw) {
continue;
}
if (obd->type == OB_MBALL) {
continue;
}
if (deg_object_hide_original(data->eval_mode, dob->ob, dob)) {
continue;
}
verify_id_properties_freed(data);
@ -142,12 +161,11 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
/* Duplicated elements shouldn't care whether their original collection is visible or not. */
temp_dupli_object->base_flag |= BASE_VISIBLE;
if (BKE_object_is_visible(temp_dupli_object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) {
int ob_visibility = BKE_object_visibility(temp_dupli_object, data->eval_mode);
if (ob_visibility == 0) {
continue;
}
temp_dupli_object->transflag &= ~OB_DUPLI;
copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
iter->current = &data->temp_dupli_object;
BLI_assert(
@ -196,25 +214,29 @@ void deg_iterator_objects_step(BLI_Iterator *iter, DEG::IDDepsNode *id_node)
Object *object = (Object *)id_node->id_cow;
BLI_assert(DEG::deg_validate_copy_on_write_datablock(&object->id));
if ((BKE_object_is_visible(object, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE) == false) &&
((data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) != 0))
{
return;
}
int ob_visibility = OB_VISIBLE_ALL;
if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
ob_visibility = BKE_object_visibility(object, data->eval_mode);
if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
(object->transflag & OB_DUPLI))
{
data->dupli_parent = object;
data->dupli_list = object_duplilist(data->graph, data->scene, object);
data->dupli_object_next = (DupliObject *)data->dupli_list->first;
if (BKE_object_is_visible(object, (eObjectVisibilityCheck)data->visibility_check) == false) {
if (deg_object_hide_original(data->eval_mode, object, NULL)) {
return;
}
}
iter->current = object;
iter->skip = false;
if (ob_visibility & OB_VISIBLE_INSTANCES) {
if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
(object->transflag & OB_DUPLI))
{
data->dupli_parent = object;
data->dupli_list = object_duplilist(data->graph, data->scene, object);
data->dupli_object_next = (DupliObject *)data->dupli_list->first;
}
}
if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
iter->current = object;
iter->skip = false;
}
}
} // namespace
@ -239,10 +261,7 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
data->scene = DEG_get_evaluated_scene(depsgraph);
data->id_node_index = 0;
data->num_id_nodes = num_id_nodes;
eEvaluationMode eval_mode = DEG_get_mode(depsgraph);
data->visibility_check = (eval_mode == DAG_EVAL_RENDER)
? OB_VISIBILITY_CHECK_FOR_RENDER
: OB_VISIBILITY_CHECK_FOR_VIEWPORT;
data->eval_mode = DEG_get_mode(depsgraph);
deg_invalidate_iterator_work_data(data);
DEG::IDDepsNode *id_node = deg_graph->id_nodes[data->id_node_index];

View File

@ -130,15 +130,14 @@ void EEVEE_cache_populate(void *vedata, Object *ob)
EEVEE_ViewLayerData *sldata = EEVEE_view_layer_data_ensure();
const DRWContextState *draw_ctx = DRW_context_state_get();
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
bool cast_shadow = false;
if (ob->base_flag & BASE_VISIBLE) {
if (ob_visibility & OB_VISIBLE_PARTICLES) {
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (DRW_object_is_renderable(ob) &&
DRW_object_is_visible_in_active_context(ob))
{
if (DRW_object_is_renderable(ob) && (ob_visibility & OB_VISIBLE_SELF)) {
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}

View File

@ -411,7 +411,8 @@ static void eevee_lightbake_count_probes(EEVEE_LightBake *lbake)
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
if (!BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_FOR_RENDER)) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
}
@ -1006,7 +1007,8 @@ static void eevee_lightbake_gather_probes(EEVEE_LightBake *lbake)
* This allows a large number of probe to be precomputed (even dupli ones). */
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
if (!BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_FOR_RENDER)) {
const int ob_visibility = BKE_object_visibility(ob, DAG_EVAL_RENDER);
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
continue;
}

View File

@ -34,6 +34,7 @@
#include "DNA_object_types.h"
#include "BKE_camera.h"
#include "BKE_object.h"
#include "BLI_rand.h"
#include "BLI_rect.h"
@ -179,11 +180,12 @@ void EEVEE_render_cache(
RE_engine_update_stats(engine, NULL, info);
}
if (ob->base_flag & BASE_VISIBLE) {
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
if (ob_visibility & OB_VISIBLE_PARTICLES) {
EEVEE_hair_cache_populate(vedata, sldata, ob, &cast_shadow);
}
if (DRW_object_is_visible_in_active_context(ob)) {
if (ob_visibility & OB_VISIBLE_SELF) {
if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
EEVEE_materials_cache_populate(vedata, sldata, ob, &cast_shadow);
}

View File

@ -559,7 +559,7 @@ static void gpencil_add_draw_data(void *vedata, Object *ob)
void GPENCIL_cache_populate(void *vedata, Object *ob)
{
/* object must be visible */
if (!DRW_object_is_visible_in_active_context(ob)) {
if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
return;
}

View File

@ -28,6 +28,7 @@
#include "DRW_render.h"
#include "BKE_camera.h"
#include "BKE_object.h"
#include "DNA_gpencil_types.h"
@ -130,12 +131,10 @@ static void GPENCIL_render_cache(
void *vedata, struct Object *ob,
struct RenderEngine *UNUSED(engine), struct Depsgraph *UNUSED(depsgraph))
{
if ((ob == NULL) || (DRW_object_is_visible_in_active_context(ob) == false)) {
return;
}
if (ob->type == OB_GPENCIL) {
GPENCIL_cache_populate(vedata, ob);
if (ob && ob->type == OB_GPENCIL) {
if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
GPENCIL_cache_populate(vedata, ob);
}
}
}

View File

@ -35,6 +35,7 @@
#include "BKE_node.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_particle.h"
#include "DNA_image_types.h"
@ -808,7 +809,10 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_SOLID)) {
if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
return;
}
if (ob->dt < OB_SOLID) {
return;
}

View File

@ -34,6 +34,7 @@
#include "BKE_node.h"
#include "BKE_particle.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
@ -489,7 +490,10 @@ void workbench_forward_cache_populate(WORKBENCH_Data *vedata, Object *ob)
return; /* Do not draw solid in this case. */
}
if (!DRW_object_is_visible_in_active_context(ob) || (ob->dt < OB_WIRE)) {
if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) {
return;
}
if (ob->dt < OB_WIRE) {
return;
}

View File

@ -511,7 +511,7 @@ DrawData *DRW_drawdata_ensure(
/* Settings */
bool DRW_object_is_renderable(const struct Object *ob);
bool DRW_object_is_visible_in_active_context(const struct Object *ob);
int DRW_object_visibility_in_active_context(const struct Object *ob);
bool DRW_object_is_flat_normal(const struct Object *ob);
bool DRW_object_use_hide_faces(const struct Object *ob);

View File

@ -151,7 +151,7 @@ struct DRWTextStore *DRW_text_cache_ensure(void)
bool DRW_object_is_renderable(const Object *ob)
{
BLI_assert(BKE_object_is_visible(ob, OB_VISIBILITY_CHECK_UNKNOWN_RENDER_MODE));
BLI_assert((ob->base_flag & BASE_VISIBLE) != 0);
if (ob->type == OB_MESH) {
if ((ob == DST.draw_ctx.object_edit) || BKE_object_is_in_editmode(ob)) {
@ -171,12 +171,12 @@ bool DRW_object_is_renderable(const Object *ob)
* Return whether this object is visible depending if
* we are rendering or drawing in the viewport.
*/
bool DRW_object_is_visible_in_active_context(const Object *ob)
int DRW_object_visibility_in_active_context(const Object *ob)
{
const eObjectVisibilityCheck mode = DRW_state_is_scene_render() ?
OB_VISIBILITY_CHECK_FOR_RENDER :
OB_VISIBILITY_CHECK_FOR_VIEWPORT;
return BKE_object_is_visible(ob, mode);
const eEvaluationMode mode = DRW_state_is_scene_render() ?
DAG_EVAL_RENDER :
DAG_EVAL_VIEWPORT;
return BKE_object_visibility(ob, mode);
}
bool DRW_object_is_flat_normal(const Object *ob)
@ -1673,8 +1673,10 @@ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph)
{
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob)
{
if ((ob->type == OB_GPENCIL) && (DRW_object_is_visible_in_active_context(ob))) {
return true;
if (ob->type == OB_GPENCIL) {
if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) {
return true;
}
}
}
DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END

View File

@ -2271,7 +2271,7 @@ static void DRW_shgroup_relationship_lines(
Scene *scene,
Object *ob)
{
if (ob->parent && DRW_object_is_visible_in_active_context(ob->parent)) {
if (ob->parent && (DRW_object_visibility_in_active_context(ob->parent) & OB_VISIBLE_SELF)) {
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->orig);
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
}
@ -2279,11 +2279,11 @@ static void DRW_shgroup_relationship_lines(
if (ob->rigidbody_constraint) {
Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
if (rbc_ob1 && DRW_object_is_visible_in_active_context(rbc_ob1)) {
if (rbc_ob1 && (DRW_object_visibility_in_active_context(rbc_ob1) & OB_VISIBLE_SELF)) {
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob1->obmat[3]);
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
}
if (rbc_ob2 && DRW_object_is_visible_in_active_context(rbc_ob2)) {
if (rbc_ob2 && (DRW_object_visibility_in_active_context(rbc_ob2) & OB_VISIBLE_SELF)) {
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, rbc_ob2->obmat[3]);
DRW_shgroup_call_dynamic_add(sgl->relationship_lines, ob->obmat[3]);
}
@ -2608,13 +2608,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
RegionView3D *rv3d = draw_ctx->rv3d;
ModifierData *md = NULL;
int theme_id = TH_UNDEFINED;
const int ob_visibility = DRW_object_visibility_in_active_context(ob);
/* Handle particles first in case the emitter itself shouldn't be rendered. */
if (ob->type == OB_MESH) {
if (ob_visibility & OB_VISIBLE_PARTICLES) {
OBJECT_cache_populate_particles(ob, psl);
}
if (DRW_object_is_visible_in_active_context(ob) == false) {
if ((ob_visibility & OB_VISIBLE_SELF) == 0) {
return;
}

View File

@ -434,7 +434,7 @@ enum {
OB_DUPLIFACES = 1 << 9,
OB_DUPLIFACES_SCALE = 1 << 10,
OB_DUPLIPARTS = 1 << 11,
OB_RENDER_DUPLI = 1 << 12,
OB_TRANSLFAG_DEPRECATED_2 = 1 << 12,
OB_NO_CONSTRAINTS = 1 << 13, /* runtime constraints disable */
OB_NO_PSYS_UPDATE = 1 << 14, /* hack to work around particle issue */

View File

@ -46,6 +46,7 @@
#include "BLI_math.h"
#include "BKE_anim.h"
#include "BKE_object.h"
#include "DEG_depsgraph_build.h"
#include "DEG_depsgraph_debug.h"
@ -79,6 +80,22 @@ static PointerRNA rna_DepsgraphObjectInstance_instance_object_get(PointerRNA *pt
return rna_pointer_inherit_refine(ptr, &RNA_Object, instance_object);
}
static bool rna_DepsgraphObjectInstance_show_self_get(PointerRNA *ptr)
{
BLI_Iterator *iterator = ptr->data;
DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
return (ob_visibility & OB_VISIBLE_SELF) != 0;
}
static bool rna_DepsgraphObjectInstance_show_particles_get(PointerRNA *ptr)
{
BLI_Iterator *iterator = ptr->data;
DEGObjectIterData *deg_iter = (DEGObjectIterData *)iterator->data;
int ob_visibility = BKE_object_visibility(iterator->current, deg_iter->eval_mode);
return (ob_visibility & OB_VISIBLE_PARTICLES) != 0;
}
static PointerRNA rna_DepsgraphObjectInstance_parent_get(PointerRNA *ptr)
{
BLI_Iterator *iterator = ptr->data;
@ -444,9 +461,19 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_object_get", NULL, NULL, NULL);
prop = RNA_def_property(srna, "show_self", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Show Self", "The object geometry itself should be visible in the render");
RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_self_get", NULL);
prop = RNA_def_property(srna, "show_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Show Particles", "Particles part of the object should be visible in the render");
RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_show_particles_get", NULL);
prop = RNA_def_property(srna, "is_instance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Is Instance", "Denotes whether the object is coming from dupli-list");
RNA_def_property_ui_text(prop, "Is Instance", "Denotes if the object is generated by another object");
RNA_def_property_boolean_funcs(prop, "rna_DepsgraphObjectInstance_is_instance_get", NULL);
prop = RNA_def_property(srna, "instance_object", PROP_POINTER, PROP_NONE);
@ -457,7 +484,7 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_ui_text(prop, "Parent", "Evaluated parent object of the duplication list");
RNA_def_property_ui_text(prop, "Parent", "If the object is an instance, the parent object that generated it");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_pointer_funcs(prop, "rna_DepsgraphObjectInstance_parent_get", NULL, NULL, NULL);
@ -476,7 +503,7 @@ static void rna_def_depsgraph_instance(BlenderRNA *brna)
prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this instance, typically for randomized shading");
RNA_def_property_int_funcs(prop, "rna_DepsgraphObjectInstance_random_id_get", NULL, NULL);
prop = RNA_def_property(srna, "matrix_world", PROP_FLOAT, PROP_MATRIX);