Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/blender/blender_session.cpp
| Show First 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | |||||
| void BlenderSession::free_session() | void BlenderSession::free_session() | ||||
| { | { | ||||
| if (sync) | if (sync) | ||||
| delete sync; | delete sync; | ||||
| delete session; | delete session; | ||||
| } | } | ||||
| static ShaderEvalType get_shader_type(const string &pass_type) | |||||
| { | |||||
| const char *shader_type = pass_type.c_str(); | |||||
| /* data passes */ | |||||
| if (strcmp(shader_type, "NORMAL") == 0) | |||||
| return SHADER_EVAL_NORMAL; | |||||
| else if (strcmp(shader_type, "UV") == 0) | |||||
| return SHADER_EVAL_UV; | |||||
| else if (strcmp(shader_type, "ROUGHNESS") == 0) | |||||
| return SHADER_EVAL_ROUGHNESS; | |||||
| else if (strcmp(shader_type, "DIFFUSE_COLOR") == 0) | |||||
| return SHADER_EVAL_DIFFUSE_COLOR; | |||||
| else if (strcmp(shader_type, "GLOSSY_COLOR") == 0) | |||||
| return SHADER_EVAL_GLOSSY_COLOR; | |||||
| else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0) | |||||
| return SHADER_EVAL_TRANSMISSION_COLOR; | |||||
| else if (strcmp(shader_type, "EMIT") == 0) | |||||
| return SHADER_EVAL_EMISSION; | |||||
| /* light passes */ | |||||
| else if (strcmp(shader_type, "AO") == 0) | |||||
| return SHADER_EVAL_AO; | |||||
| else if (strcmp(shader_type, "COMBINED") == 0) | |||||
| return SHADER_EVAL_COMBINED; | |||||
| else if (strcmp(shader_type, "SHADOW") == 0) | |||||
| return SHADER_EVAL_SHADOW; | |||||
| else if (strcmp(shader_type, "DIFFUSE") == 0) | |||||
| return SHADER_EVAL_DIFFUSE; | |||||
| else if (strcmp(shader_type, "GLOSSY") == 0) | |||||
| return SHADER_EVAL_GLOSSY; | |||||
| else if (strcmp(shader_type, "TRANSMISSION") == 0) | |||||
| return SHADER_EVAL_TRANSMISSION; | |||||
| /* extra */ | |||||
| else if (strcmp(shader_type, "ENVIRONMENT") == 0) | |||||
| return SHADER_EVAL_ENVIRONMENT; | |||||
| else | |||||
| return SHADER_EVAL_BAKE; | |||||
| } | |||||
| static BL::RenderResult begin_render_result(BL::RenderEngine &b_engine, | static BL::RenderResult begin_render_result(BL::RenderEngine &b_engine, | ||||
| int x, | int x, | ||||
| int y, | int y, | ||||
| int w, | int w, | ||||
| int h, | int h, | ||||
| const char *layername, | const char *layername, | ||||
| const char *viewname) | const char *viewname) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 301 Lines • ▼ Show 20 Lines | for (i = 0; i < num_pixels; i++) { | ||||
| } | } | ||||
| else { | else { | ||||
| data->set_null(i); | data->set_null(i); | ||||
| } | } | ||||
| bp = bp.next(); | bp = bp.next(); | ||||
| } | } | ||||
| } | } | ||||
| static int bake_pass_filter_get(const int pass_filter) | static bool shader_is_color(ShaderEvalType type) | ||||
| { | |||||
| switch (type) { | |||||
| case SHADER_EVAL_NORMAL: | |||||
| case SHADER_EVAL_UV: | |||||
| /* TODO: SHADER_EVAL_ROUGHNESS? SHADER_EVAL_SHADOW? */ | |||||
| return false; | |||||
| default: | |||||
| return true; | |||||
| } | |||||
| } | |||||
| static ShaderEvalType get_shader_type(const string &pass_type) | |||||
| { | |||||
| const char *shader_type = pass_type.c_str(); | |||||
| /* data passes */ | |||||
| if (strcmp(shader_type, "NORMAL") == 0) | |||||
| return SHADER_EVAL_NORMAL; | |||||
| else if (strcmp(shader_type, "UV") == 0) | |||||
| return SHADER_EVAL_UV; | |||||
| else if (strcmp(shader_type, "ROUGHNESS") == 0) | |||||
| return SHADER_EVAL_ROUGHNESS; | |||||
| else if (strcmp(shader_type, "DIFFUSE_COLOR") == 0) | |||||
| return SHADER_EVAL_DIFFUSE_COLOR; | |||||
| else if (strcmp(shader_type, "GLOSSY_COLOR") == 0) | |||||
| return SHADER_EVAL_GLOSSY_COLOR; | |||||
| else if (strcmp(shader_type, "TRANSMISSION_COLOR") == 0) | |||||
| return SHADER_EVAL_TRANSMISSION_COLOR; | |||||
| else if (strcmp(shader_type, "EMIT") == 0) | |||||
| return SHADER_EVAL_EMISSION; | |||||
| else if (strcmp(shader_type, "AOV_COLOR") == 0) | |||||
| return SHADER_EVAL_AOV_COLOR; | |||||
| else if (strcmp(shader_type, "AOV_VALUE") == 0) | |||||
| return SHADER_EVAL_AOV_VALUE; | |||||
| /* light passes */ | |||||
| else if (strcmp(shader_type, "AO") == 0) | |||||
| return SHADER_EVAL_AO; | |||||
| else if (strcmp(shader_type, "COMBINED") == 0) | |||||
| return SHADER_EVAL_COMBINED; | |||||
| else if (strcmp(shader_type, "SHADOW") == 0) | |||||
| return SHADER_EVAL_SHADOW; | |||||
| else if (strcmp(shader_type, "DIFFUSE") == 0) | |||||
| return SHADER_EVAL_DIFFUSE; | |||||
| else if (strcmp(shader_type, "GLOSSY") == 0) | |||||
| return SHADER_EVAL_GLOSSY; | |||||
| else if (strcmp(shader_type, "TRANSMISSION") == 0) | |||||
| return SHADER_EVAL_TRANSMISSION; | |||||
| /* extra */ | |||||
| else if (strcmp(shader_type, "ENVIRONMENT") == 0) | |||||
| return SHADER_EVAL_ENVIRONMENT; | |||||
| else | |||||
| return SHADER_EVAL_BAKE; | |||||
| } | |||||
| static int bake_pass_filter_get(PointerRNA cbp) | |||||
| { | { | ||||
| int flag = BAKE_FILTER_NONE; | int flag = BAKE_FILTER_NONE; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_DIRECT) != 0) | if (get_boolean(cbp, "use_pass_direct")) | ||||
| flag |= BAKE_FILTER_DIRECT; | flag |= BAKE_FILTER_DIRECT; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0) | if (get_boolean(cbp, "use_pass_indirect")) | ||||
| flag |= BAKE_FILTER_INDIRECT; | flag |= BAKE_FILTER_INDIRECT; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_COLOR) != 0) | if (get_boolean(cbp, "use_pass_color")) | ||||
| flag |= BAKE_FILTER_COLOR; | flag |= BAKE_FILTER_COLOR; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0) | if (get_boolean(cbp, "use_pass_diffuse")) | ||||
| flag |= BAKE_FILTER_DIFFUSE; | flag |= BAKE_FILTER_DIFFUSE; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0) | if (get_boolean(cbp, "use_pass_glossy")) | ||||
| flag |= BAKE_FILTER_GLOSSY; | flag |= BAKE_FILTER_GLOSSY; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0) | if (get_boolean(cbp, "use_pass_transmission")) | ||||
| flag |= BAKE_FILTER_TRANSMISSION; | flag |= BAKE_FILTER_TRANSMISSION; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_EMIT) != 0) | if (get_boolean(cbp, "use_pass_emit")) | ||||
| flag |= BAKE_FILTER_EMISSION; | flag |= BAKE_FILTER_EMISSION; | ||||
| if ((pass_filter & BL::BakeSettings::pass_filter_AO) != 0) | if (get_boolean(cbp, "use_pass_ambient_occlusion")) | ||||
| flag |= BAKE_FILTER_AO; | flag |= BAKE_FILTER_AO; | ||||
| return flag; | return flag; | ||||
| } | } | ||||
| void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, | void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, | ||||
| BL::BakePass &b_bakepass, | |||||
| BL::Object &b_object, | BL::Object &b_object, | ||||
| const string &pass_type, | |||||
| const int pass_filter, | |||||
| const int object_id, | const int object_id, | ||||
| BL::BakePixel &pixel_array, | BL::BakePixel &pixel_array, | ||||
| const size_t num_pixels, | BL::BakeResult &b_result) | ||||
| const int /*depth*/, | |||||
| float result[]) | |||||
| { | { | ||||
| b_depsgraph = b_depsgraph_; | b_depsgraph = b_depsgraph_; | ||||
| PointerRNA cbp = RNA_pointer_get(&b_bakepass.ptr, "cycles"); | |||||
| string pass_type = get_enum_identifier(cbp, "bake_type"); | |||||
| ShaderEvalType shader_type = get_shader_type(pass_type); | ShaderEvalType shader_type = get_shader_type(pass_type); | ||||
| /* Set baking flag in advance, so kernel loading can check if we need | /* Set baking flag in advance, so kernel loading can check if we need | ||||
| * any baking capabilities. | * any baking capabilities. | ||||
| */ | */ | ||||
| scene->bake_manager->set_baking(true); | scene->bake_manager->set_baking(true); | ||||
| /* ensure kernels are loaded before we do any scene updates */ | /* ensure kernels are loaded before we do any scene updates */ | ||||
| session->load_kernels(); | session->load_kernels(); | ||||
| vector<Pass> passes; | |||||
| Pass::add(PASS_COMBINED, passes); | |||||
| if (shader_type == SHADER_EVAL_UV) { | if (shader_type == SHADER_EVAL_UV) { | ||||
| /* force UV to be available */ | /* force UV to be available */ | ||||
| Pass::add(PASS_UV, scene->film->passes); | Pass::add(PASS_UV, passes); | ||||
| } | } | ||||
| int bake_pass_filter = bake_pass_filter_get(pass_filter); | int bake_pass_filter = bake_pass_filter_get(cbp); | ||||
| bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter); | bake_pass_filter = BakeManager::shader_type_to_pass_filter(shader_type, bake_pass_filter); | ||||
| /* force use_light_pass to be true if we bake more than just colors */ | /* force use_light_pass to be true if we bake more than just colors */ | ||||
| if (bake_pass_filter & ~BAKE_FILTER_COLOR) { | if (bake_pass_filter & ~BAKE_FILTER_COLOR) { | ||||
| Pass::add(PASS_LIGHT, scene->film->passes); | Pass::add(PASS_LIGHT, passes); | ||||
| } | |||||
| /* If we're baking an AOV pass, add it to the film so that the corresponding | |||||
| * nodes get compiled. */ | |||||
| if (shader_type == SHADER_EVAL_AOV_COLOR) { | |||||
| string name = get_string(cbp, "aov_name"); | |||||
| Pass::add(PASS_AOV_COLOR, passes, name.c_str()); | |||||
| } | |||||
| else if (shader_type == SHADER_EVAL_AOV_VALUE) { | |||||
| string name = get_string(cbp, "aov_name"); | |||||
| Pass::add(PASS_AOV_VALUE, passes, name.c_str()); | |||||
| } | } | ||||
| /* create device and update scene */ | /* create device and update scene */ | ||||
| scene->film->tag_passes_update(scene, passes); | |||||
| scene->film->tag_update(scene); | scene->film->tag_update(scene); | ||||
| scene->integrator->tag_update(scene); | scene->integrator->tag_update(scene); | ||||
| if (!session->progress.get_cancel()) { | if (!session->progress.get_cancel()) { | ||||
| /* update scene */ | /* update scene */ | ||||
| BL::Object b_camera_override(b_engine.camera_override()); | BL::Object b_camera_override(b_engine.camera_override()); | ||||
| sync->sync_camera(b_render, b_camera_override, width, height, ""); | sync->sync_camera(b_render, b_camera_override, width, height, ""); | ||||
| sync->sync_data( | sync->sync_data( | ||||
| b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state); | ||||
| builtin_images_load(); | builtin_images_load(); | ||||
| } | } | ||||
| BakeData *bake_data = NULL; | BakeData *bake_data = NULL; | ||||
| if (!session->progress.get_cancel()) { | if (!session->progress.get_cancel()) { | ||||
| /* get buffer parameters */ | /* get buffer parameters */ | ||||
| SessionParams session_params = BlenderSync::get_session_params( | SessionParams session_params = BlenderSync::get_session_params( | ||||
| b_engine, b_userpref, b_scene, background); | b_engine, b_userpref, b_scene, background); | ||||
| BufferParams buffer_params = BlenderSync::get_buffer_params( | BufferParams buffer_params = BlenderSync::get_buffer_params( | ||||
| b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); | b_scene, b_render, b_v3d, b_rv3d, scene->camera, width, height); | ||||
| int samples = get_int(cbp, "samples"); | |||||
| if (samples > 0) { | |||||
| PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); | |||||
| if (get_boolean(cscene, "use_square_samples")) { | |||||
| samples *= samples; | |||||
| } | |||||
| } | |||||
| else { | |||||
| samples = session_params.samples; | |||||
| } | |||||
| scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); | scene->bake_manager->set_shader_limit((size_t)b_engine.tile_x(), (size_t)b_engine.tile_y()); | ||||
| /* set number of samples */ | /* set number of samples */ | ||||
| session->tile_manager.set_samples(session_params.samples); | session->tile_manager.set_samples(samples); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, samples); | ||||
| session->update_scene(); | session->update_scene(); | ||||
| /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ | /* find object index. todo: is arbitrary - copied from mesh_displace.cpp */ | ||||
| size_t object_index = OBJECT_NONE; | size_t object_index = OBJECT_NONE; | ||||
| int tri_offset = 0; | int tri_offset = 0; | ||||
| for (size_t i = 0; i < scene->objects.size(); i++) { | for (size_t i = 0; i < scene->objects.size(); i++) { | ||||
| const Object *object = scene->objects[i]; | const Object *object = scene->objects[i]; | ||||
| const Geometry *geom = object->geometry; | const Geometry *geom = object->geometry; | ||||
| if (object->name == b_object.name() && geom->type == Geometry::MESH) { | if (object->name == b_object.name() && geom->type == Geometry::MESH) { | ||||
| const Mesh *mesh = static_cast<const Mesh *>(geom); | const Mesh *mesh = static_cast<const Mesh *>(geom); | ||||
| object_index = i; | object_index = i; | ||||
| tri_offset = mesh->prim_offset; | tri_offset = mesh->prim_offset; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| size_t num_pixels = b_result.num_pixels(); | |||||
| b_result.depth(4); | |||||
| b_result.is_color(shader_is_color(shader_type)); | |||||
| b_result.is_normal(shader_type == SHADER_EVAL_NORMAL); | |||||
| float fill_other[] = {0.0f, 0.0f, 0.0f, 0.0f}, fill_normal[] = {0.5f, 0.5f, 1.0f, 0.0f}; | |||||
| b_result.fill_color((shader_type == SHADER_EVAL_NORMAL) ? fill_normal : fill_other); | |||||
| b_result.identifier(pass_type); | |||||
| /* Object might have been disabled for rendering or excluded in some | /* Object might have been disabled for rendering or excluded in some | ||||
| * other way, in that case Blender will report a warning afterwards. */ | * other way, in that case Blender will report a warning afterwards. */ | ||||
| if (object_index != OBJECT_NONE) { | if (object_index != OBJECT_NONE) { | ||||
| int object = object_index; | int object = object_index; | ||||
| bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); | bake_data = scene->bake_manager->init(object, tri_offset, num_pixels); | ||||
| populate_bake_data(bake_data, object_id, pixel_array, num_pixels); | populate_bake_data(bake_data, object_id, pixel_array, num_pixels); | ||||
| } | } | ||||
| /* set number of samples */ | /* set number of samples */ | ||||
| session->tile_manager.set_samples(session_params.samples); | session->tile_manager.set_samples(samples); | ||||
| session->reset(buffer_params, session_params.samples); | session->reset(buffer_params, samples); | ||||
| session->update_scene(); | session->update_scene(); | ||||
| session->progress.set_update_callback( | session->progress.set_update_callback( | ||||
| function_bind(&BlenderSession::update_bake_progress, this)); | function_bind(&BlenderSession::update_bake_progress, this)); | ||||
| } | } | ||||
| /* Perform bake. Check cancel to avoid crash with incomplete scene data. */ | /* Perform bake. Check cancel to avoid crash with incomplete scene data. */ | ||||
| if (!session->progress.get_cancel() && bake_data) { | if (!session->progress.get_cancel() && bake_data) { | ||||
| float *pixels = (float *)b_result.allocate().ptr.data; | |||||
| scene->bake_manager->bake(scene->device, | scene->bake_manager->bake(scene->device, | ||||
| &scene->dscene, | &scene->dscene, | ||||
| scene, | scene, | ||||
| session->progress, | session->progress, | ||||
| shader_type, | shader_type, | ||||
| bake_pass_filter, | bake_pass_filter, | ||||
| bake_data, | bake_data, | ||||
| result); | pixels); | ||||
| } | } | ||||
| /* free all memory used (host and device), so we wouldn't leave render | /* free all memory used (host and device), so we wouldn't leave render | ||||
| * engine with extra memory allocated | * engine with extra memory allocated | ||||
| */ | */ | ||||
| session->device_free(); | session->device_free(); | ||||
| ▲ Show 20 Lines • Show All 431 Lines • Show Last 20 Lines | |||||