Compare commits
13 Commits
temp-colle
...
temp-colle
Author | SHA1 | Date | |
---|---|---|---|
a6896bda89 | |||
22e102efae | |||
16ae0e7e0a | |||
2aec6f88f0 | |||
2bc1dcdb1a | |||
4d5bb5e3de | |||
143a7cf055 | |||
2f11352251 | |||
3ef54e21cf | |||
d64b07c3ae | |||
46ae259390 | |||
fcdc3f00e1 | |||
d1e59b29c9 |
@@ -25,6 +25,7 @@ struct BlendDataReader;
|
||||
struct BlendExpander;
|
||||
struct BlendLibReader;
|
||||
struct BlendWriter;
|
||||
struct BoundBox;
|
||||
struct Collection;
|
||||
struct Library;
|
||||
struct Main;
|
||||
@@ -38,6 +39,19 @@ typedef struct CollectionParent {
|
||||
struct Collection *collection;
|
||||
} CollectionParent;
|
||||
|
||||
/**
|
||||
* Options to control how object visibility flags should affect operations. Used for bounding-box
|
||||
* calculations, for example.
|
||||
*/
|
||||
typedef enum CollectionObjectVisibility {
|
||||
/** Include all objects linked to the scene, regardless of visibility flags. */
|
||||
COLLECTION_VISIBILITY_ALL_OBJECTS,
|
||||
/** Exclude objects hidden with the render visibility flag. */
|
||||
COLLECTION_VISIBILITY_RENDER,
|
||||
/** Exclude objects hidden with the viewport visibility flag. */
|
||||
COLLECTION_VISIBILITY_VIEWPORT
|
||||
} CollectionObjectVisibility;
|
||||
|
||||
/* Collections */
|
||||
|
||||
/**
|
||||
@@ -206,6 +220,39 @@ void BKE_collection_object_cache_free(struct Collection *collection);
|
||||
struct Base *BKE_collection_or_layer_objects(const struct ViewLayer *view_layer,
|
||||
struct Collection *collection);
|
||||
|
||||
/* Dimensions. */
|
||||
|
||||
/**
|
||||
* Calculate an axis-aligned bounding box (in global space) of all objects in this collection,
|
||||
* excluding empties (but including lamps, cameras, curves, etc.). Nested collections and
|
||||
* collection instances are included.
|
||||
*
|
||||
* \warning This is not a reliable bounding box for things like collision detection. For example,
|
||||
* it doesn't consider particle instances or grease pencil stroke width.
|
||||
* Take it as approximation, e.g. for visual feedback.
|
||||
*
|
||||
* \param object_visibility: Define the required object visibility is (e.g. decide between viewport
|
||||
* vs. render visibility).
|
||||
*/
|
||||
void BKE_collection_boundbox_hint_calc(const struct Collection *collection,
|
||||
CollectionObjectVisibility object_visibility,
|
||||
struct BoundBox *r_boundbox);
|
||||
/**
|
||||
* Calculate axis-aligned dimensions of all objects in this collection, excluding empties (but
|
||||
* including lamps, cameras, curves, etc.). Nested collections and collection instances are
|
||||
* included.
|
||||
*
|
||||
* \warning This is not a reliable bounding box for things like collision detection. For example,
|
||||
* it doesn't consider particle instances or grease pencil stroke width.
|
||||
* Take it as approximation, e.g. for visual feedback.
|
||||
*
|
||||
* \param object_visibility: Define the required object visibility is (e.g. decide between viewport
|
||||
* vs. render visibility).
|
||||
*/
|
||||
void BKE_collection_dimensions_hint_calc(const struct Collection *collection,
|
||||
CollectionObjectVisibility object_visibility,
|
||||
float r_vec[3]);
|
||||
|
||||
/* Editing. */
|
||||
|
||||
/**
|
||||
|
@@ -12,11 +12,13 @@
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_iterator.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_threads.h"
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_asset.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -352,6 +354,43 @@ static void collection_blend_read_expand(BlendExpander *expander, ID *id)
|
||||
BKE_collection_blend_read_expand(expander, collection);
|
||||
}
|
||||
|
||||
static IDProperty *collection_asset_dimensions_property(Collection *collection)
|
||||
{
|
||||
float dimensions[3];
|
||||
/* Use the bounding-box for what the user sees, i.e. use viewport visibility. */
|
||||
BKE_collection_dimensions_hint_calc(collection, COLLECTION_VISIBILITY_VIEWPORT, dimensions);
|
||||
if (is_zero_v3(dimensions)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IDPropertyTemplate idprop = {0};
|
||||
idprop.array.len = ARRAY_SIZE(dimensions);
|
||||
idprop.array.type = IDP_FLOAT;
|
||||
|
||||
/* Note that since the dimensions are more of an approximation (e.g. excluding instances), this
|
||||
* is really just a hint for visual feedback! */
|
||||
IDProperty *property = IDP_New(IDP_ARRAY, &idprop, "dimensions_hint");
|
||||
memcpy(IDP_Array(property), dimensions, sizeof(dimensions));
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
static void collection_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_data)
|
||||
{
|
||||
Collection *collection = (Collection *)asset_ptr;
|
||||
BLI_assert(GS(collection->id.name) == ID_GR);
|
||||
|
||||
/* Update dimensions hint for the asset. */
|
||||
IDProperty *dimensions_prop = collection_asset_dimensions_property(collection);
|
||||
if (dimensions_prop) {
|
||||
BKE_asset_metadata_idprop_ensure(asset_data, dimensions_prop);
|
||||
}
|
||||
}
|
||||
|
||||
AssetTypeInfo AssetType_GR = {
|
||||
/* pre_save_fn */ collection_asset_pre_save,
|
||||
};
|
||||
|
||||
IDTypeInfo IDType_ID_GR = {
|
||||
.id_code = ID_GR,
|
||||
.id_filter = FILTER_ID_GR,
|
||||
@@ -361,7 +400,7 @@ IDTypeInfo IDType_ID_GR = {
|
||||
.name_plural = "collections",
|
||||
.translation_context = BLT_I18NCONTEXT_ID_COLLECTION,
|
||||
.flags = IDTYPE_FLAGS_NO_ANIMDATA,
|
||||
.asset_type_info = NULL,
|
||||
.asset_type_info = &AssetType_GR,
|
||||
|
||||
.init_data = collection_init_data,
|
||||
.copy_data = collection_copy_data,
|
||||
@@ -839,6 +878,105 @@ Base *BKE_collection_or_layer_objects(const ViewLayer *view_layer, Collection *c
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Collection Dimensions
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* \param with_empties: Include the location of empties in the bounding box.
|
||||
* \param instance_mat: The transform matrix of the object instancing this collection. Pass the
|
||||
* unit matrix if the collection is not an instance.
|
||||
*/
|
||||
static void collection_minmax_calc_recursive(const Collection *parent_collection,
|
||||
const CollectionObjectVisibility object_visibility,
|
||||
const bool with_empties,
|
||||
float parent_instance_mat[4][4],
|
||||
float r_min[3],
|
||||
float r_max[3])
|
||||
{
|
||||
LISTBASE_FOREACH (const CollectionObject *, cob, &parent_collection->gobject) {
|
||||
Object *ob = cob->ob;
|
||||
|
||||
if (ob->instance_collection) {
|
||||
float child_collection_mat[4][4];
|
||||
unit_m4(child_collection_mat);
|
||||
sub_v3_v3(child_collection_mat[3], ob->instance_collection->instance_offset);
|
||||
mul_m4_m4m4(child_collection_mat, ob->obmat, parent_instance_mat);
|
||||
|
||||
collection_minmax_calc_recursive(ob->instance_collection,
|
||||
object_visibility,
|
||||
with_empties,
|
||||
child_collection_mat,
|
||||
r_min,
|
||||
r_max);
|
||||
}
|
||||
|
||||
if ((object_visibility == COLLECTION_VISIBILITY_RENDER) &&
|
||||
(ob->visibility_flag & OB_HIDE_RENDER)) {
|
||||
continue;
|
||||
}
|
||||
if ((object_visibility == COLLECTION_VISIBILITY_VIEWPORT) &&
|
||||
(ob->visibility_flag & OB_HIDE_VIEWPORT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Empties don't contribute to the dimensions. */
|
||||
if (!with_empties && (ob->type == OB_EMPTY)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BoundBox *bb_object = BKE_object_boundbox_get(ob);
|
||||
if (bb_object) {
|
||||
float obmat[4][4];
|
||||
mul_m4_m4m4(obmat, ob->obmat, parent_instance_mat);
|
||||
BKE_boundbox_minmax(bb_object, obmat, r_min, r_max);
|
||||
}
|
||||
else {
|
||||
minmax_v3v3_v3(r_min, r_max, ob->obmat[3]);
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &parent_collection->children) {
|
||||
collection_minmax_calc_recursive(
|
||||
child->collection, object_visibility, with_empties, parent_instance_mat, r_min, r_max);
|
||||
}
|
||||
}
|
||||
|
||||
static void collection_minmax(const Collection *collection,
|
||||
const CollectionObjectVisibility object_visibility,
|
||||
float r_min[3],
|
||||
float r_max[3])
|
||||
{
|
||||
INIT_MINMAX(r_min, r_max);
|
||||
|
||||
/* The matrix of the */
|
||||
float instance_collection_mat[4][4];
|
||||
unit_m4(instance_collection_mat);
|
||||
|
||||
collection_minmax_calc_recursive(
|
||||
collection, object_visibility, false, instance_collection_mat, r_min, r_max);
|
||||
}
|
||||
|
||||
void BKE_collection_boundbox_hint_calc(const Collection *collection,
|
||||
const CollectionObjectVisibility object_visibility,
|
||||
BoundBox *r_boundbox)
|
||||
{
|
||||
float min[3], max[3];
|
||||
collection_minmax(collection, object_visibility, min, max);
|
||||
BKE_boundbox_init_from_minmax(r_boundbox, min, max);
|
||||
}
|
||||
|
||||
void BKE_collection_dimensions_hint_calc(const Collection *collection,
|
||||
const CollectionObjectVisibility object_visibility,
|
||||
float r_vec[3])
|
||||
{
|
||||
float min[3], max[3];
|
||||
collection_minmax(collection, object_visibility, min, max);
|
||||
sub_v3_v3v3(r_vec, max, min);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Scene Master Collection
|
||||
* \{ */
|
||||
|
@@ -3888,7 +3888,7 @@ static int object_transform_to_mouse_exec(bContext *C, wmOperator *op)
|
||||
void OBJECT_OT_transform_to_mouse(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Place Object Under Mouse";
|
||||
ot->name = "Place Object or Collection Under Mouse";
|
||||
ot->description = "Snap selected item(s) to the mouse location";
|
||||
ot->idname = "OBJECT_OT_transform_to_mouse";
|
||||
|
||||
|
@@ -490,7 +490,9 @@ 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)
|
||||
static void view3d_boundbox_drop_draw_activate(struct wmDropBox *drop,
|
||||
wmDrag *drag,
|
||||
const float dimensions[3])
|
||||
{
|
||||
V3DSnapCursorState *state = drop->draw_data;
|
||||
if (state) {
|
||||
@@ -503,22 +505,14 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
|
||||
return;
|
||||
}
|
||||
|
||||
const int drag_id_type = WM_drag_get_ID_type(drag);
|
||||
if (!ELEM(drag_id_type, ID_OB, ID_GR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state = drop->draw_data = ED_view3d_cursor_snap_active();
|
||||
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);
|
||||
@@ -526,7 +520,51 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_ob_drop_draw_deactivate(struct wmDropBox *drop, wmDrag *UNUSED(drag))
|
||||
static void view3d_boundbox_drop_draw_activate_object(struct wmDropBox *drop, wmDrag *drag)
|
||||
{
|
||||
const int drag_id_type = WM_drag_get_ID_type(drag);
|
||||
|
||||
BLI_assert(drag_id_type == ID_OB);
|
||||
|
||||
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, drag_id_type);
|
||||
IDProperty *dimensions_prop = BKE_asset_metadata_idprop_find(meta_data, "dimensions");
|
||||
if (dimensions_prop) {
|
||||
copy_v3_v3(dimensions, IDP_Array(dimensions_prop));
|
||||
}
|
||||
}
|
||||
|
||||
view3d_boundbox_drop_draw_activate(drop, drag, dimensions);
|
||||
}
|
||||
|
||||
static void view3d_boundbox_drop_draw_activate_collection(struct wmDropBox *drop, wmDrag *drag)
|
||||
{
|
||||
const int drag_id_type = WM_drag_get_ID_type(drag);
|
||||
|
||||
BLI_assert(drag_id_type == ID_GR);
|
||||
|
||||
float dimensions[3] = {0.0f};
|
||||
if (drag->type == WM_DRAG_ID) {
|
||||
Collection *collection = (Collection *)WM_drag_get_local_ID(drag, ID_GR);
|
||||
BKE_collection_dimensions_hint_calc(collection, COLLECTION_VISIBILITY_VIEWPORT, dimensions);
|
||||
}
|
||||
else {
|
||||
struct AssetMetaData *meta_data = WM_drag_get_asset_meta_data(drag, drag_id_type);
|
||||
IDProperty *dimensions_prop = BKE_asset_metadata_idprop_find(meta_data, "dimensions_hint");
|
||||
if (dimensions_prop) {
|
||||
copy_v3_v3(dimensions, IDP_Array(dimensions_prop));
|
||||
}
|
||||
}
|
||||
|
||||
view3d_boundbox_drop_draw_activate(drop, drag, dimensions);
|
||||
}
|
||||
|
||||
static void view3d_boundbox_drop_draw_deactivate(struct wmDropBox *drop, wmDrag *UNUSED(drag))
|
||||
{
|
||||
V3DSnapCursorState *state = drop->draw_data;
|
||||
if (state) {
|
||||
@@ -564,6 +602,10 @@ static bool view3d_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent
|
||||
return view3d_drop_id_in_main_region_poll(C, drag, event, ID_GR);
|
||||
}
|
||||
|
||||
/**
|
||||
* \note the term local here refers to not being an external asset,
|
||||
* poll will succeed for linked library objects.
|
||||
*/
|
||||
static bool view3d_collection_drop_poll_local_id(bContext *C, wmDrag *drag, const wmEvent *event)
|
||||
{
|
||||
if (!view3d_collection_drop_poll(C, drag, event) || (drag->type != WM_DRAG_ID)) {
|
||||
@@ -688,30 +730,37 @@ static bool view3d_volume_drop_poll(bContext *UNUSED(C),
|
||||
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
|
||||
}
|
||||
|
||||
static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
||||
Object *ob,
|
||||
float obmat_final[4][4])
|
||||
static void view3d_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
||||
const BoundBox *bb,
|
||||
const float base_mat[4][4],
|
||||
float r_mat_final[4][4])
|
||||
{
|
||||
V3DSnapCursorData *snap_data;
|
||||
snap_data = ED_view3d_cursor_snap_data_get(snap_state, NULL, 0, 0);
|
||||
BLI_assert(snap_state->draw_box || snap_state->draw_plane);
|
||||
copy_m4_m3(obmat_final, snap_data->plane_omat);
|
||||
copy_v3_v3(obmat_final[3], snap_data->loc);
|
||||
copy_m4_m3(r_mat_final, snap_data->plane_omat);
|
||||
copy_v3_v3(r_mat_final[3], snap_data->loc);
|
||||
|
||||
float scale[3];
|
||||
mat4_to_size(scale, ob->obmat);
|
||||
rescale_m4(obmat_final, scale);
|
||||
mat4_to_size(scale, base_mat);
|
||||
rescale_m4(r_mat_final, scale);
|
||||
|
||||
const 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);
|
||||
mul_mat3_m4_v3(r_mat_final, offset);
|
||||
sub_v3_v3(r_mat_final[3], offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
||||
Object *ob,
|
||||
float r_obmat_final[4][4])
|
||||
{
|
||||
view3d_drop_matrix_from_snap(snap_state, BKE_object_boundbox_get(ob), ob->obmat, r_obmat_final);
|
||||
}
|
||||
|
||||
static void view3d_ob_drop_copy_local_id(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID(drag, ID_OB);
|
||||
@@ -771,10 +820,18 @@ static void view3d_ob_drop_copy_external_asset(wmDrag *drag, wmDropBox *drop)
|
||||
}
|
||||
}
|
||||
|
||||
static void view3d_collection_drop_copy_local_id(wmDrag *drag, wmDropBox *drop)
|
||||
static void view3d_collection_drop_matrix_get(const Collection *collection,
|
||||
float r_mat_final[4][4])
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID(drag, ID_GR);
|
||||
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
|
||||
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||
const float unit_mat[4][4];
|
||||
unit_m4((float(*)[])unit_mat);
|
||||
|
||||
BoundBox boundbox;
|
||||
/* Use the bounding-box for what the user will see, i.e. use viewport visibility. */
|
||||
const CollectionObjectVisibility visibility = COLLECTION_VISIBILITY_VIEWPORT;
|
||||
BKE_collection_boundbox_hint_calc(collection, visibility, &boundbox);
|
||||
view3d_drop_matrix_from_snap(snap_state, &boundbox, unit_mat, r_mat_final);
|
||||
}
|
||||
|
||||
/* Mostly the same logic as #view3d_ob_drop_copy_external_asset(), just different enough to make
|
||||
@@ -810,11 +867,39 @@ static void view3d_collection_drop_copy_external_asset(wmDrag *drag, wmDropBox *
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||
ED_outliner_select_sync_from_object_tag(C);
|
||||
|
||||
float mat[4][4];
|
||||
view3d_collection_drop_matrix_get(collection, mat);
|
||||
|
||||
float loc[3], rot_quat[4], rot_eul[3], scale[3];
|
||||
mat4_decompose(loc, rot_quat, scale, mat);
|
||||
add_v3_v3(loc, collection->instance_offset);
|
||||
quat_to_eul(rot_eul, rot_quat);
|
||||
RNA_float_set_array(drop->ptr, "location", loc);
|
||||
RNA_float_set_array(drop->ptr, "rotation", rot_eul);
|
||||
RNA_float_set_array(drop->ptr, "scale", scale);
|
||||
|
||||
/* XXX Without an undo push here, there will be a crash when the user modifies operator
|
||||
* properties. The stuff we do in these drop callbacks just isn't safe over undo/redo. */
|
||||
ED_undo_push(C, "Collection_Drop");
|
||||
}
|
||||
|
||||
static void view3d_collection_drop_copy_local_id(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, ID_GR);
|
||||
|
||||
float mat[4][4];
|
||||
view3d_collection_drop_matrix_get((Collection *)id, mat);
|
||||
|
||||
float loc[3], rot_quat[4], rot_eul[3], scale[3];
|
||||
mat4_decompose(loc, rot_quat, scale, mat);
|
||||
quat_to_eul(rot_eul, rot_quat);
|
||||
RNA_float_set_array(drop->ptr, "location", loc);
|
||||
RNA_float_set_array(drop->ptr, "rotation", rot_eul);
|
||||
RNA_float_set_array(drop->ptr, "scale", scale);
|
||||
|
||||
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
|
||||
}
|
||||
|
||||
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
|
||||
@@ -871,40 +956,48 @@ static void view3d_dropboxes(void)
|
||||
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
||||
|
||||
struct wmDropBox *drop;
|
||||
/* Local object. */
|
||||
drop = WM_dropbox_add(lb,
|
||||
"OBJECT_OT_add_named",
|
||||
view3d_ob_drop_poll_local_id,
|
||||
view3d_ob_drop_copy_local_id,
|
||||
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->draw_activate = view3d_boundbox_drop_draw_activate_object;
|
||||
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||
|
||||
/* Object asset from external file. */
|
||||
drop = WM_dropbox_add(lb,
|
||||
"OBJECT_OT_transform_to_mouse",
|
||||
view3d_ob_drop_poll_external_asset,
|
||||
view3d_ob_drop_copy_external_asset,
|
||||
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->draw_activate = view3d_boundbox_drop_draw_activate_object;
|
||||
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||
|
||||
WM_dropbox_add(lb,
|
||||
"OBJECT_OT_collection_external_asset_drop",
|
||||
view3d_collection_drop_poll_external_asset,
|
||||
view3d_collection_drop_copy_external_asset,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
WM_dropbox_add(lb,
|
||||
"OBJECT_OT_collection_instance_add",
|
||||
view3d_collection_drop_poll_local_id,
|
||||
view3d_collection_drop_copy_local_id,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
/* Local collection (adds collection instance). */
|
||||
drop = WM_dropbox_add(lb,
|
||||
"OBJECT_OT_collection_instance_add",
|
||||
view3d_collection_drop_poll_local_id,
|
||||
view3d_collection_drop_copy_local_id,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
drop->draw = WM_drag_draw_item_name_fn;
|
||||
drop->draw_activate = view3d_boundbox_drop_draw_activate_collection;
|
||||
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||
|
||||
drop = WM_dropbox_add(lb,
|
||||
"OBJECT_OT_collection_external_asset_drop",
|
||||
view3d_collection_drop_poll_external_asset,
|
||||
view3d_collection_drop_copy_external_asset,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
NULL);
|
||||
drop->draw = WM_drag_draw_item_name_fn;
|
||||
drop->draw_activate = view3d_boundbox_drop_draw_activate_collection;
|
||||
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||
|
||||
WM_dropbox_add(lb,
|
||||
"OBJECT_OT_drop_named_material",
|
||||
|
@@ -1182,6 +1182,9 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
|
||||
|
||||
/* ID drag and drop */
|
||||
|
||||
ID *WM_drag_asset_id_import_ex(wmDragAsset *asset_drag,
|
||||
const int flag_extra,
|
||||
const bool collection_instance);
|
||||
/**
|
||||
* \param flag_extra: Additional linking flags (from #eFileSel_Params_Flag).
|
||||
*/
|
||||
@@ -1194,6 +1197,7 @@ struct ID *WM_drag_get_local_ID_from_event(const struct wmEvent *event, short id
|
||||
* Check if the drag data is either a local ID or an external ID asset of type \a idcode.
|
||||
*/
|
||||
bool WM_drag_is_ID_type(const struct wmDrag *drag, int idcode);
|
||||
int WM_drag_get_ID_type(const struct wmDrag *drag);
|
||||
|
||||
/**
|
||||
* \note: Does not store \a asset in any way, so it's fine to pass a temporary.
|
||||
|
@@ -507,6 +507,21 @@ bool WM_drag_is_ID_type(const wmDrag *drag, int idcode)
|
||||
return WM_drag_get_local_ID(drag, idcode) || WM_drag_get_asset_data(drag, idcode);
|
||||
}
|
||||
|
||||
int WM_drag_get_ID_type(const wmDrag *drag)
|
||||
{
|
||||
const ID *local_id = WM_drag_get_local_ID(drag, 0);
|
||||
if (local_id) {
|
||||
return GS(local_id->name);
|
||||
}
|
||||
|
||||
const wmDragAsset *asset_drag = WM_drag_get_asset_data(drag, 0);
|
||||
if (asset_drag) {
|
||||
return asset_drag->id_type;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset,
|
||||
AssetMetaData *metadata,
|
||||
const char *path,
|
||||
@@ -554,11 +569,16 @@ struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
||||
ID *WM_drag_asset_id_import_ex(wmDragAsset *asset_drag,
|
||||
const int flag_extra,
|
||||
const bool collection_instance)
|
||||
{
|
||||
/* Only support passing in limited flags. */
|
||||
BLI_assert(flag_extra == (flag_extra & FILE_AUTOSELECT));
|
||||
eFileSel_Params_Flag flag = flag_extra | FILE_ACTIVE_COLLECTION;
|
||||
if (collection_instance) {
|
||||
flag |= BLO_LIBLINK_COLLECTION_INSTANCE;
|
||||
}
|
||||
|
||||
const char *name = asset_drag->name;
|
||||
ID_Type idtype = asset_drag->id_type;
|
||||
@@ -602,6 +622,11 @@ ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ID *WM_drag_asset_id_import(wmDragAsset *asset_drag, const int flag_extra)
|
||||
{
|
||||
return WM_drag_asset_id_import_ex(asset_drag, flag_extra, false);
|
||||
}
|
||||
|
||||
bool WM_drag_asset_will_import_linked(const wmDrag *drag)
|
||||
{
|
||||
if (drag->type != WM_DRAG_ASSET) {
|
||||
|
Reference in New Issue
Block a user