Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_geometry.cpp
| Context not available. | |||||
| #include "util/util_foreach.h" | #include "util/util_foreach.h" | ||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, | |||||
easythrees: Just created a new version of this function that takes in the sync object. When running the… | |||||
sergeyUnsubmitted Done Inline ActionsAvoid access to b_ob and b_ob_instance here. Pass b_ob.data() instead, and all the rest of Object level properties stored in a some sort of struct which is initialized form single-threaded traversal. sergey: Avoid access to `b_ob` and `b_ob_instance` here. Pass `b_ob.data()` instead, and all the rest… | |||||
easythreesAuthorUnsubmitted Done Inline ActionsSo do you mean pass in b_ob.data() and b_ob_instance.data() instead? easythrees: So do you mean pass in `b_ob.data()` and `b_ob_instance.data()` instead? | |||||
easythreesAuthorUnsubmitted Done Inline ActionsWhat should I do about this line: BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; I can't avoid accessing b_ob_instance here right? Or should I just use b_ob_instance.data()? easythrees: What should I do about this line:
```
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? | |||||
easythreesAuthorUnsubmitted Done Inline ActionsAlso, what should I do about sync_mesh(...), sync_hair(...) and sync_volume(...)? I'm guessing I need to do the same thing? easythrees: Also, what should I do about `sync_mesh(...)`, `sync_hair(...)` and `sync_volume(...)`? I'm… | |||||
| BL::Object &b_ob, | |||||
| BL::Object &b_ob_instance, | |||||
| bool object_updated, | |||||
| bool use_particle_hair, | |||||
| SyncObject &curr_obj) | |||||
| { | |||||
| /* Test if we can instance or if the object is modified. */ | |||||
| BL::ID b_ob_data = b_ob.data(); | |||||
| BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data; | |||||
| GeometryKey key(b_key_id.ptr.data, use_particle_hair); | |||||
| BL::Material material_override = view_layer.material_override; | |||||
| Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume : | |||||
| scene->default_surface; | |||||
| Geometry::Type geom_type = (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) ? | |||||
| Geometry::HAIR : | |||||
| Geometry::MESH; | |||||
| /* Find shader indices. */ | |||||
| vector<Shader *> used_shaders; | |||||
| BL::Object::material_slots_iterator slot; | |||||
| for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { | |||||
easythreesAuthorUnsubmitted Not Done Inline ActionsThis is another gotcha I think. material_slots is defined as COLLECTION_PROPERTY(DefaultCollectionFunctions, MaterialSlot, Object, material_slots, true, true, true) Is there a "proper" way to grab these slots? easythrees: This is another gotcha I think. `material_slots` is defined as
```
COLLECTION_PROPERTY… | |||||
| if (material_override) { | |||||
| find_shader(material_override, used_shaders, default_shader); | |||||
| } | |||||
| else { | |||||
| BL::ID b_material(slot->material()); | |||||
| find_shader(b_material, used_shaders, default_shader); | |||||
| } | |||||
| } | |||||
| if (used_shaders.size() == 0) { | |||||
| if (material_override) | |||||
| find_shader(material_override, used_shaders, default_shader); | |||||
| else | |||||
| used_shaders.push_back(default_shader); | |||||
| } | |||||
| /* Test if we need to sync. */ | |||||
| Geometry *geom = geometry_map.find(key); | |||||
| bool sync = true; | |||||
| if (geom == NULL) { | |||||
| /* Add new geometry if it did not exist yet. */ | |||||
| if (geom_type == Geometry::HAIR) { | |||||
| geom = new Hair(); | |||||
| } | |||||
| else { | |||||
| geom = new Mesh(); | |||||
| } | |||||
| geometry_map.add(key, geom); | |||||
| } | |||||
| else { | |||||
| /* Test if we need to update existing geometry. */ | |||||
| sync = geometry_map.update(geom, b_key_id); | |||||
| } | |||||
| if (!sync) { | |||||
| /* If transform was applied to geometry, need full update. */ | |||||
| if (object_updated && geom->transform_applied) { | |||||
| ; | |||||
| } | |||||
| /* Test if shaders changed, these can be object level so geometry | |||||
| * does not get tagged for recalc. */ | |||||
| else if (geom->used_shaders != used_shaders) { | |||||
| ; | |||||
| } | |||||
| else { | |||||
| /* Even if not tagged for recalc, we may need to sync anyway | |||||
| * because the shader needs different geometry attributes. */ | |||||
| bool attribute_recalc = false; | |||||
| foreach (Shader *shader, geom->used_shaders) { | |||||
| if (shader->need_update_geometry) { | |||||
| attribute_recalc = true; | |||||
| } | |||||
| } | |||||
| if (!attribute_recalc) { | |||||
| return geom; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* Ensure we only sync instanced geometry once. */ | |||||
| if (geometry_synced.find(geom) != geometry_synced.end()) { | |||||
| return geom; | |||||
| } | |||||
| progress.set_sync_status("Synchronizing object", curr_obj.name); | |||||
| geometry_synced.insert(geom); | |||||
| geom->name = ustring(b_ob_data.name().c_str()); | |||||
| if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { | |||||
| Hair *hair = static_cast<Hair *>(geom); | |||||
| sync_hair(b_depsgraph, b_ob, hair, used_shaders); | |||||
| } | |||||
| else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { | |||||
| Mesh *mesh = static_cast<Mesh *>(geom); | |||||
| sync_volume(b_ob, mesh, used_shaders); | |||||
| } | |||||
| else { | |||||
| Mesh *mesh = static_cast<Mesh *>(geom); | |||||
| sync_mesh(b_depsgraph, b_ob, mesh, used_shaders); | |||||
| } | |||||
| return geom; | |||||
| } | |||||
| Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, | Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, | ||||
| BL::Object &b_ob, | BL::Object &b_ob, | ||||
| Context not available. | |||||
Just created a new version of this function that takes in the sync object. When running the multi-threaded version, I saw a lot of crashes accessing data members of BL::Object, so I figured I'd store some info on the sync object.