Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated) { /* test if we can instance or if the object is modified */ BL::ID b_ob_data = b_ob.data(); BL::ID key = (object_is_modified(b_ob))? b_ob: b_ob_data; /* find shader indices */ vector<uint> used_shaders; BL::Object::material_slots_iterator slot; for(b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { BL::Material material_override = render_layers.front().material_override; if(material_override) find_shader(material_override, used_shaders, scene->default_surface); else find_shader(slot->material(), used_shaders, scene->default_surface); } if(used_shaders.size() == 0) used_shaders.push_back(scene->default_surface); /* test if we need to sync */ Mesh *mesh; if(!mesh_map.sync(&mesh, key)) { /* if transform was applied to mesh, need full update */ if(object_updated && mesh->transform_applied); /* test if shaders changed, these can be object level so mesh does not get tagged for recalc */ else if(mesh->used_shaders != used_shaders); else { /* even if not tagged for recalc, we may need to sync anyway * because the shader needs different mesh attributes */ bool attribute_recalc = false; foreach(uint shader, mesh->used_shaders) if(scene->shaders[shader]->need_update_attributes) attribute_recalc = true; if(!attribute_recalc) return mesh; } } /* ensure we only sync instanced meshes once */ if(mesh_synced.find(mesh) != mesh_synced.end()) return mesh; mesh_synced.insert(mesh); /* create derived mesh */ BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview); PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles"); vector<Mesh::Triangle> oldtriangle = mesh->triangles; mesh->clear(); mesh->used_shaders = used_shaders; mesh->name = ustring(b_ob_data.name().c_str()); if(b_mesh) { if(cmesh.data && experimental && RNA_boolean_get(&cmesh, "use_subdivision")) create_subd_mesh(mesh, b_mesh, &cmesh, used_shaders); else create_mesh(scene, mesh, b_mesh, used_shaders); /* free derived mesh */ object_remove_mesh(b_data, b_mesh); } /* displacement method */ if(cmesh.data) { int method = RNA_enum_get(&cmesh, "displacement_method"); if(method == 0 || !experimental) mesh->displacement_method = Mesh::DISPLACE_BUMP; else if(method == 1) mesh->displacement_method = Mesh::DISPLACE_TRUE; else mesh->displacement_method = Mesh::DISPLACE_BOTH; } /* tag update */ bool rebuild = false; if(oldtriangle.size() != mesh->triangles.size()) rebuild = true; else if(oldtriangle.size()) { if(memcmp(&oldtriangle[0], &mesh->triangles[0], sizeof(Mesh::Triangle)*oldtriangle.size()) != 0) rebuild = true; } mesh->tag_update(scene, rebuild); return mesh; }
int rna_Object_is_modified(Object *ob, Scene *scene, int settings) { return object_is_modified(scene, ob) & settings; }