Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/render/render_preview.cc')
-rw-r--r--source/blender/editors/render/render_preview.cc123
1 files changed, 122 insertions, 1 deletions
diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc
index addcedc4481..bb067d57649 100644
--- a/source/blender/editors/render/render_preview.cc
+++ b/source/blender/editors/render/render_preview.cc
@@ -30,6 +30,7 @@
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_collection_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_light_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
@@ -47,6 +48,7 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_gpencil.h"
#include "BKE_icons.h"
#include "BKE_idprop.h"
#include "BKE_image.h"
@@ -365,6 +367,7 @@ static ID *duplicate_ids(ID *id, const bool allow_failure)
case ID_MA:
case ID_TE:
case ID_LA:
+ case ID_GD:
case ID_WO: {
BLI_assert(BKE_previewimg_id_supports_jobs(id));
ID *id_copy = BKE_id_copy_ex(nullptr,
@@ -763,6 +766,8 @@ struct ObjectPreviewData {
/* Copy of the object to create the preview for. The copy is for thread safety (and to insert
* it into its own main). */
Object *object;
+ /* Datablock copy. Can be nullptr. */
+ ID *datablock;
/* Current frame. */
int cfra;
int sizex;
@@ -851,7 +856,7 @@ static void object_preview_render(IconPreview *preview, IconPreviewSize *preview
preview_data.pr_main = preview_main;
/* Act on a 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.sizey = preview_sized->sizey;
@@ -1031,6 +1036,119 @@ static void action_preview_render(IconPreview *preview, IconPreviewSize *preview
/** \} */
/* -------------------------------------------------------------------- */
+/** \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
* \{ */
@@ -1634,6 +1752,9 @@ static void icon_preview_startjob_all_sizes(void *customdata,
case ID_AC:
action_preview_render(ip, cur_size);
continue;
+ case ID_GD:
+ gpencil_preview_render(ip, cur_size);
+ continue;
default:
/* Fall through to the same code as the `ip->id == nullptr` case. */
break;