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:
authorGermano Cavalcante <mano-wii>2021-10-25 14:02:08 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-10-25 17:57:26 +0300
commita84f1c02d251a9ce6267030a46e02ed2d3ce22e1 (patch)
tree3f2e33fb29a844c2c5105862dfb99c4fb9aefcde /source/blender
parentb17038db31e0dd312dd3987fb9491bf402b3a40a (diff)
Assets: Snapping with visual feedback while dragging
The drag and drop feature of objects in 3D View has been modified to include: - Snap the object being dragged. - Visual feedback through a box and the placement tool grid. Maniphest Tasks: T90198 Differential Revision: https://developer.blender.org/D12912
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_asset.h17
-rw-r--r--source/blender/blenkernel/BKE_idtype.h5
-rw-r--r--source/blender/blenkernel/BKE_main.h4
-rw-r--r--source/blender/blenkernel/intern/asset.cc20
-rw-r--r--source/blender/blenkernel/intern/object.c37
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/editors/asset/ED_asset_mark_clear.h3
-rw-r--r--source/blender/editors/asset/intern/asset_mark_clear.cc19
-rw-r--r--source/blender/editors/include/ED_view3d.h4
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c3
-rw-r--r--source/blender/editors/interface/interface_template_asset_view.cc1
-rw-r--r--source/blender/editors/object/object_add.c28
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c84
-rw-r--r--source/blender/editors/space_view3d/view3d_cursor_snap.c61
-rw-r--r--source/blender/gpu/GPU_immediate_util.h4
-rw-r--r--source/blender/gpu/intern/gpu_immediate_util.c27
-rw-r--r--source/blender/makesdna/DNA_asset_types.h3
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/WM_types.h1
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c25
-rw-r--r--source/blender/windowmanager/intern/wm_files.c2
23 files changed, 314 insertions, 43 deletions
diff --git a/source/blender/blenkernel/BKE_asset.h b/source/blender/blenkernel/BKE_asset.h
index 42eea41b7a7..722d142b56c 100644
--- a/source/blender/blenkernel/BKE_asset.h
+++ b/source/blender/blenkernel/BKE_asset.h
@@ -20,6 +20,7 @@
#pragma once
+#include "BLI_compiler_attrs.h"
#include "BLI_utildefines.h"
#include "DNA_asset_types.h"
@@ -29,11 +30,23 @@ extern "C" {
#endif
struct AssetLibraryReference;
+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);
@@ -56,6 +69,10 @@ void BKE_asset_metadata_catalog_id_set(struct AssetMetaData *asset_data,
void BKE_asset_library_reference_init_default(struct AssetLibraryReference *library_ref);
+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 cd656d94fce..d33c24f2c75 100644
--- a/source/blender/blenkernel/BKE_idtype.h
+++ b/source/blender/blenkernel/BKE_idtype.h
@@ -228,6 +228,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 68b1b55f47f..9ded97e0003 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -244,9 +244,9 @@ void BKE_main_library_weak_reference_remove_item(struct GHash *library_weak_refe
#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 dfe568729db..7bea089b9bf 100644
--- a/source/blender/blenkernel/intern/asset.cc
+++ b/source/blender/blenkernel/intern/asset.cc
@@ -141,6 +141,25 @@ void BKE_asset_metadata_catalog_id_set(struct AssetMetaData *asset_data,
trimmed_id.copy(asset_data->catalog_simple_name, max_simple_name_length);
}
+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),
@@ -173,6 +192,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 e85c6b4c7c5..45dfb9af074 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"
@@ -1190,6 +1191,40 @@ static void object_lib_override_apply_post(ID *id_dst, ID *id_src)
BLI_freelistN(&pidlist_src);
}
+static IDProperty *object_asset_dimensions_property(Object *ob)
+{
+ float dimensions[3];
+ BKE_object_dimensions_get(ob, dimensions);
+ if (is_zero_v3(dimensions)) {
+ return NULL;
+ }
+
+ IDPropertyTemplate idprop = {0};
+ idprop.array.len = ARRAY_SIZE(dimensions);
+ idprop.array.type = IDP_FLOAT;
+
+ IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "dimensions");
+ memcpy(IDP_Array(property), dimensions, sizeof(dimensions));
+
+ 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 dimensions hint for the asset. */
+ IDProperty *dimensions_prop = object_asset_dimensions_property(ob);
+ if (dimensions_prop) {
+ BKE_asset_metadata_idprop_ensure(asset_data, dimensions_prop);
+ }
+}
+
+AssetTypeInfo AssetType_OB = {
+ .pre_save_fn = object_asset_pre_save,
+};
+
IDTypeInfo IDType_ID_OB = {
.id_code = ID_OB,
.id_filter = FILTER_ID_OB,
@@ -1216,6 +1251,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 0b69395b4f8..600abcca818 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -2211,6 +2211,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/ED_asset_mark_clear.h b/source/blender/editors/asset/ED_asset_mark_clear.h
index bab1d1bf8a5..8e6a8e11d69 100644
--- a/source/blender/editors/asset/ED_asset_mark_clear.h
+++ b/source/blender/editors/asset/ED_asset_mark_clear.h
@@ -26,6 +26,7 @@ extern "C" {
struct ID;
struct bContext;
+struct Main;
/**
* Mark the datablock as asset.
@@ -52,6 +53,8 @@ void ED_asset_generate_preview(const struct bContext *C, struct ID *id);
* \return whether the asset metadata was actually removed; false when the ID was not an asset. */
bool ED_asset_clear_id(struct ID *id);
+void ED_assets_pre_save(struct Main *bmain);
+
bool ED_asset_can_mark_single_from_context(const struct bContext *C);
#ifdef __cplusplus
diff --git a/source/blender/editors/asset/intern/asset_mark_clear.cc b/source/blender/editors/asset/intern/asset_mark_clear.cc
index 4be7376a1c3..eb254dcd28b 100644
--- a/source/blender/editors/asset/intern/asset_mark_clear.cc
+++ b/source/blender/editors/asset/intern/asset_mark_clear.cc
@@ -25,7 +25,9 @@
#include "BKE_asset.h"
#include "BKE_context.h"
+#include "BKE_idtype.h"
#include "BKE_lib_id.h"
+#include "BKE_main.h"
#include "BLO_readfile.h"
@@ -52,7 +54,9 @@ bool ED_asset_mark_id(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;
/* Important for asset storage to update properly! */
ED_assetlist_storage_tag_main_data_dirty();
@@ -79,6 +83,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_mark_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_view3d.h b/source/blender/editors/include/ED_view3d.h
index 67c470a005f..a0c733b2ebf 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -276,12 +276,15 @@ typedef struct V3DSnapCursorState {
eV3DPlaceOrient plane_orient;
uchar color_line[4];
uchar color_point[4];
+ uchar color_box[4];
float *prevpoint;
+ float box_dimensions[3];
short snap_elem_force; /* If zero, use scene settings. */
short plane_axis;
bool use_plane_axis_auto;
bool draw_point;
bool draw_plane;
+ bool draw_box;
} V3DSnapCursorState;
void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state);
@@ -293,7 +296,6 @@ V3DSnapCursorData *ED_view3d_cursor_snap_data_get(V3DSnapCursorState *state,
const struct bContext *C,
const int x,
const int y);
-
struct SnapObjectContext *ED_view3d_cursor_snap_context_ensure(struct Scene *scene);
void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d,
const float loc_prev[3],
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 4cd921bc61e..1ac20a5d070 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -37,6 +37,7 @@ extern "C" {
struct ARegion;
struct AssetFilterSettings;
struct AssetHandle;
+struct AssetMetaData;
struct AutoComplete;
struct EnumPropertyItem;
struct FileDirEntry;
@@ -785,6 +786,7 @@ void UI_but_drag_set_id(uiBut *but, struct ID *id);
void UI_but_drag_set_asset(uiBut *but,
const struct AssetHandle *asset,
const char *path,
+ struct AssetMetaData *metadata,
int import_type, /* eFileAssetImportType */
int icon,
struct ImBuf *imb,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 5068969946a..62c84ed38ff 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -6231,12 +6231,13 @@ void UI_but_drag_set_id(uiBut *but, ID *id)
void UI_but_drag_set_asset(uiBut *but,
const AssetHandle *asset,
const char *path,
+ struct AssetMetaData *metadata,
int import_type,
int icon,
struct ImBuf *imb,
float scale)
{
- wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, path, import_type);
+ wmDragAsset *asset_drag = WM_drag_create_asset_data(asset, metadata, path, import_type);
/* FIXME: This is temporary evil solution to get scene/viewlayer/etc in the copy callback of the
* #wmDropBox.
diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc
index f27b37a27de..d3ce7ebc3db 100644
--- a/source/blender/editors/interface/interface_template_asset_view.cc
+++ b/source/blender/editors/interface/interface_template_asset_view.cc
@@ -70,6 +70,7 @@ static void asset_view_item_but_drag_set(uiBut *but,
UI_but_drag_set_asset(but,
asset_handle,
BLI_strdup(blend_path),
+ ED_asset_handle_get_metadata(asset_handle),
FILE_ASSET_IMPORT_APPEND,
ED_asset_handle_get_preview_icon_id(asset_handle),
imbuf,
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 114f540b614..629f40e0ae9 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -3533,12 +3533,6 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
basen->object->visibility_flag &= ~OB_HIDE_VIEWPORT;
- int mval[2];
- if (object_add_drop_xy_get(C, op, &mval)) {
- ED_object_location_from_view(C, basen->object->loc);
- ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
- }
-
/* object_add_duplicate_internal() doesn't deselect other objects, unlike object_add_common() or
* BKE_view_layer_base_deselect_all(). */
ED_object_base_deselect_all(view_layer, NULL, SEL_DESELECT);
@@ -3556,13 +3550,29 @@ static int object_add_named_exec(bContext *C, wmOperator *op)
WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene);
ED_outliner_select_sync_from_object_tag(C);
+ PropertyRNA *prop_matrix = RNA_struct_find_property(op->ptr, "matrix");
+ if (RNA_property_is_set(op->ptr, prop_matrix)) {
+ Object *ob_add = basen->object;
+ RNA_property_float_get_array(op->ptr, prop_matrix, &ob_add->obmat[0][0]);
+ BKE_object_apply_mat4(ob_add, ob_add->obmat, true, true);
+
+ DEG_id_tag_update(&ob_add->id, ID_RECALC_TRANSFORM);
+ }
+ else {
+ int mval[2];
+ if (object_add_drop_xy_get(C, op, &mval)) {
+ ED_object_location_from_view(C, basen->object->loc);
+ ED_view3d_cursor3d_position(C, mval, false, basen->object->loc);
+ }
+ }
+
return OPERATOR_FINISHED;
}
void OBJECT_OT_add_named(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Named Object";
+ ot->name = "Add Object";
ot->description = "Add named object";
ot->idname = "OBJECT_OT_add_named";
@@ -3594,6 +3604,10 @@ void OBJECT_OT_add_named(wmOperatorType *ot)
RNA_def_string(ot->srna, "name", NULL, MAX_ID_NAME - 2, "Name", "Object name to add");
+ prop = RNA_def_float_matrix(
+ ot->srna, "matrix", 4, 4, NULL, 0.0f, 0.0f, "Matrix", "", 0.0f, 0.0f);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
+
object_add_drop_xy_props(ot);
}
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 24b24eb81dd..5c6b753d4a5 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -190,6 +190,7 @@ static void file_draw_icon(const SpaceFile *sfile,
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
+ file->asset_data,
asset_params->import_type,
icon,
preview_image,
@@ -515,6 +516,7 @@ static void file_draw_preview(const SpaceFile *sfile,
UI_but_drag_set_asset(but,
&(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
+ file->asset_data,
asset_params->import_type,
icon,
imb,
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index eb30d0987ab..eaf90aabe8c 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -40,6 +40,7 @@
#include "BLT_translation.h"
+#include "BKE_asset.h"
#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_global.h"
@@ -515,6 +516,45 @@ static bool view3d_drop_id_in_main_region_poll(bContext *C,
return WM_drag_is_ID_type(drag, id_type);
}
+static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
+{
+ V3DSnapCursorState *state = drop->draw_data;
+ if (state) {
+ return;
+ }
+ state = drop->draw_data = ED_view3d_cursor_snap_active();
+ state->draw_point = true;
+ state->draw_plane = true;
+
+ float dimensions[3] = {0.0f};
+ if (drag->type == WM_DRAG_ID) {
+ Object *ob = (Object *)WM_drag_get_local_ID(drag, ID_OB);
+ BKE_object_dimensions_get(ob, dimensions);
+ }
+ else {
+ struct AssetMetaData *meta_data = WM_drag_get_asset_meta_data(drag, ID_OB);
+ IDProperty *dimensions_prop = BKE_asset_metadata_idprop_find(meta_data, "dimensions");
+ if (dimensions_prop) {
+ copy_v3_v3(dimensions, IDP_Array(dimensions_prop));
+ }
+ }
+
+ if (!is_zero_v3(dimensions)) {
+ mul_v3_v3fl(state->box_dimensions, dimensions, 0.5f);
+ UI_GetThemeColor4ubv(TH_GIZMO_PRIMARY, state->color_box);
+ state->draw_box = true;
+ }
+}
+
+static void view3d_ob_drop_draw_deactivate(struct wmDropBox *drop, wmDrag *UNUSED(drag))
+{
+ V3DSnapCursorState *state = drop->draw_data;
+ if (state) {
+ ED_view3d_cursor_snap_deactive(state);
+ drop->draw_data = NULL;
+ }
+}
+
static bool view3d_ob_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_OB);
@@ -639,6 +679,31 @@ static void view3d_ob_drop_copy(wmDrag *drag, wmDropBox *drop)
/* Don't duplicate ID's which were just imported. Only do that for existing, local IDs. */
const bool is_imported_id = drag->type == WM_DRAG_ASSET;
RNA_boolean_set(drop->ptr, "duplicate", !is_imported_id);
+
+ V3DSnapCursorState *snap_state = drop->draw_data;
+ if (snap_state) {
+ Object *ob = (Object *)id;
+ float obmat_final[4][4];
+
+ V3DSnapCursorData *snap_data;
+ snap_data = ED_view3d_cursor_snap_data_get(snap_state, NULL, 0, 0);
+ copy_m4_m3(obmat_final, snap_data->plane_omat);
+ copy_v3_v3(obmat_final[3], snap_data->loc);
+
+ float scale[3];
+ mat4_to_size(scale, ob->obmat);
+ rescale_m4(obmat_final, scale);
+
+ BoundBox *bb = BKE_object_boundbox_get(ob);
+ if (bb) {
+ float offset[3];
+ BKE_boundbox_calc_center_aabb(bb, offset);
+ offset[2] = bb->vec[0][2];
+ mul_mat3_m4_v3(obmat_final, offset);
+ sub_v3_v3(obmat_final[3], offset);
+ }
+ RNA_float_set_array(drop->ptr, "matrix", &obmat_final[0][0]);
+ }
}
static void view3d_collection_drop_copy(wmDrag *drag, wmDropBox *drop)
@@ -703,12 +768,19 @@ static void view3d_dropboxes(void)
{
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
- WM_dropbox_add(lb,
- "OBJECT_OT_add_named",
- view3d_ob_drop_poll,
- view3d_ob_drop_copy,
- WM_drag_free_imported_drag_ID,
- NULL);
+ struct wmDropBox *drop;
+ drop = WM_dropbox_add(lb,
+ "OBJECT_OT_add_named",
+ view3d_ob_drop_poll,
+ view3d_ob_drop_copy,
+ WM_drag_free_imported_drag_ID,
+ NULL);
+
+ drop->draw = WM_drag_draw_item_name_fn;
+ drop->draw_activate = view3d_ob_drop_draw_activate;
+ drop->draw_deactivate = view3d_ob_drop_draw_deactivate;
+ drop->opcontext = WM_OP_EXEC_DEFAULT; /* Not really needed. */
+
WM_dropbox_add(lb,
"OBJECT_OT_drop_named_material",
view3d_mat_drop_poll,
diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c
index 1cb650910ce..5eb9ec3625c 100644
--- a/source/blender/editors/space_view3d/view3d_cursor_snap.c
+++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c
@@ -58,7 +58,6 @@
typedef struct SnapStateIntern {
V3DSnapCursorState snap_state;
- float prevpoint_stack[3];
int state_active_prev;
bool is_active;
} SnapStateIntern;
@@ -75,6 +74,8 @@ typedef struct SnapCursorDataIntern {
const Scene *scene;
short snap_elem_hidden;
+ float prevpoint_stack[3];
+
/* Copy of the parameters of the last event state in order to detect updates. */
struct {
int x;
@@ -94,17 +95,6 @@ typedef struct SnapCursorDataIntern {
bool is_initiated;
} SnapCursorDataIntern;
-static void UNUSED_FUNCTION(v3d_cursor_snap_state_init)(V3DSnapCursorState *state)
-{
- state->prevpoint = NULL;
- state->snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE |
- SCE_SNAP_MODE_EDGE_PERPENDICULAR | SCE_SNAP_MODE_EDGE_MIDPOINT);
- state->plane_axis = 2;
- rgba_uchar_args_set(state->color_point, 255, 255, 255, 255);
- rgba_uchar_args_set(state->color_line, 255, 255, 255, 128);
- state->draw_point = true;
- state->draw_plane = false;
-}
static SnapCursorDataIntern g_data_intern = {
.state_default = {.prevpoint = NULL,
.snap_elem_force = (SCE_SNAP_MODE_VERTEX | SCE_SNAP_MODE_EDGE |
@@ -113,8 +103,9 @@ static SnapCursorDataIntern g_data_intern = {
.plane_axis = 2,
.color_point = {255, 255, 255, 255},
.color_line = {255, 255, 255, 128},
- .draw_point = true,
- .draw_plane = false}};
+ .color_box = {255, 255, 255, 128},
+ .box_dimensions = {1.0f, 1.0f, 1.0f},
+ .draw_point = true}};
/**
* Calculate a 3x3 orientation matrix from the surface under the cursor.
@@ -373,6 +364,24 @@ static void v3d_cursor_plane_draw(const RegionView3D *rv3d,
}
}
+static void cursor_box_draw(const float dimensions[3], uchar color[4])
+{
+ GPUVertFormat *format = immVertexFormat();
+ const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
+
+ GPU_blend(GPU_BLEND_ALPHA);
+ GPU_line_smooth(true);
+ GPU_line_width(1.0f);
+
+ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
+ immUniformColor4ubv(color);
+ imm_draw_cube_corners_3d(pos_id, (float[3]){0.0f, 0.0f, dimensions[2]}, dimensions, 0.15f);
+ immUnbindProgram();
+
+ GPU_line_smooth(false);
+ GPU_blend(GPU_BLEND_NONE);
+}
+
void ED_view3d_cursor_snap_draw_util(RegionView3D *rv3d,
const float loc_prev[3],
const float loc_curr[3],
@@ -601,7 +610,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
ushort snap_elements = v3d_cursor_snap_elements(state, scene);
data_intern->snap_elem_hidden = 0;
- const bool draw_plane = state->draw_plane;
+ const bool draw_plane = state->draw_plane || state->draw_box;
if (draw_plane && !(snap_elements & SCE_SNAP_MODE_FACE)) {
data_intern->snap_elem_hidden = SCE_SNAP_MODE_FACE;
snap_elements |= SCE_SNAP_MODE_FACE;
@@ -674,6 +683,7 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
}
if (draw_plane) {
+ RegionView3D *rv3d = region->regiondata;
bool orient_surface = snap_elem && (state->plane_orient == V3D_PLACE_ORIENT_SURFACE);
if (orient_surface) {
copy_m3_m4(omat, obmat);
@@ -686,7 +696,6 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
ED_transform_calc_orientation_from_type_ex(
scene, view_layer, v3d, region->regiondata, ob, ob, orient_index, pivot_point, omat);
- RegionView3D *rv3d = region->regiondata;
if (state->use_plane_axis_auto) {
mat3_align_axis_to_v3(omat, state->plane_axis, rv3d->viewinv[2]);
}
@@ -699,6 +708,9 @@ static void v3d_cursor_snap_update(V3DSnapCursorState *state,
orthogonalize_m3(omat, state->plane_axis);
if (orient_surface) {
+ if (dot_v3v3(rv3d->viewinv[2], face_nor) < 0.0f) {
+ negate_v3(face_nor);
+ }
v3d_cursor_poject_surface_normal(face_nor, obmat, omat);
}
}
@@ -791,7 +803,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
v3d_cursor_snap_update(state, C, wm, depsgraph, scene, region, v3d, x, y);
}
- const bool draw_plane = state->draw_plane;
+ const bool draw_plane = state->draw_plane || state->draw_box;
if (!snap_data->snap_elem && !draw_plane) {
return;
}
@@ -802,8 +814,6 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
GPU_matrix_projection_set(rv3d->winmat);
GPU_matrix_set(rv3d->viewmat);
- GPU_blend(GPU_BLEND_ALPHA);
-
float matrix[4][4];
if (draw_plane) {
copy_m4_m3(matrix, snap_data->plane_omat);
@@ -812,7 +822,7 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
v3d_cursor_plane_draw(rv3d, state->plane_axis, matrix);
}
- if (snap_data->snap_elem && state->draw_point) {
+ if (snap_data->snap_elem && (state->draw_point || state->draw_box)) {
const float *prev_point = (snap_data->snap_elem & SCE_SNAP_MODE_EDGE_PERPENDICULAR) ?
state->prevpoint :
NULL;
@@ -829,7 +839,10 @@ static void v3d_cursor_snap_draw_fn(bContext *C, int x, int y, void *UNUSED(cust
snap_data->snap_elem);
}
- GPU_blend(GPU_BLEND_NONE);
+ if (state->draw_box) {
+ GPU_matrix_mul(matrix);
+ cursor_box_draw(state->box_dimensions, state->color_box);
+ }
/* Restore matrix. */
wmWindowViewport(CTX_wm_window(C));
@@ -942,10 +955,10 @@ void ED_view3d_cursor_snap_deactive(V3DSnapCursorState *state)
void ED_view3d_cursor_snap_prevpoint_set(V3DSnapCursorState *state, const float prev_point[3])
{
- SnapStateIntern *state_intern = (SnapStateIntern *)state;
+ SnapCursorDataIntern *data_intern = &g_data_intern;
if (prev_point) {
- copy_v3_v3(state_intern->prevpoint_stack, prev_point);
- state->prevpoint = state_intern->prevpoint_stack;
+ copy_v3_v3(data_intern->prevpoint_stack, prev_point);
+ state->prevpoint = data_intern->prevpoint_stack;
}
else {
state->prevpoint = NULL;
diff --git a/source/blender/gpu/GPU_immediate_util.h b/source/blender/gpu/GPU_immediate_util.h
index 3ea809d59a7..793348ad8d2 100644
--- a/source/blender/gpu/GPU_immediate_util.h
+++ b/source/blender/gpu/GPU_immediate_util.h
@@ -80,6 +80,10 @@ void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2);
void imm_draw_cube_fill_3d(uint pos, const float co[3], const float aspect[3]);
void imm_draw_cube_wire_3d(uint pos, const float co[3], const float aspect[3]);
+void imm_draw_cube_corners_3d(uint pos,
+ const float co[3],
+ const float aspect[3],
+ const float factor);
void imm_draw_cylinder_fill_normal_3d(
uint pos, uint nor, float base, float top, float height, int slices, int stacks);
diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c
index d18dc862ce7..d848ea09a2a 100644
--- a/source/blender/gpu/intern/gpu_immediate_util.c
+++ b/source/blender/gpu/intern/gpu_immediate_util.c
@@ -428,6 +428,33 @@ void imm_draw_cube_wire_3d(uint pos, const float co[3], const float aspect[3])
immEnd();
}
+void imm_draw_cube_corners_3d(uint pos,
+ const float co[3],
+ const float aspect[3],
+ const float factor)
+{
+ float coords[ARRAY_SIZE(cube_coords)][3];
+
+ for (int i = 0; i < ARRAY_SIZE(cube_coords); i++) {
+ madd_v3_v3v3v3(coords[i], co, cube_coords[i], aspect);
+ }
+
+ immBegin(GPU_PRIM_LINES, ARRAY_SIZE(cube_line_index) * 4);
+ for (int i = 0; i < ARRAY_SIZE(cube_line_index); i++) {
+ float vec[3], co[3];
+ sub_v3_v3v3(vec, coords[cube_line_index[i][1]], coords[cube_line_index[i][0]]);
+ mul_v3_fl(vec, factor);
+
+ immVertex3fv(pos, coords[cube_line_index[i][0]]);
+ add_v3_v3v3(co, coords[cube_line_index[i][0]], vec);
+ immVertex3fv(pos, co);
+ sub_v3_v3v3(co, coords[cube_line_index[i][1]], vec);
+ immVertex3fv(pos, co);
+ immVertex3fv(pos, coords[cube_line_index[i][1]]);
+ }
+ immEnd();
+}
+
/**
* Draw a cylinder. Replacement for gluCylinder.
* _warning_ : Slow, better use it only if you no other choices.
diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h
index 60de254fec7..bd604b90b5a 100644
--- a/source/blender/makesdna/DNA_asset_types.h
+++ b/source/blender/makesdna/DNA_asset_types.h
@@ -56,6 +56,9 @@ typedef struct AssetFilterSettings {
* more than that from the file. So pointers to other IDs or ID data are strictly forbidden.
*/
typedef struct AssetMetaData {
+ /** Runtime type, to reference event callbacks. Only valid for local assets. */
+ struct AssetTypeInfo *local_type_info;
+
/** Custom asset meta-data. Cannot store pointers to IDs (#STRUCT_NO_DATABLOCK_IDPROPERTIES)! */
struct IDProperty *properties;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index c7087b28783..2988aacc4d3 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -757,9 +757,11 @@ struct ID *WM_drag_get_local_ID_from_event(const struct wmEvent *event, short id
bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
wmDragAsset *WM_drag_create_asset_data(const struct AssetHandle *asset,
+ struct AssetMetaData *metadata,
const char *path,
int import_type);
struct wmDragAsset *WM_drag_get_asset_data(const struct wmDrag *drag, int idcode);
+struct AssetMetaData *WM_drag_get_asset_meta_data(const struct wmDrag *drag, int idcode);
struct ID *WM_drag_get_local_ID_or_import_from_asset(const struct wmDrag *drag, int idcode);
void WM_drag_free_imported_drag_ID(struct Main *bmain,
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index bbfc9d53e44..2813047f0e4 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -989,6 +989,7 @@ typedef struct wmDragAsset {
/* Always freed. */
const char *path;
int id_type;
+ struct AssetMetaData *metadata;
int import_type; /* eFileAssetImportType */
/* FIXME: This is temporary evil solution to get scene/view-layer/etc in the copy callback of the
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index bad58c32cdb..f78bd528c5e 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -40,6 +40,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@@ -405,11 +406,15 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
/**
* \note: Does not store \a asset in any way, so it's fine to pass a temporary.
*/
-wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset, const char *path, int import_type)
+wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset,
+ AssetMetaData *metadata,
+ const char *path,
+ int import_type)
{
wmDragAsset *asset_drag = MEM_mallocN(sizeof(*asset_drag), "wmDragAsset");
BLI_strncpy(asset_drag->name, ED_asset_handle_get_name(asset), sizeof(asset_drag->name));
+ asset_drag->metadata = metadata;
asset_drag->path = path;
asset_drag->id_type = ED_asset_handle_get_id_type(asset);
asset_drag->import_type = import_type;
@@ -433,6 +438,21 @@ wmDragAsset *WM_drag_get_asset_data(const wmDrag *drag, int idcode)
return (ELEM(idcode, 0, asset_drag->id_type)) ? asset_drag : NULL;
}
+struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode)
+{
+ wmDragAsset *drag_asset = WM_drag_get_asset_data(drag, idcode);
+ if (drag_asset) {
+ return drag_asset->metadata;
+ }
+
+ ID *local_id = WM_drag_get_local_ID(drag, idcode);
+ if (local_id) {
+ return local_id->asset_data;
+ }
+
+ return NULL;
+}
+
static ID *wm_drag_asset_id_import(wmDragAsset *asset_drag)
{
const char *name = asset_drag->name;
@@ -566,11 +586,12 @@ void WM_drag_add_asset_list_item(
drag_asset->asset_data.local_id = local_id;
}
else {
+ AssetMetaData *metadata = ED_asset_handle_get_metadata(asset);
char asset_blend_path[FILE_MAX_LIBEXTRA];
ED_asset_handle_get_full_library_path(C, asset_library_ref, asset, asset_blend_path);
drag_asset->is_external = true;
drag_asset->asset_data.external_info = WM_drag_create_asset_data(
- asset, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
+ asset, metadata, BLI_strdup(asset_blend_path), FILE_ASSET_IMPORT_APPEND);
}
BLI_addtail(&drag->asset_items, drag_asset);
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 2525c627785..8fcc30dfed7 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -1788,6 +1788,7 @@ static bool wm_file_write(bContext *C,
/* Call pre-save callbacks before writing preview,
* that way you can generate custom file thumbnail. */
BKE_callback_exec_null(bmain, BKE_CB_EVT_SAVE_PRE);
+ ED_assets_pre_save(bmain);
/* Enforce full override check/generation on file save. */
BKE_lib_override_library_main_operations_create(bmain, true);
@@ -2105,6 +2106,7 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op)
}
BKE_callback_exec_null(bmain, BKE_CB_EVT_SAVE_PRE);
+ ED_assets_pre_save(bmain);
/* check current window and close it if temp */
if (win && WM_window_is_temp_screen(win)) {