Cleanup: export particle hair as a separate Cycles object
This commit is contained in:
parent
ad489b7164
commit
7b66f73558
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
if (show_in_viewport && (show_self || show_particles)) {
|
||||
/* object itself */
|
||||
/* Object itself. */
|
||||
if (b_instance.show_self()) {
|
||||
sync_object(b_depsgraph,
|
||||
b_view_layer,
|
||||
b_instance,
|
||||
motion_time,
|
||||
show_self,
|
||||
show_particles,
|
||||
false,
|
||||
show_lights,
|
||||
culling,
|
||||
&use_portal);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
true,
|
||||
show_lights,
|
||||
culling,
|
||||
&use_portal);
|
||||
|
|
|
@ -108,10 +108,12 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||
}
|
||||
|
||||
if (dicing_prop_changed) {
|
||||
for (const pair<void *, Mesh *> &iter : mesh_map.key_to_scene_data()) {
|
||||
for (const pair<MeshKey, Mesh *> &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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<void *, Shader> shader_map;
|
||||
id_map<ObjectKey, Object> object_map;
|
||||
id_map<void *, Mesh> mesh_map;
|
||||
id_map<MeshKey, Mesh> mesh_map;
|
||||
id_map<ObjectKey, Light> light_map;
|
||||
id_map<ParticleSystemKey, ParticleSystem> particle_system_map;
|
||||
set<Mesh *> mesh_synced;
|
||||
|
|
|
@ -625,6 +625,11 @@ template<typename K, typename T> 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<typename K, typename T> 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)
|
||||
return memcmp(id, k.id, sizeof(id)) < 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue