[Bf-blender-cvs] [b8e592bd77d] asset-metadata: Support object preview thumbnails, generated on asset creation
Julian Eisel
noreply at git.blender.org
Sat Jul 4 15:16:42 CEST 2020
Commit: b8e592bd77daf1a142e758e17de626a40605dbc6
Author: Julian Eisel
Date: Sat Jul 4 15:06:58 2020 +0200
Branches: asset-metadata
https://developer.blender.org/rBb8e592bd77daf1a142e758e17de626a40605dbc6
Support object preview thumbnails, generated on asset creation
To generate the preview, a temporary main data-base is created (think of this
as a virtual .blend within the current .blend) with a new scene and the object
to generate the preview for. It's rendered with a camera from the front, using
the "Camera Fit Frame to Selected" logic.
This should be a simple solution requiring no further setup that should work in
most cases. If needed we can have a way to set up the preview differently.
To see it in action:
* In the Outliner context menu for an object run ID Data > Create Asset
* Save the file
* Open a different file (so you can browse into the former)
* Use link/append to navigate into the saved file with the assets. You should
see the preview in thumbnail mode.
===================================================================
M source/blender/editors/include/ED_view3d.h
M source/blender/editors/interface/interface_icons.c
M source/blender/editors/render/render_preview.c
M source/blender/editors/space_view3d/view3d_utils.c
M source/blender/editors/space_view3d/view3d_view.c
===================================================================
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 5e706856738..6a9b34a9b87 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -160,6 +160,11 @@ void ED_view3d_to_object(const struct Depsgraph *depsgraph,
const float quat[4],
const float dist);
+bool ED_view3d_camera_to_view_selected(struct Main *bmain,
+ struct Depsgraph *depsgraph,
+ const struct Scene *scene,
+ struct Object *camera_ob);
+
void ED_view3d_lastview_store(struct RegionView3D *rv3d);
/* Depth buffer */
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 7411639a99f..f984db6dce9 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1988,12 +1988,7 @@ static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs)
}
for (i = 0; i < NUM_ICON_SIZES; i++) {
- /* check if rect needs to be created; changed
- * only set by dynamic icons */
- if (((pi->flag[i] & PRV_CHANGED) || !pi->rect[i])) {
- icon_set_image(C, NULL, id, pi, i, use_jobs);
- pi->flag[i] &= ~PRV_CHANGED;
- }
+ ui_id_preview_image_render_size(C, NULL, id, pi, i, use_jobs);
}
}
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 33d9e599473..3432a1895a0 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -68,6 +68,7 @@
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_node.h"
+#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
#include "BKE_world.h"
@@ -95,12 +96,16 @@
#include "ED_datafiles.h"
#include "ED_render.h"
#include "ED_screen.h"
+#include "ED_view3d.h"
+#include "ED_view3d_offscreen.h"
#ifndef NDEBUG
/* Used for database init assert(). */
# include "BLI_threads.h"
#endif
+void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect);
+
ImBuf *get_brush_icon(Brush *brush)
{
static const int flags = IB_rect | IB_multilayer | IB_metadata;
@@ -705,6 +710,135 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r
}
}
+/* **************************** Object preview ****************** */
+
+struct ObjectPreviewData {
+ /* The main for the preview, not of the current file. */
+ Main *main;
+ /* The original object to create the preview for. */
+ Object *object;
+ int sizex;
+ int sizey;
+};
+
+static Object *object_preview_camera_create(Main *preview_main,
+ Scene *scene,
+ ViewLayer *view_layer,
+ Object *preview_object,
+ int sizex,
+ int sizey)
+{
+ Object *camera = BKE_object_add(preview_main, scene, view_layer, OB_CAMERA, "Preview Camera");
+
+ float rotmat[3][3];
+ float dummyscale[3];
+ mat4_to_loc_rot_size(camera->loc, rotmat, dummyscale, preview_object->obmat);
+
+ /* Camera is Y up, so needs additional 90deg rotation around X to match object's Z up. */
+ float drotmat[3][3];
+ axis_angle_to_mat3_single(drotmat, 'X', M_PI_2);
+ mul_m3_m3_post(rotmat, drotmat);
+
+ camera->rotmode = ROT_MODE_QUAT;
+ mat3_to_quat(camera->quat, rotmat);
+
+ /* shader_preview_render() does this too. */
+ if (sizex > sizey) {
+ ((Camera *)camera->data)->lens *= (float)sizey / (float)sizex;
+ }
+
+ return camera;
+}
+
+static Scene *object_preview_scene_create(const struct ObjectPreviewData *preview_data,
+ Depsgraph **r_depsgraph)
+{
+ Scene *scene = BKE_scene_add(preview_data->main, "Object preview scene");
+ ViewLayer *view_layer = scene->view_layers.first;
+ Depsgraph *depsgraph = DEG_graph_new(preview_data->main, scene, view_layer, DAG_EVAL_VIEWPORT);
+
+ /* FIXME For now just create a copy of the object for the new main, until we have a better way to
+ * obtain the ID in a different Main (i.e. read from asset file). */
+ Object *preview_object_copy;
+ if (!BKE_id_copy(preview_data->main, &preview_data->object->id, (ID **)&preview_object_copy)) {
+ BLI_assert(false);
+ return NULL;
+ }
+
+ BKE_collection_object_add(preview_data->main, scene->master_collection, preview_object_copy);
+
+ Object *camera_object = object_preview_camera_create(preview_data->main,
+ scene,
+ view_layer,
+ preview_object_copy,
+ preview_data->sizex,
+ preview_data->sizey);
+
+ 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, preview_object_copy);
+ /* For 'view selected' below. */
+ preview_base->flag |= BASE_SELECTED;
+
+ DEG_graph_build_from_view_layer(depsgraph, preview_data->main, scene, view_layer);
+ DEG_evaluate_on_refresh(preview_data->main, depsgraph);
+
+ ED_view3d_camera_to_view_selected(preview_data->main, depsgraph, scene, camera_object);
+
+ BKE_scene_graph_update_tagged(depsgraph, preview_data->main);
+
+ *r_depsgraph = depsgraph;
+ return scene;
+}
+
+static void object_preview_render(IconPreview *preview, IconPreviewSize *preview_sized)
+{
+ Main *preview_main = BKE_main_new();
+ const float pixelsize_old = U.pixelsize;
+ char err_out[256] = "unknown";
+
+ struct ObjectPreviewData preview_data = {
+ .main = preview_main,
+ .object = (Object *)preview->id,
+ .sizex = preview_sized->sizex,
+ .sizey = preview_sized->sizey,
+ };
+ Depsgraph *depsgraph;
+ Scene *scene = object_preview_scene_create(&preview_data, &depsgraph);
+
+ U.pixelsize = 2.0f;
+
+ ImBuf *ibuf = ED_view3d_draw_offscreen_imbuf_simple(
+ depsgraph,
+ DEG_get_evaluated_scene(depsgraph),
+ NULL,
+ OB_SOLID,
+ DEG_get_evaluated_object(depsgraph, scene->camera),
+ preview_sized->sizex,
+ preview_sized->sizey,
+ IB_rect,
+ V3D_OFSDRAW_NONE,
+ R_ALPHAPREMUL,
+ NULL,
+ NULL,
+ err_out);
+ /* TODO color-management? */
+
+ 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);
+}
+
/* **************************** new shader preview system ****************** */
/* inside thread, called by renderer, sets job update value */
@@ -1016,7 +1150,7 @@ static void shader_preview_free(void *customdata)
/* ************************* icon preview ********************** */
-static void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
+void icon_copy_rect(ImBuf *ibuf, uint w, uint h, uint *rect)
{
struct ImBuf *ima;
uint *drect, *srect;
@@ -1240,6 +1374,11 @@ static void icon_preview_startjob_all_sizes(void *customdata,
continue;
}
+ if (ELEM(GS(ip->id->name), ID_OB)) {
+ object_preview_render(ip, cur_size);
+ continue;
+ }
+
ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
const bool is_render = !(prv->tag & PRV_TAG_DEFFERED);
diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c
index 15d6a43d105..b3b47cd9e2c 100644
--- a/source/blender/editors/space_view3d/view3d_utils.c
+++ b/source/blender/editors/space_view3d/view3d_utils.c
@@ -1559,6 +1559,41 @@ void ED_view3d_to_object(const Depsgraph *depsgraph,
BKE_object_apply_mat4_ex(ob, mat, ob_eval->parent, ob_eval->parentinv, true);
}
+bool ED_view3d_camera_to_view_selected(struct Main *bmain,
+ Depsgraph *depsgraph,
+ const Scene *scene,
+ Object *camera_ob)
+{
+ Object *camera_ob_eval = DEG_get_evaluated_object(depsgraph, camera_ob);
+ float co[3]; /* the new location to apply */
+ float scale; /* only for ortho cameras */
+
+ if (BKE_camera_view_frame_fit_to_scene(depsgraph, scene, camera_ob_eval, co, &scale)) {
+ ObjectTfmProtectedChannels obtfm;
+ float obmat_new[4][4];
+
+ if ((camera_ob_eval->type == OB_CAMERA) &&
+ (((Camera *)camera_ob_eval->data)->type == CAM_ORTHO)) {
+ ((Camera *)camera_ob->data)->ortho_scale = scale;
+ }
+
+ copy_m4_m4(obmat_new, camera_ob_eval->obmat);
+ copy_v3_v3(obmat_new[3], co);
+
+ /* only touch location */
+ BKE_object_tfm_protected_backup(camera_ob, &obtfm);
+ BKE_object_apply_mat4(camera_ob, obmat_new, true, true);
+ BKE_object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D);
+
+ /* notifiers */
+ DEG_id_tag_update_ex(bmain, &camera_ob->id, ID_RECALC_TRANSFORM);
+
+ return true;
+ }
+
+ return false;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 3fc990160d2..20fb877af5b 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -531,40 +531,18 @@ void VIEW3D_OT_camera_to_view(wmOperatorType *ot)
* meant to take into account vertex/bone selection for eg. */
static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *op)
{
+ Main *bmain = CTX_data_main(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); /* can be NULL */
Object *camera_ob = v3d ? v3d->camera : scen
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list