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 BlendExpander;
|
||||||
struct BlendLibReader;
|
struct BlendLibReader;
|
||||||
struct BlendWriter;
|
struct BlendWriter;
|
||||||
|
struct BoundBox;
|
||||||
struct Collection;
|
struct Collection;
|
||||||
struct Library;
|
struct Library;
|
||||||
struct Main;
|
struct Main;
|
||||||
@@ -38,6 +39,19 @@ typedef struct CollectionParent {
|
|||||||
struct Collection *collection;
|
struct Collection *collection;
|
||||||
} CollectionParent;
|
} 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 */
|
/* 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 Base *BKE_collection_or_layer_objects(const struct ViewLayer *view_layer,
|
||||||
struct Collection *collection);
|
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. */
|
/* Editing. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,11 +12,13 @@
|
|||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_iterator.h"
|
#include "BLI_iterator.h"
|
||||||
#include "BLI_listbase.h"
|
#include "BLI_listbase.h"
|
||||||
|
#include "BLI_math.h"
|
||||||
#include "BLI_math_base.h"
|
#include "BLI_math_base.h"
|
||||||
#include "BLI_threads.h"
|
#include "BLI_threads.h"
|
||||||
#include "BLT_translation.h"
|
#include "BLT_translation.h"
|
||||||
|
|
||||||
#include "BKE_anim_data.h"
|
#include "BKE_anim_data.h"
|
||||||
|
#include "BKE_asset.h"
|
||||||
#include "BKE_collection.h"
|
#include "BKE_collection.h"
|
||||||
#include "BKE_icons.h"
|
#include "BKE_icons.h"
|
||||||
#include "BKE_idprop.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);
|
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 = {
|
IDTypeInfo IDType_ID_GR = {
|
||||||
.id_code = ID_GR,
|
.id_code = ID_GR,
|
||||||
.id_filter = FILTER_ID_GR,
|
.id_filter = FILTER_ID_GR,
|
||||||
@@ -361,7 +400,7 @@ IDTypeInfo IDType_ID_GR = {
|
|||||||
.name_plural = "collections",
|
.name_plural = "collections",
|
||||||
.translation_context = BLT_I18NCONTEXT_ID_COLLECTION,
|
.translation_context = BLT_I18NCONTEXT_ID_COLLECTION,
|
||||||
.flags = IDTYPE_FLAGS_NO_ANIMDATA,
|
.flags = IDTYPE_FLAGS_NO_ANIMDATA,
|
||||||
.asset_type_info = NULL,
|
.asset_type_info = &AssetType_GR,
|
||||||
|
|
||||||
.init_data = collection_init_data,
|
.init_data = collection_init_data,
|
||||||
.copy_data = collection_copy_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
|
/** \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)
|
void OBJECT_OT_transform_to_mouse(wmOperatorType *ot)
|
||||||
{
|
{
|
||||||
/* identifiers */
|
/* 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->description = "Snap selected item(s) to the mouse location";
|
||||||
ot->idname = "OBJECT_OT_transform_to_mouse";
|
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);
|
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;
|
V3DSnapCursorState *state = drop->draw_data;
|
||||||
if (state) {
|
if (state) {
|
||||||
@@ -503,22 +505,14 @@ static void view3d_ob_drop_draw_activate(struct wmDropBox *drop, wmDrag *drag)
|
|||||||
return;
|
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 = drop->draw_data = ED_view3d_cursor_snap_active();
|
||||||
state->draw_plane = 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)) {
|
if (!is_zero_v3(dimensions)) {
|
||||||
mul_v3_v3fl(state->box_dimensions, dimensions, 0.5f);
|
mul_v3_v3fl(state->box_dimensions, dimensions, 0.5f);
|
||||||
UI_GetThemeColor4ubv(TH_GIZMO_PRIMARY, state->color_box);
|
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;
|
V3DSnapCursorState *state = drop->draw_data;
|
||||||
if (state) {
|
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);
|
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)
|
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)) {
|
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);
|
return (drag->type == WM_DRAG_PATH) && (drag->icon == ICON_FILE_VOLUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view3d_ob_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
static void view3d_drop_matrix_from_snap(V3DSnapCursorState *snap_state,
|
||||||
Object *ob,
|
const BoundBox *bb,
|
||||||
float obmat_final[4][4])
|
const float base_mat[4][4],
|
||||||
|
float r_mat_final[4][4])
|
||||||
{
|
{
|
||||||
V3DSnapCursorData *snap_data;
|
V3DSnapCursorData *snap_data;
|
||||||
snap_data = ED_view3d_cursor_snap_data_get(snap_state, NULL, 0, 0);
|
snap_data = ED_view3d_cursor_snap_data_get(snap_state, NULL, 0, 0);
|
||||||
BLI_assert(snap_state->draw_box || snap_state->draw_plane);
|
BLI_assert(snap_state->draw_box || snap_state->draw_plane);
|
||||||
copy_m4_m3(obmat_final, snap_data->plane_omat);
|
copy_m4_m3(r_mat_final, snap_data->plane_omat);
|
||||||
copy_v3_v3(obmat_final[3], snap_data->loc);
|
copy_v3_v3(r_mat_final[3], snap_data->loc);
|
||||||
|
|
||||||
float scale[3];
|
float scale[3];
|
||||||
mat4_to_size(scale, ob->obmat);
|
mat4_to_size(scale, base_mat);
|
||||||
rescale_m4(obmat_final, scale);
|
rescale_m4(r_mat_final, scale);
|
||||||
|
|
||||||
const BoundBox *bb = BKE_object_boundbox_get(ob);
|
|
||||||
if (bb) {
|
if (bb) {
|
||||||
float offset[3];
|
float offset[3];
|
||||||
BKE_boundbox_calc_center_aabb(bb, offset);
|
BKE_boundbox_calc_center_aabb(bb, offset);
|
||||||
offset[2] = bb->vec[0][2];
|
offset[2] = bb->vec[0][2];
|
||||||
mul_mat3_m4_v3(obmat_final, offset);
|
mul_mat3_m4_v3(r_mat_final, offset);
|
||||||
sub_v3_v3(obmat_final[3], 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)
|
static void view3d_ob_drop_copy_local_id(wmDrag *drag, wmDropBox *drop)
|
||||||
{
|
{
|
||||||
ID *id = WM_drag_get_local_ID(drag, ID_OB);
|
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);
|
V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_state_get();
|
||||||
RNA_int_set(drop->ptr, "session_uuid", (int)id->session_uuid);
|
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
|
/* 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);
|
DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
|
||||||
ED_outliner_select_sync_from_object_tag(C);
|
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
|
/* 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. */
|
* properties. The stuff we do in these drop callbacks just isn't safe over undo/redo. */
|
||||||
ED_undo_push(C, "Collection_Drop");
|
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)
|
static void view3d_id_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||||
{
|
{
|
||||||
ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0);
|
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);
|
ListBase *lb = WM_dropboxmap_find("View3D", SPACE_VIEW3D, RGN_TYPE_WINDOW);
|
||||||
|
|
||||||
struct wmDropBox *drop;
|
struct wmDropBox *drop;
|
||||||
|
/* Local object. */
|
||||||
drop = WM_dropbox_add(lb,
|
drop = WM_dropbox_add(lb,
|
||||||
"OBJECT_OT_add_named",
|
"OBJECT_OT_add_named",
|
||||||
view3d_ob_drop_poll_local_id,
|
view3d_ob_drop_poll_local_id,
|
||||||
view3d_ob_drop_copy_local_id,
|
view3d_ob_drop_copy_local_id,
|
||||||
WM_drag_free_imported_drag_ID,
|
WM_drag_free_imported_drag_ID,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
drop->draw = WM_drag_draw_item_name_fn;
|
drop->draw = WM_drag_draw_item_name_fn;
|
||||||
drop->draw_activate = view3d_ob_drop_draw_activate;
|
drop->draw_activate = view3d_boundbox_drop_draw_activate_object;
|
||||||
drop->draw_deactivate = view3d_ob_drop_draw_deactivate;
|
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||||
|
|
||||||
|
/* Object asset from external file. */
|
||||||
drop = WM_dropbox_add(lb,
|
drop = WM_dropbox_add(lb,
|
||||||
"OBJECT_OT_transform_to_mouse",
|
"OBJECT_OT_transform_to_mouse",
|
||||||
view3d_ob_drop_poll_external_asset,
|
view3d_ob_drop_poll_external_asset,
|
||||||
view3d_ob_drop_copy_external_asset,
|
view3d_ob_drop_copy_external_asset,
|
||||||
WM_drag_free_imported_drag_ID,
|
WM_drag_free_imported_drag_ID,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
drop->draw = WM_drag_draw_item_name_fn;
|
drop->draw = WM_drag_draw_item_name_fn;
|
||||||
drop->draw_activate = view3d_ob_drop_draw_activate;
|
drop->draw_activate = view3d_boundbox_drop_draw_activate_object;
|
||||||
drop->draw_deactivate = view3d_ob_drop_draw_deactivate;
|
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||||
|
|
||||||
WM_dropbox_add(lb,
|
/* Local collection (adds collection instance). */
|
||||||
"OBJECT_OT_collection_external_asset_drop",
|
drop = WM_dropbox_add(lb,
|
||||||
view3d_collection_drop_poll_external_asset,
|
"OBJECT_OT_collection_instance_add",
|
||||||
view3d_collection_drop_copy_external_asset,
|
view3d_collection_drop_poll_local_id,
|
||||||
WM_drag_free_imported_drag_ID,
|
view3d_collection_drop_copy_local_id,
|
||||||
NULL);
|
WM_drag_free_imported_drag_ID,
|
||||||
WM_dropbox_add(lb,
|
NULL);
|
||||||
"OBJECT_OT_collection_instance_add",
|
drop->draw = WM_drag_draw_item_name_fn;
|
||||||
view3d_collection_drop_poll_local_id,
|
drop->draw_activate = view3d_boundbox_drop_draw_activate_collection;
|
||||||
view3d_collection_drop_copy_local_id,
|
drop->draw_deactivate = view3d_boundbox_drop_draw_deactivate;
|
||||||
WM_drag_free_imported_drag_ID,
|
|
||||||
NULL);
|
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,
|
WM_dropbox_add(lb,
|
||||||
"OBJECT_OT_drop_named_material",
|
"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 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).
|
* \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.
|
* 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);
|
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.
|
* \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);
|
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,
|
wmDragAsset *WM_drag_create_asset_data(const AssetHandle *asset,
|
||||||
AssetMetaData *metadata,
|
AssetMetaData *metadata,
|
||||||
const char *path,
|
const char *path,
|
||||||
@@ -554,11 +569,16 @@ struct AssetMetaData *WM_drag_get_asset_meta_data(const wmDrag *drag, int idcode
|
|||||||
return NULL;
|
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. */
|
/* Only support passing in limited flags. */
|
||||||
BLI_assert(flag_extra == (flag_extra & FILE_AUTOSELECT));
|
BLI_assert(flag_extra == (flag_extra & FILE_AUTOSELECT));
|
||||||
eFileSel_Params_Flag flag = flag_extra | FILE_ACTIVE_COLLECTION;
|
eFileSel_Params_Flag flag = flag_extra | FILE_ACTIVE_COLLECTION;
|
||||||
|
if (collection_instance) {
|
||||||
|
flag |= BLO_LIBLINK_COLLECTION_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
const char *name = asset_drag->name;
|
const char *name = asset_drag->name;
|
||||||
ID_Type idtype = asset_drag->id_type;
|
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;
|
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)
|
bool WM_drag_asset_will_import_linked(const wmDrag *drag)
|
||||||
{
|
{
|
||||||
if (drag->type != WM_DRAG_ASSET) {
|
if (drag->type != WM_DRAG_ASSET) {
|
||||||
|
Reference in New Issue
Block a user