Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/render/render_preview.cc
| Show All 24 Lines | |||||
| #include "PIL_time.h" | #include "PIL_time.h" | ||||
| #include "BLO_readfile.h" | #include "BLO_readfile.h" | ||||
| #include "DNA_brush_types.h" | #include "DNA_brush_types.h" | ||||
| #include "DNA_camera_types.h" | #include "DNA_camera_types.h" | ||||
| #include "DNA_collection_types.h" | #include "DNA_collection_types.h" | ||||
| #include "DNA_gpencil_types.h" | |||||
| #include "DNA_light_types.h" | #include "DNA_light_types.h" | ||||
| #include "DNA_material_types.h" | #include "DNA_material_types.h" | ||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_node_types.h" | #include "DNA_node_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_space_types.h" | #include "DNA_space_types.h" | ||||
| #include "DNA_world_types.h" | #include "DNA_world_types.h" | ||||
| #include "BKE_animsys.h" | #include "BKE_animsys.h" | ||||
| #include "BKE_appdir.h" | #include "BKE_appdir.h" | ||||
| #include "BKE_armature.h" | #include "BKE_armature.h" | ||||
| #include "BKE_brush.h" | #include "BKE_brush.h" | ||||
| #include "BKE_colortools.h" | #include "BKE_colortools.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_gpencil.h" | |||||
| #include "BKE_icons.h" | #include "BKE_icons.h" | ||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_image.h" | #include "BKE_image.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_light.h" | #include "BKE_light.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_material.h" | #include "BKE_material.h" | ||||
| ▲ Show 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | if (id == nullptr) { | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| switch (GS(id->name)) { | switch (GS(id->name)) { | ||||
| case ID_OB: | case ID_OB: | ||||
| case ID_MA: | case ID_MA: | ||||
| case ID_TE: | case ID_TE: | ||||
| case ID_LA: | case ID_LA: | ||||
| case ID_GD: | |||||
| case ID_WO: { | case ID_WO: { | ||||
| BLI_assert(BKE_previewimg_id_supports_jobs(id)); | BLI_assert(BKE_previewimg_id_supports_jobs(id)); | ||||
| ID *id_copy = BKE_id_copy_ex(nullptr, | ID *id_copy = BKE_id_copy_ex(nullptr, | ||||
| id, | id, | ||||
| nullptr, | nullptr, | ||||
| LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | | LIB_ID_CREATE_LOCAL | LIB_ID_COPY_LOCALIZE | | ||||
| LIB_ID_COPY_NO_ANIMDATA); | LIB_ID_COPY_NO_ANIMDATA); | ||||
| return id_copy; | return id_copy; | ||||
| ▲ Show 20 Lines • Show All 382 Lines • ▼ Show 20 Lines | |||||
| * \{ */ | * \{ */ | ||||
| struct ObjectPreviewData { | struct ObjectPreviewData { | ||||
| /* The main for the preview, not of the current file. */ | /* The main for the preview, not of the current file. */ | ||||
| Main *pr_main; | Main *pr_main; | ||||
| /* Copy of the object to create the preview for. The copy is for thread safety (and to insert | /* Copy of the object to create the preview for. The copy is for thread safety (and to insert | ||||
| * it into its own main). */ | * it into its own main). */ | ||||
| Object *object; | Object *object; | ||||
| /* Datablock copy. Can be nullptr. */ | |||||
| ID *datablock; | |||||
| /* Current frame. */ | /* Current frame. */ | ||||
| int cfra; | int cfra; | ||||
| int sizex; | int sizex; | ||||
| int sizey; | int sizey; | ||||
| }; | }; | ||||
| static bool object_preview_is_type_supported(const Object *ob) | static bool object_preview_is_type_supported(const Object *ob) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | static void object_preview_render(IconPreview *preview, IconPreviewSize *preview_sized) | ||||
| char err_out[256] = "unknown"; | char err_out[256] = "unknown"; | ||||
| BLI_assert(preview->id_copy && (preview->id_copy != preview->id)); | BLI_assert(preview->id_copy && (preview->id_copy != preview->id)); | ||||
| struct ObjectPreviewData preview_data = {}; | struct ObjectPreviewData preview_data = {}; | ||||
| preview_data.pr_main = preview_main; | preview_data.pr_main = preview_main; | ||||
| /* Act on a copy. */ | /* Act on a copy. */ | ||||
| preview_data.object = (Object *)preview->id_copy; | preview_data.object = (Object *)preview->id_copy; | ||||
| preview_data.cfra = preview->scene->r.cfra; | preview_data.datablock = nullptr; | ||||
| preview_data.sizex = preview_sized->sizex; | preview_data.sizex = preview_sized->sizex; | ||||
| preview_data.sizey = preview_sized->sizey; | preview_data.sizey = preview_sized->sizey; | ||||
| Depsgraph *depsgraph; | Depsgraph *depsgraph; | ||||
| Scene *scene = object_preview_scene_create(&preview_data, &depsgraph); | Scene *scene = object_preview_scene_create(&preview_data, &depsgraph); | ||||
| /* Ownership is now ours. */ | /* Ownership is now ours. */ | ||||
| preview->id_copy = nullptr; | preview->id_copy = nullptr; | ||||
| ▲ Show 20 Lines • Show All 163 Lines • ▼ Show 20 Lines | if (ibuf) { | ||||
| icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect); | icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect); | ||||
| IMB_freeImBuf(ibuf); | IMB_freeImBuf(ibuf); | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Grease Pencil Preview | |||||
| * \{ */ | |||||
| static Scene *gpencil_preview_scene_create(const struct ObjectPreviewData *preview_data, | |||||
| Depsgraph **r_depsgraph) | |||||
| { | |||||
| Scene *scene = BKE_scene_add(preview_data->pr_main, "Object preview scene"); | |||||
| /* Grease pencil needs to set the scene to the current frame or the strokes | |||||
| * will not be visible in the preview. */ | |||||
| CFRA = preview_data->cfra; | |||||
| ViewLayer *view_layer = (ViewLayer *)scene->view_layers.first; | |||||
| Depsgraph *depsgraph = DEG_graph_new( | |||||
| preview_data->pr_main, scene, view_layer, DAG_EVAL_VIEWPORT); | |||||
| /* Grease pencil draw engine needs an object to draw the datablock. */ | |||||
| Object *ob_temp = BKE_object_add_for_data(preview_data->pr_main, | |||||
| view_layer, | |||||
| OB_GPENCIL, | |||||
| "preview_object", | |||||
| preview_data->datablock, | |||||
| true); | |||||
| BLI_assert(ob_temp != nullptr); | |||||
| /* Copy the materials to get full color previews. */ | |||||
| const short *materials_len_p = BKE_id_material_len_p(preview_data->datablock); | |||||
| if (materials_len_p && *materials_len_p > 0) { | |||||
| BKE_object_materials_test(preview_data->pr_main, ob_temp, preview_data->datablock); | |||||
| } | |||||
| Object *camera_object = object_preview_camera_create(preview_data->pr_main, view_layer, ob_temp); | |||||
| scene->camera = camera_object; | |||||
| scene->r.xsch = preview_data->sizex; | |||||
| scene->r.ysch = preview_data->sizey; | |||||
| scene->r.size = 100; | |||||
| Base *preview_base = BKE_view_layer_base_find(view_layer, ob_temp); | |||||
| /* For 'view selected' below. */ | |||||
| preview_base->flag |= BASE_SELECTED; | |||||
| DEG_graph_build_from_view_layer(depsgraph); | |||||
| DEG_evaluate_on_refresh(depsgraph); | |||||
| ED_view3d_camera_to_view_selected(preview_data->pr_main, depsgraph, scene, camera_object); | |||||
| BKE_scene_graph_update_tagged(depsgraph, preview_data->pr_main); | |||||
| *r_depsgraph = depsgraph; | |||||
| return scene; | |||||
| } | |||||
| /* Render a grease pencil datablock. As the Draw Engine needs an object, the datablock is assigned | |||||
| * to a temporary object, just for render. */ | |||||
| static void gpencil_preview_render(IconPreview *preview, IconPreviewSize *preview_sized) | |||||
| { | |||||
| Main *preview_main = BKE_main_new(); | |||||
| const float pixelsize_old = U.pixelsize; | |||||
| char err_out[256] = "unknown"; | |||||
| BLI_assert(preview->id_copy && (preview->id_copy != preview->id)); | |||||
| /* Find the frame number to make preview visible. */ | |||||
| int f_min, f_max; | |||||
| bGPdata *gpd = (bGPdata *)preview->id_copy; | |||||
| BKE_gpencil_frame_min_max(gpd, &f_min, &f_max); | |||||
| const int framenum = ((preview->scene->r.cfra < f_min) || (preview->scene->r.cfra > f_max)) ? | |||||
| f_min : | |||||
| preview->scene->r.cfra; | |||||
| struct ObjectPreviewData preview_data = {}; | |||||
| preview_data.pr_main = preview_main; | |||||
| /* Act on a copy. */ | |||||
| preview_data.object = nullptr; | |||||
| preview_data.datablock = (ID *)preview->id_copy; | |||||
| preview_data.cfra = framenum; | |||||
| preview_data.sizex = preview_sized->sizex; | |||||
| preview_data.sizey = preview_sized->sizey; | |||||
| Depsgraph *depsgraph; | |||||
| Scene *scene = gpencil_preview_scene_create(&preview_data, &depsgraph); | |||||
| U.pixelsize = 2.0f; | |||||
| View3DShading shading; | |||||
| BKE_screen_view3d_shading_init(&shading); | |||||
| ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple( | |||||
| depsgraph, | |||||
| DEG_get_evaluated_scene(depsgraph), | |||||
| &shading, | |||||
| OB_TEXTURE, | |||||
| DEG_get_evaluated_object(depsgraph, scene->camera), | |||||
| preview_sized->sizex, | |||||
| preview_sized->sizey, | |||||
| IB_rect, | |||||
| V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS, | |||||
| R_ALPHAPREMUL, | |||||
| nullptr, | |||||
| nullptr, | |||||
| err_out); | |||||
| U.pixelsize = pixelsize_old; | |||||
| if (ibuf) { | |||||
| icon_copy_rect(ibuf, preview_sized->sizex, preview_sized->sizey, preview_sized->rect); | |||||
| IMB_freeImBuf(ibuf); | |||||
| } | |||||
| DEG_graph_free(depsgraph); | |||||
| BKE_main_free(preview_main); | |||||
| } | |||||
| /** \} */ | |||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name New Shader Preview System | /** \name New Shader Preview System | ||||
| * \{ */ | * \{ */ | ||||
| /* inside thread, called by renderer, sets job update value */ | /* inside thread, called by renderer, sets job update value */ | ||||
| static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), struct rcti *UNUSED(rect)) | static void shader_preview_update(void *spv, RenderResult *UNUSED(rr), struct rcti *UNUSED(rect)) | ||||
| { | { | ||||
| ShaderPreview *sp = static_cast<ShaderPreview *>(spv); | ShaderPreview *sp = static_cast<ShaderPreview *>(spv); | ||||
| ▲ Show 20 Lines • Show All 587 Lines • ▼ Show 20 Lines | if (ip->id != nullptr) { | ||||
| BLI_assert(collection_preview_contains_geometry_recursive((Collection *)ip->id)); | BLI_assert(collection_preview_contains_geometry_recursive((Collection *)ip->id)); | ||||
| /* A collection instance empty was created, so this can just reuse the object preview | /* A collection instance empty was created, so this can just reuse the object preview | ||||
| * rendering. */ | * rendering. */ | ||||
| object_preview_render(ip, cur_size); | object_preview_render(ip, cur_size); | ||||
| continue; | continue; | ||||
| case ID_AC: | case ID_AC: | ||||
| action_preview_render(ip, cur_size); | action_preview_render(ip, cur_size); | ||||
| continue; | continue; | ||||
| case ID_GD: | |||||
| gpencil_preview_render(ip, cur_size); | |||||
| continue; | |||||
| default: | default: | ||||
| /* Fall through to the same code as the `ip->id == nullptr` case. */ | /* Fall through to the same code as the `ip->id == nullptr` case. */ | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress); | other_id_types_preview_render(ip, cur_size, pr_method, stop, do_update, progress); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 523 Lines • Show Last 20 Lines | |||||