[Bf-blender-cvs] [78008642ae0] asset-browser-snap-dragging: Show a bounding box for object assets while dragging

Julian Eisel noreply at git.blender.org
Fri Apr 30 02:30:14 CEST 2021


Commit: 78008642ae010c64da4cb6b64911b44488823c3e
Author: Julian Eisel
Date:   Fri Apr 30 02:02:45 2021 +0200
Branches: asset-browser-snap-dragging
https://developer.blender.org/rB78008642ae010c64da4cb6b64911b44488823c3e

Show a bounding box for object assets while dragging

Note: Object assets have to be saved with this commit or later for the bounding
box to appear.

Basic idea is:
* Store the bounding box (and related info) in the asset metadata.
* The bounding box has to be updated and written to custom properties of the
  asset metadata.
* There's a new `AssetTypeInfo` struct, to set asset type dependent callbacks
  or data (in future). ID types can conveniently define asset-type info as part
  of their `IDTypeInfo` definition.
* The asset-type info can contain a custom callback to be executed before the
  asset is saved. This is how the object can write its custom asset metadata.
* The dropbox can also register a callback to set properties for its
  gizmo-group now. Used to copy
* The "placement plane" gizmo is scaled to the bounding box size too.
* For local ID assets, the data should be accessed directly, so the file
  doesn't have to be saved to get the bounding box updated.

Also:
* Added proper gizmo group custom property support to C (was already supported
  in Python, or in C with some hacking).
* Store the basis matrix (world matrix without parent or constraint transforms)
  in the custom asset metadata. Used by the placement gizmo to scale the
  bounding box to match the result visually when dropping.
* The preview image is disabled while dragging objects over the 3D view.
* The bounding box always snaps with its lower edge (Z axis) to the surface.
  Snapping with other axes can be added still.
* However, actually dropping the object still uses the origin, so the drop
  position may not match what the bounding box indicated. This could be changed
  to also use the bounding box instead. Or the drawn bounding box should be
  translated to respect the origin position.

===================================================================

M	source/blender/blenkernel/BKE_asset.h
M	source/blender/blenkernel/BKE_idtype.h
M	source/blender/blenkernel/BKE_main.h
M	source/blender/blenkernel/intern/asset.cc
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/editors/asset/asset_edit.cc
M	source/blender/editors/include/ED_asset.h
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_view3d/space_view3d.c
M	source/blender/editors/space_view3d/view3d_placement.c
M	source/blender/makesdna/DNA_asset_types.h
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/WM_types.h
M	source/blender/windowmanager/gizmo/WM_gizmo_types.h
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c
M	source/blender/windowmanager/intern/wm_dragdrop.c
M	source/blender/windowmanager/intern/wm_files.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index d1f543b1f38..38c053607f5 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -20,17 +20,30 @@
 
 #pragma once
 
+#include "BLI_compiler_attrs.h"
 #include "BLI_utildefines.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct AssetMetaData;
 struct BlendDataReader;
 struct BlendWriter;
 struct ID;
+struct IDProperty;
 struct PreviewImage;
 
+typedef void (*PreSaveFn)(void *asset_ptr, struct AssetMetaData *asset_data);
+
+typedef struct AssetTypeInfo {
+  /**
+   * For local assets (assets in the current .blend file), a callback to execute before the file is
+   * saved.
+   */
+  PreSaveFn pre_save_fn;
+} AssetTypeInfo;
+
 struct AssetMetaData *BKE_asset_metadata_create(void);
 void BKE_asset_metadata_free(struct AssetMetaData **asset_data);
 
@@ -45,6 +58,10 @@ struct AssetTagEnsureResult BKE_asset_metadata_tag_ensure(struct AssetMetaData *
                                                           const char *name);
 void BKE_asset_metadata_tag_remove(struct AssetMetaData *asset_data, struct AssetTag *tag);
 
+void BKE_asset_metadata_idprop_ensure(struct AssetMetaData *asset_data, struct IDProperty *prop);
+struct IDProperty *BKE_asset_metadata_idprop_find(const struct AssetMetaData *asset_data,
+                                                  const char *name) ATTR_WARN_UNUSED_RESULT;
+
 struct PreviewImage *BKE_asset_metadata_preview_get_from_id(const struct AssetMetaData *asset_data,
                                                             const struct ID *owner_id);
 
diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h
index 4578f1c3ca5..be3691009d2 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -223,6 +223,11 @@ typedef struct IDTypeInfo {
    * \note Currently needed for some update operation on point caches.
    */
   IDTypeLibOverrideApplyPost lib_override_apply_post;
+
+  /**
+   * Callbacks for assets, based on the type of asset.
+   */
+  struct AssetTypeInfo *asset_type_info;
 } IDTypeInfo;
 
 /* ********** Declaration of each IDTypeInfo. ********** */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 2c6e5ed3873..4b279dfee67 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -212,9 +212,9 @@ struct GSet *BKE_main_gset_create(struct Main *bmain, struct GSet *gset);
 
 #define FOREACH_MAIN_LISTBASE_ID_BEGIN(_lb, _id) \
   { \
-    ID *_id_next = (_lb)->first; \
+    ID *_id_next = (ID *)(_lb)->first; \
     for ((_id) = _id_next; (_id) != NULL; (_id) = _id_next) { \
-      _id_next = (_id)->next;
+      _id_next = (ID *)(_id)->next;
 
 #define FOREACH_MAIN_LISTBASE_ID_END \
   } \
diff --git a/source/blender/blenkernel/intern/asset.cc b/source/blender/blenkernel/intern/asset.cc
index b5a7f5e37a6..412fdcf6944 100644
--- a/source/blender/blenkernel/intern/asset.cc
+++ b/source/blender/blenkernel/intern/asset.cc
@@ -110,6 +110,25 @@ void BKE_asset_metadata_tag_remove(AssetMetaData *asset_data, AssetTag *tag)
   BLI_assert(BLI_listbase_count(&asset_data->tags) == asset_data->tot_tags);
 }
 
+void BKE_asset_metadata_idprop_ensure(AssetMetaData *asset_data, IDProperty *prop)
+{
+  if (!asset_data->properties) {
+    IDPropertyTemplate val = {0};
+    asset_data->properties = IDP_New(IDP_GROUP, &val, "AssetMetaData.properties");
+  }
+  /* Important: The property may already exist. For now just allow always allow a newly allocated
+   * property, and replace the existing one as a way of updating. */
+  IDP_ReplaceInGroup(asset_data->properties, prop);
+}
+
+IDProperty *BKE_asset_metadata_idprop_find(const AssetMetaData *asset_data, const char *name)
+{
+  if (!asset_data->properties) {
+    return nullptr;
+  }
+  return IDP_GetPropertyFromGroup(asset_data->properties, name);
+}
+
 /* Queries -------------------------------------------- */
 
 PreviewImage *BKE_asset_metadata_preview_get_from_id(const AssetMetaData *UNUSED(asset_data),
@@ -139,6 +158,7 @@ void BKE_asset_metadata_write(BlendWriter *writer, AssetMetaData *asset_data)
 void BKE_asset_metadata_read(BlendDataReader *reader, AssetMetaData *asset_data)
 {
   /* asset_data itself has been read already. */
+  asset_data->local_type_info = nullptr;
 
   if (asset_data->properties) {
     BLO_read_data_address(reader, &asset_data->properties);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 24593bf3812..7cde6e8d297 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -82,6 +82,7 @@
 #include "BKE_anim_visualization.h"
 #include "BKE_animsys.h"
 #include "BKE_armature.h"
+#include "BKE_asset.h"
 #include "BKE_camera.h"
 #include "BKE_collection.h"
 #include "BKE_constraint.h"
@@ -1132,6 +1133,57 @@ static void object_lib_override_apply_post(ID *id_dst, ID *UNUSED(id_src))
   BLI_freelistN(&pidlist);
 }
 
+static IDProperty *object_asset_boundbox_hint_property(Object *ob)
+{
+  BoundBox *boundbox = BKE_object_boundbox_get(ob);
+  if (!boundbox) {
+    return NULL;
+  }
+
+  IDPropertyTemplate idprop = {0};
+  idprop.array.len = sizeof(boundbox->vec) / sizeof(**boundbox->vec);
+  idprop.array.type = IDP_FLOAT;
+
+  IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "boundbox_hint");
+  memcpy(IDP_Array(property), boundbox->vec, sizeof(boundbox->vec));
+
+  return property;
+}
+
+static IDProperty *object_asset_matrix_basis_property(Object *ob)
+{
+  float mat[4][4];
+  IDPropertyTemplate idprop = {0};
+  idprop.array.len = sizeof(mat) / sizeof(**mat);
+  idprop.array.type = IDP_FLOAT;
+
+  IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "matrix_basis");
+  BKE_object_to_mat4(ob, (float(*)[])IDP_Array(property));
+
+  return property;
+}
+
+static void object_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data)
+{
+  Object *ob = asset_ptr;
+  BLI_assert(GS(ob->id.name) == ID_OB);
+
+  /* Update bounding-box hint for the asset. */
+  IDProperty *boundbox_prop = object_asset_boundbox_hint_property(ob);
+  if (boundbox_prop) {
+    BKE_asset_metadata_idprop_ensure(asset_data, boundbox_prop);
+  }
+  /* Base matrix (object matrix without parent or constraint transforms). */
+  IDProperty *base_matrix_prop = object_asset_matrix_basis_property(ob);
+  if (base_matrix_prop) {
+    BKE_asset_metadata_idprop_ensure(asset_data, base_matrix_prop);
+  }
+}
+
+AssetTypeInfo AssetType_OB = {
+    .pre_save_fn = object_asset_pre_save,
+};
+
 IDTypeInfo IDType_ID_OB = {
     .id_code = ID_OB,
     .id_filter = FILTER_ID_OB,
@@ -1158,6 +1210,8 @@ IDTypeInfo IDType_ID_OB = {
     .blend_read_undo_preserve = NULL,
 
     .lib_override_apply_post = object_lib_override_apply_post,
+
+    .asset_type_info = &AssetType_OB,
 };
 
 void BKE_object_workob_clear(Object *workob)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index b4623425582..da3d0685d46 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2466,6 +2466,9 @@ static void direct_link_id_common(
   if (id->asset_data) {
     BLO_read_data_address(reader, &id->asset_data);
     BKE_asset_metadata_read(reader, id->asset_data);
+    /* Restore runtime asset type info. */
+    const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id);
+    id->asset_data->local_type_info = id_type->asset_type_info;
   }
 
   /*link direct data of ID properties*/
diff --git a/source/blender/editors/asset/asset_edit.cc b/source/blender/editors/asset/asset_edit.cc
index d20de4141cb..f695694c77c 100644
--- a/source/blender/editors/asset/asset_edit.cc
+++ b/source/blender/editors/asset/asset_edit.cc
@@ -20,9 +20,12 @@
 
 #include "BKE_asset.h"
 #include "BKE_context.h"
+#include "BKE_idtype.h"
 #include "BKE_lib_id.h"
+#include "BKE_main.h"
 
 #include "DNA_ID.h"
+#include "DNA_asset_types.h"
 
 #include "UI_interface_icons.h"
 
@@ -41,7 +44,9 @@ bool ED_asset_mark_id(const bContext *C, ID *id)
 
   id_fake_user_set(id);
 
+  const IDTypeInfo *id_type_info = BKE_idtype_get_info_from_id(id);
   id->asset_data = BKE_asset_metadata_create();
+  id->asset_data->local_type_info = id_type_info->asset_type_info;
 
   UI_icon_render_id(C, nullptr, id, ICON_SIZE_PREVIEW, true);
 
@@ -60,6 +65,21 @@ bool ED_asset_clear_id(ID *id)
   return true;
 }
 
+void ED_assets_pre_save(struct Main *bmain)
+{
+  ID *id;
+  FOREACH_MAIN_ID_BEGIN (bmain, id) {
+    if (!id->asset_data || !id->asset_data->local_type_info) {
+      continue;
+    }
+
+    if (id->asset_data->local_type_info->pre_save_fn) {
+      id->asset_data->local_type_info->pre_save_fn(id, id->asset_data);
+    }
+  }
+  FOREACH_MAIN_ID_END;
+}
+
 bool ED_asset_can_make_single_from_context(const bContext *C)
 {
   /* Context needs a "id" pointer to be set for #ASSET_OT_mark()/#ASSET_OT_clear() to use. */
diff --git a/source/blender/editors/include/ED_asset.h b/source/blender/editors/include/ED_asset.h
index dd505167fe5..daa20355af8 100644
--- a/source/blender/editors/include/ED_asset.h
+++ b/source/blender/editors/include/ED_asset.h
@@ -24,9 +24,13 @@
 extern "C" {
 #endif
 
+struct bMain;
+
 bool ED_asset_mark_id(const struct bContext *C, struct ID *id);
 bool ED_asset_clear_id(struct ID *id);
 
+void ED_assets_pre_save(struct Main *bmain);
+
 bool ED_asset_can_make_single_from_context(const struct bContext *C);
 
 void ED_operatortypes_asset(void);
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 338b12f7985..b6602756029 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -34,6 +34,7 @@ extern "C" {
 /* Struct Declarations */
 
 struct ARegion;
+struct AssetMetaData;
 struct AutoComplete;
 struct EnumPropertyItem;
 struct FileSelectParams;
@@ -723,6 +724,7 @@ void UI_but_drag_set_asset(uiBut *but,
                            const char *name,
                            const char *path,
                            int id_type,
+        

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list