From 7b66f73558d1e4dda308366bc8ad2b5dfa8009d3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 2 Feb 2020 13:09:18 +0100 Subject: Cleanup: export particle hair as a separate Cycles object --- intern/cycles/blender/blender_curves.cpp | 24 ++++++++++++++- intern/cycles/blender/blender_mesh.cpp | 20 +++++++------ intern/cycles/blender/blender_object.cpp | 42 ++++++++++++++++---------- intern/cycles/blender/blender_sync.cpp | 6 ++-- intern/cycles/blender/blender_sync.h | 11 ++++--- intern/cycles/blender/blender_util.h | 51 ++++++++++++++++++++++++++++---- 6 files changed, 114 insertions(+), 40 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 78db1d5c832..755214f422c 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -964,7 +964,29 @@ void BlenderSync::sync_curve_settings() curve_system_manager->tag_update(scene); } -void BlenderSync::sync_curves( +bool BlenderSync::object_has_particle_hair(BL::Object b_ob) +{ + /* Test if the object has a particle modifier with hair. */ + BL::Object::modifiers_iterator b_mod; + for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) { + if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && + (preview ? b_mod->show_viewport() : b_mod->show_render())) { + BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr); + BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr); + BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr); + + if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && + (b_part.type() == BL::ParticleSettings::type_HAIR)) { + return true; + } + } + } + + return false; +} + +/* Old particle hair. */ +void BlenderSync::sync_particle_hair( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step) { if (!motion) { diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index b18f9a37948..d3dac3c6151 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -967,12 +967,12 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool show_self, - bool show_particles) + bool use_particle_hair) { /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); - BL::ID key = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; + BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; + MeshKey key(b_key_id.ptr.data, use_particle_hair); BL::Material material_override = view_layer.material_override; /* find shader indices */ @@ -1006,7 +1006,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, } Mesh *mesh; - if (!mesh_map.sync(&mesh, key)) { + if (!mesh_map.sync(&mesh, b_key_id, key)) { /* if transform was applied to mesh, need full update */ if (object_updated && mesh->transform_applied) ; @@ -1078,7 +1078,7 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, if (b_mesh) { /* Sync mesh itself. */ - if (view_layer.use_surfaces && show_self) { + if (view_layer.use_surfaces && !use_particle_hair) { if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) create_subd_mesh(scene, mesh, b_ob, b_mesh, used_shaders, dicing_rate, max_subdivisions); else @@ -1088,9 +1088,9 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, } /* Sync hair curves. */ - if (view_layer.use_hair && show_particles && + if (view_layer.use_hair && use_particle_hair && mesh->subdivision_type == Mesh::SUBDIVISION_NONE) { - sync_curves(mesh, b_mesh, b_ob, false); + sync_particle_hair(mesh, b_mesh, b_ob, false); } free_object_to_mesh(b_data, b_ob, b_mesh); @@ -1099,7 +1099,9 @@ Mesh *BlenderSync::sync_mesh(BL::Depsgraph &b_depsgraph, mesh->geometry_flags = requested_geometry_flags; /* mesh fluid motion mantaflow */ - sync_mesh_fluid_motion(b_ob, scene, mesh); + if (!use_particle_hair) { + sync_mesh_fluid_motion(b_ob, scene, mesh); + } /* tag update */ bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) || @@ -1258,7 +1260,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph &b_depsgraph, /* hair motion */ if (numkeys) - sync_curves(mesh, b_mesh, b_ob, true, motion_step); + sync_particle_hair(mesh, b_mesh, b_ob, true, motion_step); /* free derived mesh */ free_object_to_mesh(b_data, b_ob, b_mesh); diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 6981412bb88..c397a95fa71 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -115,7 +115,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, { /* test if we need to sync */ Light *light; - ObjectKey key(b_parent, persistent_id, b_ob_instance); + ObjectKey key(b_parent, persistent_id, b_ob_instance, false); BL::Light b_light(b_ob.data()); /* Update if either object or light data changed. */ @@ -254,7 +254,7 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) if (sample_as_light || use_portal) { /* test if we need to sync */ Light *light; - ObjectKey key(b_world, 0, b_world); + ObjectKey key(b_world, 0, b_world, false); if (light_map.sync(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { @@ -295,8 +295,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, BL::ViewLayer &b_view_layer, BL::DepsgraphObjectInstance &b_instance, float motion_time, - bool show_self, - bool show_particles, + bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, bool *use_portal) @@ -378,7 +377,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, } /* key to lookup object */ - ObjectKey key(b_parent, persistent_id, b_ob_instance); + ObjectKey key(b_parent, persistent_id, b_ob_instance, use_particle_hair); Object *object; /* motion vector case */ @@ -407,8 +406,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, show_self, show_particles); + object->mesh = sync_mesh(b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); /* special case not tracked by object update flags */ @@ -552,22 +550,34 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, BL::DepsgraphObjectInstance b_instance = *b_instance_iter; BL::Object b_ob = b_instance.object(); - /* load per-object culling data */ + /* Viewport visibility. */ + const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d); + if (show_in_viewport == false) { + continue; + } + + /* Load per-object culling data. */ culling.init_object(scene, b_ob); - /* test if object needs to be hidden */ - const bool show_self = b_instance.show_self(); - const bool show_particles = b_instance.show_particles(); - const bool show_in_viewport = !b_v3d || b_ob.visible_in_viewport_get(b_v3d); + /* Object itself. */ + if (b_instance.show_self()) { + sync_object(b_depsgraph, + b_view_layer, + b_instance, + motion_time, + false, + show_lights, + culling, + &use_portal); + } - if (show_in_viewport && (show_self || show_particles)) { - /* object itself */ + /* Particle hair as separate object. */ + if (b_instance.show_particles() && object_has_particle_hair(b_ob)) { sync_object(b_depsgraph, b_view_layer, b_instance, motion_time, - show_self, - show_particles, + true, show_lights, culling, &use_portal); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 20dbe23cdb7..bb8a132ebb7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -108,10 +108,12 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d } if (dicing_prop_changed) { - for (const pair &iter : mesh_map.key_to_scene_data()) { + for (const pair &iter : mesh_map.key_to_scene_data()) { Mesh *mesh = iter.second; if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { - mesh_map.set_recalc(iter.first); + PointerRNA id_ptr; + RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); + mesh_map.set_recalc(BL::ID(id_ptr)); } } } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index a80f484fb92..07dccdc5a73 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -127,16 +127,15 @@ class BlenderSync { BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool show_self, - bool show_particles); - void sync_curves( + bool use_particle_hair); + bool object_has_particle_hair(BL::Object b_ob); + void sync_particle_hair( Mesh *mesh, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); Object *sync_object(BL::Depsgraph &b_depsgraph, BL::ViewLayer &b_view_layer, BL::DepsgraphObjectInstance &b_instance, float motion_time, - bool show_self, - bool show_particles, + bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, bool *use_portal); @@ -179,7 +178,7 @@ class BlenderSync { id_map shader_map; id_map object_map; - id_map mesh_map; + id_map mesh_map; id_map light_map; id_map particle_system_map; set mesh_synced; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index bea30a20b8c..6d6dd75db6b 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -625,6 +625,11 @@ template class id_map { return sync(r_data, id, id, id.ptr.owner_id); } + bool sync(T **r_data, const BL::ID &id, const K &key) + { + return sync(r_data, id, id, key); + } + bool sync(T **r_data, const BL::ID &id, const BL::ID &parent, const K &key) { T *data = find(key); @@ -639,8 +644,9 @@ template class id_map { } else { recalc = (b_recalc.find(id.ptr.data) != b_recalc.end()); - if (parent.ptr.data) + if (parent.ptr.data && parent.ptr.data != id.ptr.data) { recalc = recalc || (b_recalc.find(parent.ptr.data) != b_recalc.end()); + } } used(data); @@ -725,9 +731,10 @@ struct ObjectKey { void *parent; int id[OBJECT_PERSISTENT_ID_SIZE]; void *ob; + bool use_particle_hair; - ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_) - : parent(parent_), ob(ob_) + ObjectKey(void *parent_, int id_[OBJECT_PERSISTENT_ID_SIZE], void *ob_, bool use_particle_hair_) + : parent(parent_), ob(ob_), use_particle_hair(use_particle_hair_) { if (id_) memcpy(id, id_, sizeof(id)); @@ -741,10 +748,42 @@ struct ObjectKey { return true; } else if (ob == k.ob) { - if (parent < k.parent) + if (parent < k.parent) { + return true; + } + else if (parent == k.parent) { + if (use_particle_hair < k.use_particle_hair) { + return true; + } + else if (use_particle_hair == k.use_particle_hair) { + return memcmp(id, k.id, sizeof(id)) < 0; + } + } + } + + return false; + } +}; + +/* Mesh Key */ + +struct MeshKey { + void *id; + bool use_particle_hair; + + MeshKey(void *id, bool use_particle_hair) : id(id), use_particle_hair(use_particle_hair) + { + } + + bool operator<(const MeshKey &k) const + { + if (id < k.id) { + return true; + } + else if (id == k.id) { + if (use_particle_hair < k.use_particle_hair) { return true; - else if (parent == k.parent) - return memcmp(id, k.id, sizeof(id)) < 0; + } } return false; -- cgit v1.2.3