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:
authorHans Goudey <h.goudey@me.com>2021-09-08 17:13:22 +0300
committerHans Goudey <h.goudey@me.com>2021-09-08 17:13:22 +0300
commit655223e4c67e2d3f6460eacf6ff576a60804c8b8 (patch)
treec5ebfb2accbe60dbacb259f86c4ad5c52bdd3828
parent54cc128a3171ce7c2aefc21632cc104e9d5aeea3 (diff)
parent6bc6ffc35c58ca4ac1ac1a55367e20fc06f5fe3a (diff)
Merge branch 'master' into temp-geometry-nodes-fields
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py6
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py3
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/intern/image.c67
-rw-r--r--source/blender/blenkernel/intern/image_gpu.c222
-rw-r--r--source/blender/blenkernel/intern/object.c6
-rw-r--r--source/blender/blenloader/intern/versioning_290.c27
-rw-r--r--source/blender/blenloader/intern/versioning_300.c27
-rw-r--r--source/blender/blenloader/intern/versioning_common.cc28
-rw-r--r--source/blender/blenloader/intern/versioning_common.h6
-rw-r--r--source/blender/draw/DRW_engine.h1
-rw-r--r--source/blender/draw/engines/basic/basic_engine.c75
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c7
-rw-r--r--source/blender/draw/intern/draw_manager.h1
-rw-r--r--source/blender/editors/include/ED_view3d.h10
-rw-r--r--source/blender/editors/object/object_relations.c20
-rw-r--r--source/blender/editors/space_graph/graph_slider_ops.c46
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c402
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c62
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c25
-rw-r--r--source/blender/editors/transform/transform_snap_sequencer.c2
-rw-r--r--source/blender/io/usd/intern/usd_reader_instance.cc64
-rw-r--r--source/blender/io/usd/intern/usd_reader_instance.h47
-rw-r--r--source/blender/io/usd/intern/usd_reader_stage.cc2
-rw-r--r--source/blender/makesdna/DNA_image_types.h36
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_point_instance.cc2
-rw-r--r--source/blender/nodes/intern/node_socket_declarations.cc2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c15
30 files changed, 660 insertions, 556 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 6a9306c2eab..44b77ab2aac 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2606,8 +2606,7 @@ def km_sequencer(params):
for i in range(10)
)
),
- ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'},
- {"properties": [("deselect_all", True)]}),
+ ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'}, None),
("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "shift": True},
{"properties": [("extend", True)]}),
("sequencer.select", {"type": params.select_mouse, "value": 'PRESS', "alt": True},
@@ -6997,8 +6996,7 @@ def km_sequencer_editor_tool_select(params):
"Sequencer Tool: Select",
{"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'},
{"items": [
- ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'},
- {"properties": [("deselect_all", not params.legacy)]}),
+ ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS'}, None),
*_template_items_change_frame(params),
]},
)
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index dba94d71a43..dbe351eb10c 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -1814,8 +1814,7 @@ def km_sequencer(params):
for i in range(10)
)
),
- ("sequencer.select", {"type": 'LEFTMOUSE', "value": 'PRESS'},
- {"properties": [("deselect_all", True)]}),
+ ("sequencer.select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
("sequencer.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True},
{"properties": [("extend", True)]}),
("sequencer.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True},
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 31b3cd66cbb..0e153c5a82a 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -463,6 +463,8 @@ void BKE_object_replace_data_on_shallow_copy(struct Object *ob, struct ID *new_d
struct PartEff;
struct PartEff *BKE_object_do_version_give_parteff_245(struct Object *ob);
+bool BKE_object_supports_material_slots(struct Object *ob);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index d87290e1eb4..33f007c6dee 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -155,7 +155,9 @@ static void image_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
for (int eye = 0; eye < 2; eye++) {
for (int i = 0; i < TEXTARGET_COUNT; i++) {
- image_dst->gputexture[i][eye] = NULL;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ image_dst->gputexture[i][eye][resolution] = NULL;
+ }
}
}
@@ -208,9 +210,11 @@ static void image_foreach_cache(ID *id,
for (int eye = 0; eye < 2; eye++) {
for (int a = 0; a < TEXTARGET_COUNT; a++) {
- key.offset_in_ID = offsetof(Image, gputexture[a][eye]);
- key.cache_v = image->gputexture[a][eye];
- function_callback(id, &key, (void **)&image->gputexture[a][eye], 0, user_data);
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ key.offset_in_ID = offsetof(Image, gputexture[a][eye][resolution]);
+ key.cache_v = image->gputexture[a][eye];
+ function_callback(id, &key, (void **)&image->gputexture[a][eye][resolution], 0, user_data);
+ }
}
}
@@ -239,7 +243,9 @@ static void image_blend_write(BlendWriter *writer, ID *id, const void *id_addres
BLI_listbase_clear(&ima->gpu_refresh_areas);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
- ima->gputexture[i][j] = NULL;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ ima->gputexture[i][j][resolution] = NULL;
+ }
}
}
@@ -677,8 +683,10 @@ bool BKE_image_has_opengl_texture(Image *ima)
{
for (int eye = 0; eye < 2; eye++) {
for (int i = 0; i < TEXTARGET_COUNT; i++) {
- if (ima->gputexture[i][eye] != NULL) {
- return true;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ if (ima->gputexture[i][eye][resolution] != NULL) {
+ return true;
+ }
}
}
}
@@ -3531,9 +3539,11 @@ static void image_free_tile(Image *ima, ImageTile *tile)
}
for (int eye = 0; eye < 2; eye++) {
- if (ima->gputexture[i][eye] != NULL) {
- GPU_texture_free(ima->gputexture[i][eye]);
- ima->gputexture[i][eye] = NULL;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ if (ima->gputexture[i][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[i][eye][resolution]);
+ ima->gputexture[i][eye][resolution] = NULL;
+ }
}
}
}
@@ -3801,14 +3811,16 @@ ImageTile *BKE_image_add_tile(struct Image *ima, int tile_number, const char *la
}
for (int eye = 0; eye < 2; eye++) {
- /* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL;
- }
- if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ /* Reallocate GPU tile array. */
+ if (ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution]);
+ ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution] = NULL;
+ }
+ if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution]);
+ ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution] = NULL;
+ }
}
}
@@ -3863,14 +3875,17 @@ void BKE_image_reassign_tile(struct Image *ima, ImageTile *tile, int new_tile_nu
}
for (int eye = 0; eye < 2; eye++) {
- /* Reallocate GPU tile array. */
- if (ima->gputexture[TEXTARGET_2D_ARRAY][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye]);
- ima->gputexture[TEXTARGET_2D_ARRAY][eye] = NULL;
- }
- if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye] != NULL) {
- GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye]);
- ima->gputexture[TEXTARGET_TILE_MAPPING][eye] = NULL;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+
+ /* Reallocate GPU tile array. */
+ if (ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution]);
+ ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution] = NULL;
+ }
+ if (ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution]);
+ ima->gputexture[TEXTARGET_TILE_MAPPING][eye][resolution] = NULL;
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/image_gpu.c b/source/blender/blenkernel/intern/image_gpu.c
index d179dd40c33..9712e912bed 100644
--- a/source/blender/blenkernel/intern/image_gpu.c
+++ b/source/blender/blenkernel/intern/image_gpu.c
@@ -49,6 +49,7 @@
/* Prototypes. */
static void gpu_free_unused_buffers(void);
static void image_free_gpu(Image *ima, const bool immediate);
+static void image_free_gpu_limited_scale(Image *ima);
static void image_update_gputexture_ex(
Image *ima, ImageTile *tile, ImBuf *ibuf, int x, int y, int w, int h);
@@ -97,9 +98,11 @@ static int smaller_power_of_2_limit(int num, bool limit_gl_texture_size)
return power_of_2_min_i(GPU_texture_size_with_limit(num, limit_gl_texture_size));
}
-static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multiview_eye)
+static GPUTexture *gpu_texture_create_tile_mapping(
+ Image *ima, const int multiview_eye, const eImageTextureResolution texture_resolution)
{
- GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye];
+ const int resolution = (texture_resolution == IMA_TEXTURE_RESOLUTION_LIMITED) ? 1 : 0;
+ GPUTexture *tilearray = ima->gputexture[TEXTARGET_2D_ARRAY][multiview_eye][resolution];
if (tilearray == NULL) {
return 0;
@@ -121,13 +124,14 @@ static GPUTexture *gpu_texture_create_tile_mapping(Image *ima, const int multivi
}
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
int i = tile->tile_number - 1001;
- data[4 * i] = tile->runtime.tilearray_layer;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ data[4 * i] = tile_runtime->tilearray_layer;
float *tile_info = &data[4 * width + 4 * i];
- tile_info[0] = tile->runtime.tilearray_offset[0] / array_w;
- tile_info[1] = tile->runtime.tilearray_offset[1] / array_h;
- tile_info[2] = tile->runtime.tilearray_size[0] / array_w;
- tile_info[3] = tile->runtime.tilearray_size[1] / array_h;
+ tile_info[0] = tile_runtime->tilearray_offset[0] / array_w;
+ tile_info[1] = tile_runtime->tilearray_offset[1] / array_h;
+ tile_info[2] = tile_runtime->tilearray_size[0] / array_w;
+ tile_info[3] = tile_runtime->tilearray_size[1] / array_h;
}
GPUTexture *tex = GPU_texture_create_1d_array(ima->id.name + 2, width, 2, 1, GPU_RGBA32F, data);
@@ -152,9 +156,12 @@ static int compare_packtile(const void *a, const void *b)
return tile_a->pack_score < tile_b->pack_score;
}
-static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
+static GPUTexture *gpu_texture_create_tile_array(Image *ima,
+ ImBuf *main_ibuf,
+ const eImageTextureResolution texture_resolution)
{
- const bool limit_gl_texture_size = (ima->gpuflag & IMA_GPU_MAX_RESOLUTION) == 0;
+ const bool limit_gl_texture_size = texture_resolution == IMA_TEXTURE_RESOLUTION_LIMITED;
+ const int resolution = texture_resolution == IMA_TEXTURE_RESOLUTION_LIMITED ? 1 : 0;
int arraywidth = 0, arrayheight = 0;
ListBase boxes = {NULL};
@@ -200,14 +207,15 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
LISTBASE_FOREACH (PackTile *, packtile, &packed) {
ImageTile *tile = packtile->tile;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ int *tileoffset = tile_runtime->tilearray_offset;
+ int *tilesize = tile_runtime->tilearray_size;
tileoffset[0] = packtile->boxpack.x;
tileoffset[1] = packtile->boxpack.y;
tilesize[0] = packtile->boxpack.w;
tilesize[1] = packtile->boxpack.h;
- tile->runtime.tilearray_layer = arraylayers;
+ tile_runtime->tilearray_layer = arraylayers;
}
BLI_freelistN(&packed);
@@ -221,9 +229,10 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
/* Upload each tile one by one. */
LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
- int tilelayer = tile->runtime.tilearray_layer;
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ int tilelayer = tile_runtime->tilearray_layer;
+ int *tileoffset = tile_runtime->tilearray_offset;
+ int *tilesize = tile_runtime->tilearray_size;
if (tilesize[0] == 0 || tilesize[1] == 0) {
continue;
@@ -268,16 +277,33 @@ static GPUTexture *gpu_texture_create_tile_array(Image *ima, ImBuf *main_ibuf)
/** \name Regular gpu texture
* \{ */
+static bool image_max_resolution_texture_fits_in_limited_scale(Image *ima,
+ eGPUTextureTarget textarget,
+ const int multiview_eye)
+{
+ BLI_assert_msg(U.glreslimit != 0,
+ "limited scale function called without limited scale being set.");
+ GPUTexture *max_resolution_texture =
+ ima->gputexture[textarget][multiview_eye][IMA_TEXTURE_RESOLUTION_FULL];
+ if (max_resolution_texture && GPU_texture_width(max_resolution_texture) <= U.glreslimit &&
+ GPU_texture_height(max_resolution_texture) <= U.glreslimit) {
+ return true;
+ }
+ return false;
+}
+
static GPUTexture **get_image_gpu_texture_ptr(Image *ima,
eGPUTextureTarget textarget,
- const int multiview_eye)
+ const int multiview_eye,
+ const eImageTextureResolution texture_resolution)
{
const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT);
BLI_assert(in_range);
BLI_assert(multiview_eye == 0 || multiview_eye == 1);
+ const int resolution = (texture_resolution == IMA_TEXTURE_RESOLUTION_LIMITED) ? 1 : 0;
if (in_range) {
- return &(ima->gputexture[textarget][multiview_eye]);
+ return &(ima->gputexture[textarget][multiview_eye][resolution]);
}
return NULL;
}
@@ -296,6 +322,21 @@ static GPUTexture *image_gpu_texture_error_create(eGPUTextureTarget textarget)
}
}
+static void image_update_reusable_textures(Image *ima,
+ eGPUTextureTarget textarget,
+ const int multiview_eye)
+{
+ if ((ima->gpuflag & IMA_GPU_HAS_LIMITED_SCALE_TEXTURES) == 0) {
+ return;
+ }
+
+ if (ELEM(textarget, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
+ if (image_max_resolution_texture_fits_in_limited_scale(ima, textarget, multiview_eye)) {
+ image_free_gpu_limited_scale(ima);
+ }
+ }
+}
+
static GPUTexture *image_get_gpu_texture(Image *ima,
ImageUser *iuser,
ImBuf *ibuf,
@@ -315,24 +356,17 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
short requested_pass = iuser ? iuser->pass : 0;
short requested_layer = iuser ? iuser->layer : 0;
short requested_view = iuser ? iuser->multi_index : 0;
- const bool limit_resolution = U.glreslimit != 0 &&
- ((iuser && (iuser->flag & IMA_SHOW_MAX_RESOLUTION) == 0) ||
- (iuser == NULL));
- short requested_gpu_flags = limit_resolution ? 0 : IMA_GPU_MAX_RESOLUTION;
-#define GPU_FLAGS_TO_CHECK (IMA_GPU_MAX_RESOLUTION)
/* There is room for 2 multiview textures. When a higher number is requested we should always
* target the first view slot. This is fine as multi view images aren't used together. */
if (requested_view < 2) {
requested_view = 0;
}
if (ima->gpu_pass != requested_pass || ima->gpu_layer != requested_layer ||
- ima->gpu_view != requested_view ||
- ((ima->gpuflag & GPU_FLAGS_TO_CHECK) != requested_gpu_flags)) {
+ ima->gpu_view != requested_view) {
ima->gpu_pass = requested_pass;
ima->gpu_layer = requested_layer;
ima->gpu_view = requested_view;
- ima->gpuflag &= ~GPU_FLAGS_TO_CHECK;
- ima->gpuflag |= requested_gpu_flags | IMA_GPU_REFRESH;
+ ima->gpuflag |= IMA_GPU_REFRESH;
}
#undef GPU_FLAGS_TO_CHECK
@@ -369,7 +403,14 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
if (current_view >= 2) {
current_view = 0;
}
- GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, current_view);
+ const bool limit_resolution = U.glreslimit != 0 &&
+ ((iuser && (iuser->flag & IMA_SHOW_MAX_RESOLUTION) == 0) ||
+ (iuser == NULL)) &&
+ ((ima->gpuflag & IMA_GPU_REUSE_MAX_RESOLUTION) == 0);
+ const eImageTextureResolution texture_resolution = limit_resolution ?
+ IMA_TEXTURE_RESOLUTION_LIMITED :
+ IMA_TEXTURE_RESOLUTION_FULL;
+ GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, current_view, texture_resolution);
if (*tex) {
return *tex;
}
@@ -392,22 +433,19 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
}
if (textarget == TEXTARGET_2D_ARRAY) {
- *tex = gpu_texture_create_tile_array(ima, ibuf_intern);
+ *tex = gpu_texture_create_tile_array(ima, ibuf_intern, texture_resolution);
}
else if (textarget == TEXTARGET_TILE_MAPPING) {
- *tex = gpu_texture_create_tile_mapping(ima, iuser ? iuser->multiview_eye : 0);
+ *tex = gpu_texture_create_tile_mapping(
+ ima, iuser ? iuser->multiview_eye : 0, texture_resolution);
}
else {
const bool use_high_bitdepth = (ima->flag & IMA_HIGH_BITDEPTH);
const bool store_premultiplied = BKE_image_has_gpu_texture_premultiplied_alpha(ima,
ibuf_intern);
- const bool limit_gl_texture_size = (ima->gpuflag & IMA_GPU_MAX_RESOLUTION) == 0;
- *tex = IMB_create_gpu_texture(ima->id.name + 2,
- ibuf_intern,
- use_high_bitdepth,
- store_premultiplied,
- limit_gl_texture_size);
+ *tex = IMB_create_gpu_texture(
+ ima->id.name + 2, ibuf_intern, use_high_bitdepth, store_premultiplied, limit_resolution);
if (*tex) {
GPU_texture_wrap_mode(*tex, true, false);
@@ -425,6 +463,20 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
}
}
+ switch (texture_resolution) {
+ case IMA_TEXTURE_RESOLUTION_LIMITED:
+ ima->gpuflag |= IMA_GPU_HAS_LIMITED_SCALE_TEXTURES;
+ break;
+
+ case IMA_TEXTURE_RESOLUTION_FULL:
+ image_update_reusable_textures(ima, textarget, current_view);
+ break;
+
+ case IMA_TEXTURE_RESOLUTION_LEN:
+ BLI_assert_unreachable();
+ break;
+ }
+
/* if `ibuf` was given, we don't own the `ibuf_intern` */
if (ibuf == NULL) {
BKE_image_release_ibuf(ima, ibuf_intern, NULL);
@@ -497,22 +549,39 @@ static void image_free_gpu(Image *ima, const bool immediate)
{
for (int eye = 0; eye < 2; eye++) {
for (int i = 0; i < TEXTARGET_COUNT; i++) {
- if (ima->gputexture[i][eye] != NULL) {
- if (immediate) {
- GPU_texture_free(ima->gputexture[i][eye]);
- }
- else {
- BLI_mutex_lock(&gpu_texture_queue_mutex);
- BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye]);
- BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ if (ima->gputexture[i][eye][resolution] != NULL) {
+ if (immediate) {
+ GPU_texture_free(ima->gputexture[i][eye][resolution]);
+ }
+ else {
+ BLI_mutex_lock(&gpu_texture_queue_mutex);
+ BLI_linklist_prepend(&gpu_texture_free_queue, ima->gputexture[i][eye][resolution]);
+ BLI_mutex_unlock(&gpu_texture_queue_mutex);
+ }
+
+ ima->gputexture[i][eye][resolution] = NULL;
}
+ }
+ }
+ }
+
+ ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE | IMA_GPU_HAS_LIMITED_SCALE_TEXTURES);
+}
- ima->gputexture[i][eye] = NULL;
+static void image_free_gpu_limited_scale(Image *ima)
+{
+ const eImageTextureResolution resolution = IMA_TEXTURE_RESOLUTION_LIMITED;
+ for (int eye = 0; eye < 2; eye++) {
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ if (ima->gputexture[i][eye][resolution] != NULL) {
+ GPU_texture_free(ima->gputexture[i][eye][resolution]);
+ ima->gputexture[i][eye][resolution] = NULL;
}
}
}
- ima->gpuflag &= ~IMA_GPU_MIPMAP_COMPLETE;
+ ima->gpuflag &= ~(IMA_GPU_MIPMAP_COMPLETE | IMA_GPU_HAS_LIMITED_SCALE_TEXTURES);
}
void BKE_image_free_gputextures(Image *ima)
@@ -689,12 +758,21 @@ static void gpu_texture_update_unscaled(GPUTexture *tex,
GPU_unpack_row_length_set(0);
}
-static void gpu_texture_update_from_ibuf(
- GPUTexture *tex, Image *ima, ImBuf *ibuf, ImageTile *tile, int x, int y, int w, int h)
+static void gpu_texture_update_from_ibuf(GPUTexture *tex,
+ Image *ima,
+ ImBuf *ibuf,
+ ImageTile *tile,
+ int x,
+ int y,
+ int w,
+ int h,
+ eImageTextureResolution texture_resolution)
{
+ const int resolution = texture_resolution == IMA_TEXTURE_RESOLUTION_LIMITED ? 1 : 0;
bool scaled;
if (tile != NULL) {
- int *tilesize = tile->runtime.tilearray_size;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ int *tilesize = tile_runtime->tilearray_size;
scaled = (ibuf->x != tilesize[0]) || (ibuf->y != tilesize[1]);
}
else {
@@ -758,9 +836,10 @@ static void gpu_texture_update_from_ibuf(
if (scaled) {
/* Slower update where we first have to scale the input pixels. */
if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int *tilesize = tile->runtime.tilearray_size;
- int tilelayer = tile->runtime.tilearray_layer;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ int *tileoffset = tile_runtime->tilearray_offset;
+ int *tilesize = tile_runtime->tilearray_size;
+ int tilelayer = tile_runtime->tilearray_layer;
gpu_texture_update_scaled(
tex, rect, rect_float, ibuf->x, ibuf->y, x, y, tilelayer, tileoffset, tilesize, w, h);
}
@@ -772,8 +851,9 @@ static void gpu_texture_update_from_ibuf(
else {
/* Fast update at same resolution. */
if (tile != NULL) {
- int *tileoffset = tile->runtime.tilearray_offset;
- int tilelayer = tile->runtime.tilearray_layer;
+ ImageTile_RuntimeTextureSlot *tile_runtime = &tile->runtime.slots[resolution];
+ int *tileoffset = tile_runtime->tilearray_offset;
+ int tilelayer = tile_runtime->tilearray_layer;
gpu_texture_update_unscaled(
tex, rect, rect_float, x, y, tilelayer, tileoffset, w, h, tex_stride, tex_offset);
}
@@ -804,16 +884,20 @@ static void gpu_texture_update_from_ibuf(
static void image_update_gputexture_ex(
Image *ima, ImageTile *tile, ImBuf *ibuf, int x, int y, int w, int h)
{
- GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
- /* Check if we need to update the main gputexture. */
- if (tex != NULL && tile == ima->tiles.first) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h);
- }
+ const int eye = 0;
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][eye][resolution];
+ eImageTextureResolution texture_resolution = resolution;
+ /* Check if we need to update the main gputexture. */
+ if (tex != NULL && tile == ima->tiles.first) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, NULL, x, y, w, h, texture_resolution);
+ }
- /* Check if we need to update the array gputexture. */
- tex = ima->gputexture[TEXTARGET_2D_ARRAY][0];
- if (tex != NULL) {
- gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h);
+ /* Check if we need to update the array gputexture. */
+ tex = ima->gputexture[TEXTARGET_2D_ARRAY][eye][resolution];
+ if (tex != NULL) {
+ gpu_texture_update_from_ibuf(tex, ima, ibuf, tile, x, y, w, h, texture_resolution);
+ }
}
}
@@ -917,12 +1001,14 @@ void BKE_image_paint_set_mipmap(Main *bmain, bool mipmap)
LISTBASE_FOREACH (Image *, ima, &bmain->images) {
if (BKE_image_has_opengl_texture(ima)) {
if (ima->gpuflag & IMA_GPU_MIPMAP_COMPLETE) {
- for (int eye = 0; eye < 2; eye++) {
- for (int a = 0; a < TEXTARGET_COUNT; a++) {
- if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
- GPUTexture *tex = ima->gputexture[a][eye];
- if (tex != NULL) {
- GPU_texture_mipmap_mode(tex, mipmap, true);
+ for (int a = 0; a < TEXTARGET_COUNT; a++) {
+ if (ELEM(a, TEXTARGET_2D, TEXTARGET_2D_ARRAY)) {
+ for (int eye = 0; eye < 2; eye++) {
+ for (int resolution = 0; resolution < IMA_TEXTURE_RESOLUTION_LEN; resolution++) {
+ GPUTexture *tex = ima->gputexture[a][eye][resolution];
+ if (tex != NULL) {
+ GPU_texture_mipmap_mode(tex, mipmap, true);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 394245b3a2c..d0d1db9b4f8 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -5754,3 +5754,9 @@ void BKE_object_replace_data_on_shallow_copy(Object *ob, ID *new_data)
}
ob->id.py_instance = NULL;
}
+
+bool BKE_object_supports_material_slots(struct Object *ob)
+{
+ return ELEM(
+ ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL, OB_HAIR, OB_POINTCLOUD, OB_VOLUME);
+}
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index b217850e119..cb7a8ad592a 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -829,33 +829,6 @@ static void do_versions_strip_cache_settings_recursive(const ListBase *seqbase)
}
}
-static void version_node_socket_name(bNodeTree *ntree,
- const int node_type,
- const char *old_name,
- const char *new_name)
-{
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == node_type) {
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
- if (STREQ(socket->name, old_name)) {
- strcpy(socket->name, new_name);
- }
- if (STREQ(socket->identifier, old_name)) {
- strcpy(socket->identifier, new_name);
- }
- }
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
- if (STREQ(socket->name, old_name)) {
- strcpy(socket->name, new_name);
- }
- if (STREQ(socket->identifier, old_name)) {
- strcpy(socket->identifier, new_name);
- }
- }
- }
- }
-}
-
static void version_node_join_geometry_for_multi_input_socket(bNodeTree *ntree)
{
LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 13577164f20..f050de6e6e9 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -526,33 +526,6 @@ static void version_switch_node_input_prefix(Main *bmain)
FOREACH_NODETREE_END;
}
-static void version_node_socket_name(bNodeTree *ntree,
- const int node_type,
- const char *old_name,
- const char *new_name)
-{
- LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
- if (node->type == node_type) {
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
- if (STREQ(socket->name, old_name)) {
- strcpy(socket->name, new_name);
- }
- if (STREQ(socket->identifier, old_name)) {
- strcpy(socket->identifier, new_name);
- }
- }
- LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
- if (STREQ(socket->name, old_name)) {
- strcpy(socket->name, new_name);
- }
- if (STREQ(socket->identifier, old_name)) {
- strcpy(socket->identifier, new_name);
- }
- }
- }
- }
-}
-
static bool replace_bbone_len_scale_rnapath(char **p_old_path, int *p_index)
{
char *old_path = *p_old_path;
diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc
index 208c02b60d1..3f13d1ec12e 100644
--- a/source/blender/blenloader/intern/versioning_common.cc
+++ b/source/blender/blenloader/intern/versioning_common.cc
@@ -22,6 +22,7 @@
#include <cstring>
+#include "DNA_node_types.h"
#include "DNA_screen_types.h"
#include "BLI_listbase.h"
@@ -85,3 +86,30 @@ ID *do_versions_rename_id(Main *bmain,
}
return id;
}
+
+void version_node_socket_name(bNodeTree *ntree,
+ const int node_type,
+ const char *old_name,
+ const char *new_name)
+{
+ LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
+ if (node->type == node_type) {
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
+ if (STREQ(socket->name, old_name)) {
+ BLI_strncpy(socket->name, new_name, sizeof(socket->name));
+ }
+ if (STREQ(socket->identifier, old_name)) {
+ BLI_strncpy(socket->identifier, new_name, sizeof(socket->name));
+ }
+ }
+ LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
+ if (STREQ(socket->name, old_name)) {
+ BLI_strncpy(socket->name, new_name, sizeof(socket->name));
+ }
+ if (STREQ(socket->identifier, old_name)) {
+ BLI_strncpy(socket->identifier, new_name, sizeof(socket->name));
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h
index 47e0b74a3e4..c1fe2b591cd 100644
--- a/source/blender/blenloader/intern/versioning_common.h
+++ b/source/blender/blenloader/intern/versioning_common.h
@@ -23,6 +23,7 @@
struct ARegion;
struct ListBase;
struct Main;
+struct bNodeTree;
#ifdef __cplusplus
extern "C" {
@@ -38,6 +39,11 @@ ID *do_versions_rename_id(Main *bmain,
const char *name_src,
const char *name_dst);
+void version_node_socket_name(struct bNodeTree *ntree,
+ const int node_type,
+ const char *old_name,
+ const char *new_name);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 8a35ab2aeb9..a125a13eaf9 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -110,6 +110,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
bool use_obedit_skip,
bool draw_surface,
bool use_nearest,
+ const bool do_material_sub_selection,
const struct rcti *rect,
DRW_SelectPassFn select_pass_fn,
void *select_pass_user_data,
diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c
index c120df7e897..87f5c6f5857 100644
--- a/source/blender/draw/engines/basic/basic_engine.c
+++ b/source/blender/draw/engines/basic/basic_engine.c
@@ -25,9 +25,12 @@
#include "DRW_render.h"
+#include "BKE_object.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
+#include "BLI_alloca.h"
+
#include "DNA_particle_types.h"
#include "GPU_shader.h"
@@ -80,6 +83,7 @@ typedef struct BASIC_PrivateData {
DRWShadingGroup *depth_shgrp[2];
DRWShadingGroup *depth_shgrp_cull[2];
DRWShadingGroup *depth_hair_shgrp[2];
+ bool use_material_slot_selection;
} BASIC_PrivateData; /* Transient data */
/* Functions */
@@ -131,6 +135,8 @@ static void basic_cache_init(void *vedata)
stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
}
+ stl->g_data->use_material_slot_selection = DRW_state_is_material_select();
+
/* Twice for normal and in front objects. */
for (int i = 0; i < 2; i++) {
DRWState clip_state = (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? DRW_STATE_CLIP_PLANES : 0;
@@ -155,6 +161,38 @@ static void basic_cache_init(void *vedata)
}
}
+/* TODO(fclem): DRW_cache_object_surface_material_get needs a refactor to allow passing NULL
+ * instead of gpumat_array. Avoiding all this boilerplate code. */
+static struct GPUBatch **basic_object_surface_material_get(Object *ob)
+{
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
+ memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
+
+ return DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
+}
+
+static void basic_cache_populate_particles(void *vedata, Object *ob)
+{
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
+ BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
+ for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
+ if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
+ continue;
+ }
+ ParticleSettings *part = psys->part;
+ const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
+ if (draw_as == PART_DRAW_PATH) {
+ struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
+ if (stl->g_data->use_material_slot_selection) {
+ const short material_slot = part->omat;
+ DRW_select_load_id(ob->runtime.select_id | (material_slot << 16));
+ }
+ DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
+ }
+ }
+}
+
static void basic_cache_populate(void *vedata, Object *ob)
{
BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
@@ -165,24 +203,13 @@ static void basic_cache_populate(void *vedata, Object *ob)
return;
}
- bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
-
const DRWContextState *draw_ctx = DRW_context_state_get();
if (ob != draw_ctx->object_edit) {
- for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
- if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) {
- continue;
- }
- ParticleSettings *part = psys->part;
- const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
- if (draw_as == PART_DRAW_PATH) {
- struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
- DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
- }
- }
+ basic_cache_populate_particles(vedata, ob);
}
/* Make flat object selectable in ortho view if wireframe is enabled. */
+ const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
(draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
int flat_axis = 0;
@@ -211,9 +238,25 @@ static void basic_cache_populate(void *vedata, Object *ob)
DRW_shgroup_call_sculpt(shgrp, ob, false, false);
}
else {
- struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
- if (geom) {
- DRW_shgroup_call(shgrp, geom, ob);
+ if (stl->g_data->use_material_slot_selection && BKE_object_supports_material_slots(ob)) {
+ struct GPUBatch **geoms = basic_object_surface_material_get(ob);
+ if (geoms) {
+ const int materials_len = DRW_cache_object_material_count_get(ob);
+ for (int i = 0; i < materials_len; i++) {
+ if (geoms[i] == NULL) {
+ continue;
+ }
+ const short material_slot_select_id = i + 1;
+ DRW_select_load_id(ob->runtime.select_id | (material_slot_select_id << 16));
+ DRW_shgroup_call(shgrp, geoms[i], ob);
+ }
+ }
+ }
+ else {
+ struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
+ if (geom) {
+ DRW_shgroup_call(shgrp, geom, ob);
+ }
}
}
}
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 6639a100af9..660a4adaf51 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -731,6 +731,7 @@ void DRW_select_load_id(uint id);
/* Draw State */
bool DRW_state_is_fbo(void);
bool DRW_state_is_select(void);
+bool DRW_state_is_material_select(void);
bool DRW_state_is_depth(void);
bool DRW_state_is_image_render(void);
bool DRW_state_is_scene_render(void);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 9590a4aa7ee..aca645acc09 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -2232,6 +2232,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
bool use_obedit_skip,
bool draw_surface,
bool UNUSED(use_nearest),
+ const bool do_material_sub_selection,
const rcti *rect,
DRW_SelectPassFn select_pass_fn,
void *select_pass_user_data,
@@ -2299,6 +2300,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
DST.viewport = viewport;
DST.options.is_select = true;
+ DST.options.is_material_select = do_material_sub_selection;
drw_task_graph_init();
/* Get list of enabled engines */
if (use_obedit) {
@@ -2776,6 +2778,11 @@ bool DRW_state_is_select(void)
return DST.options.is_select;
}
+bool DRW_state_is_material_select(void)
+{
+ return DST.options.is_material_select;
+}
+
bool DRW_state_is_depth(void)
{
return DST.options.is_depth;
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 1747ca752c7..c09126c98ef 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -553,6 +553,7 @@ typedef struct DRWManager {
struct {
uint is_select : 1;
+ uint is_material_select : 1;
uint is_depth : 1;
uint is_image_render : 1;
uint is_scene_render : 1;
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 2c958d282f9..cf8dcbd7995 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -566,6 +566,13 @@ eV3DSelectObjectFilter ED_view3d_select_filter_from_mode(const struct Scene *sce
void view3d_opengl_select_cache_begin(void);
void view3d_opengl_select_cache_end(void);
+int view3d_opengl_select_ex(struct ViewContext *vc,
+ unsigned int *buffer,
+ unsigned int bufsize,
+ const struct rcti *input,
+ eV3DSelectMode select_mode,
+ eV3DSelectObjectFilter select_filter,
+ const bool do_material_slot_selection);
int view3d_opengl_select(struct ViewContext *vc,
unsigned int *buffer,
unsigned int bufsize,
@@ -638,6 +645,9 @@ void ED_view3d_draw_setup_view(const struct wmWindowManager *wm,
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
struct Object *ED_view3d_give_object_under_cursor(struct bContext *C, const int mval[2]);
+struct Object *ED_view3d_give_material_slot_under_cursor(struct bContext *C,
+ const int mval[2],
+ int *r_material_slot);
bool ED_view3d_is_object_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *area, struct ARegion *region, bool do_clip);
void ED_view3d_update_viewmat(struct Depsgraph *depsgraph,
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index ec72ff11683..75269dffec8 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2729,25 +2729,26 @@ char *ED_object_ot_drop_named_material_tooltip(bContext *C,
PointerRNA *properties,
const wmEvent *event)
{
- Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
+ int mat_slot = 0;
+ Object *ob = ED_view3d_give_material_slot_under_cursor(C, event->mval, &mat_slot);
if (ob == NULL) {
return BLI_strdup("");
}
+ mat_slot = max_ii(mat_slot, 1);
char name[MAX_ID_NAME - 2];
RNA_string_get(properties, "name", name);
- int active_mat_slot = max_ii(ob->actcol, 1);
- Material *prev_mat = BKE_object_material_get(ob, active_mat_slot);
+ Material *prev_mat = BKE_object_material_get(ob, mat_slot);
char *result;
if (prev_mat) {
const char *tooltip = TIP_("Drop %s on %s (slot %d, replacing %s)");
- result = BLI_sprintfN(tooltip, name, ob->id.name + 2, active_mat_slot, prev_mat->id.name + 2);
+ result = BLI_sprintfN(tooltip, name, ob->id.name + 2, mat_slot, prev_mat->id.name + 2);
}
else {
const char *tooltip = TIP_("Drop %s on %s (slot %d)");
- result = BLI_sprintfN(tooltip, name, ob->id.name + 2, active_mat_slot);
+ result = BLI_sprintfN(tooltip, name, ob->id.name + 2, mat_slot);
}
return result;
}
@@ -2755,7 +2756,10 @@ char *ED_object_ot_drop_named_material_tooltip(bContext *C,
static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
- Object *ob = ED_view3d_give_object_under_cursor(C, event->mval);
+ int mat_slot = 0;
+ Object *ob = ED_view3d_give_material_slot_under_cursor(C, event->mval, &mat_slot);
+ mat_slot = max_ii(mat_slot, 1);
+
Material *ma;
char name[MAX_ID_NAME - 2];
@@ -2765,9 +2769,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
}
- const short active_mat_slot = ob->actcol;
-
- BKE_object_material_assign(CTX_data_main(C), ob, ma, active_mat_slot, BKE_MAT_ASSIGN_USERPREF);
+ BKE_object_material_assign(CTX_data_main(C), ob, ma, mat_slot, BKE_MAT_ASSIGN_USERPREF);
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c
index 10629caa8b0..f04336cab84 100644
--- a/source/blender/editors/space_graph/graph_slider_ops.c
+++ b/source/blender/editors/space_graph/graph_slider_ops.c
@@ -41,6 +41,7 @@
#include "ED_keyframes_edit.h"
#include "ED_numinput.h"
#include "ED_screen.h"
+#include "ED_util.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -94,6 +95,8 @@ typedef struct tDecimateGraphOp {
/** The original bezt curve data (used for restoring fcurves). */
ListBase bezt_arr_list;
+ struct tSlider *slider;
+
NumInput num;
} tDecimateGraphOp;
@@ -161,6 +164,8 @@ static void decimate_exit(bContext *C, wmOperator *op)
ScrArea *area = dgo->area;
LinkData *link;
+ ED_slider_destroy(C, dgo->slider);
+
for (link = dgo->bezt_arr_list.first; link != NULL; link = link->next) {
tBeztCopyData *copy = link->data;
MEM_freeN(copy->bezt);
@@ -178,11 +183,14 @@ static void decimate_exit(bContext *C, wmOperator *op)
op->customdata = NULL;
}
-/* Draw a percentage indicator in header. */
-static void decimate_draw_status_header(wmOperator *op, tDecimateGraphOp *dgo)
+/* Draw a percentage indicator in workspace footer. */
+static void decimate_draw_status(bContext *C, tDecimateGraphOp *dgo)
{
char status_str[UI_MAX_DRAW_STR];
char mode_str[32];
+ char slider_string[UI_MAX_DRAW_STR];
+
+ ED_slider_status_string_get(dgo->slider, slider_string, UI_MAX_DRAW_STR);
strcpy(mode_str, TIP_("Decimate Keyframes"));
@@ -194,23 +202,10 @@ static void decimate_draw_status_header(wmOperator *op, tDecimateGraphOp *dgo)
BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs);
}
else {
- float percentage = RNA_property_float_get(op->ptr, dgo->percentage_prop);
- BLI_snprintf(
- status_str, sizeof(status_str), "%s: %d %%", mode_str, (int)(percentage * 100.0f));
+ BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string);
}
- ED_area_status_text(dgo->area, status_str);
-}
-
-/* Calculate percentage based on position of mouse (we only use x-axis for now.
- * Since this is more convenient for users to do), and store new percentage value.
- */
-static void decimate_mouse_update_percentage(tDecimateGraphOp *dgo,
- wmOperator *op,
- const wmEvent *event)
-{
- float percentage = (event->x - dgo->region->winrct.xmin) / ((float)dgo->region->winx);
- RNA_property_float_set(op->ptr, dgo->percentage_prop, percentage);
+ ED_workspace_status_text(C, status_str);
}
static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -234,10 +229,11 @@ static int graphkeys_decimate_invoke(bContext *C, wmOperator *op, const wmEvent
dgo->area = CTX_wm_area(C);
dgo->region = CTX_wm_region(C);
- /* Initialize percentage so that it will have the correct value before the first mouse move. */
- decimate_mouse_update_percentage(dgo, op, event);
+ dgo->slider = ED_slider_create(C);
+ ED_slider_init(dgo->slider, event);
+ ED_slider_allow_overshoot_set(dgo->slider, false);
- decimate_draw_status_header(op, dgo);
+ decimate_draw_status(C, dgo);
/* Construct a list with the original bezt arrays so we can restore them during modal operation.
*/
@@ -300,13 +296,14 @@ static void graphkeys_decimate_modal_update(bContext *C, wmOperator *op)
* (e.g. pressing a key or moving the mouse). */
tDecimateGraphOp *dgo = op->customdata;
- decimate_draw_status_header(op, dgo);
+ decimate_draw_status(C, dgo);
/* Reset keyframe data (so we get back to the original state). */
decimate_reset_bezts(dgo);
/* Apply... */
- float remove_ratio = RNA_property_float_get(op->ptr, dgo->percentage_prop);
+ float remove_ratio = ED_slider_factor_get(dgo->slider);
+ RNA_property_float_set(op->ptr, dgo->percentage_prop, remove_ratio);
/* We don't want to limit the decimation to a certain error margin. */
const float error_sq_max = FLT_MAX;
decimate_graph_keys(&dgo->ac, remove_ratio, error_sq_max);
@@ -323,6 +320,8 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
const bool has_numinput = hasNumInput(&dgo->num);
+ ED_slider_modal(dgo->slider, event);
+
switch (event->type) {
case LEFTMOUSE: /* Confirm */
case EVT_RETKEY:
@@ -353,9 +352,6 @@ static int graphkeys_decimate_modal(bContext *C, wmOperator *op, const wmEvent *
case MOUSEMOVE: /* Calculate new position. */
{
if (has_numinput == false) {
- /* Update percentage based on position of mouse. */
- decimate_mouse_update_percentage(dgo, op, event);
-
/* Update pose to reflect the new values. */
graphkeys_decimate_modal_update(C, op);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 4c938a412d2..80d3e2cbdaa 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -504,238 +504,245 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot)
/** \name Select Operator
* \{ */
-static int sequencer_select_exec(bContext *C, wmOperator *op)
+static void sequencer_select_set_active(Scene *scene, Sequence *seq)
{
- View2D *v2d = UI_view2d_fromcontext(C);
- Scene *scene = CTX_data_scene(C);
Editing *ed = SEQ_editing_get(scene);
- const bool extend = RNA_boolean_get(op->ptr, "extend");
- const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
- const bool linked_handle = RNA_boolean_get(op->ptr, "linked_handle");
- const bool linked_time = RNA_boolean_get(op->ptr, "linked_time");
- bool side_of_frame = RNA_boolean_get(op->ptr, "side_of_frame");
- bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
- int mval[2];
- int ret_value = OPERATOR_CANCELLED;
- mval[0] = RNA_int_get(op->ptr, "mouse_x");
- mval[1] = RNA_int_get(op->ptr, "mouse_y");
-
- Sequence *seq, *neighbor, *act_orig;
- int hand, sel_side;
+ SEQ_select_active_set(scene, seq);
- if (ed == NULL) {
- return OPERATOR_CANCELLED;
+ if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) {
+ if (seq->strip) {
+ BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR);
+ }
}
-
- if (extend) {
- wait_to_deselect_others = false;
+ else if (seq->type == SEQ_TYPE_SOUND_RAM) {
+ if (seq->strip) {
+ BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR);
+ }
}
+ recurs_sel_seq(seq);
+}
- seq = find_nearest_seq(scene, v2d, &hand, mval);
+static void sequencer_select_do_updates(bContext *C, Scene *scene)
+{
+ ED_outliner_select_sync_from_sequence_tag(C);
+ WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
+}
- /* XXX: not nice, Ctrl+RMB needs to do side_of_frame only when not over a strip. */
- if (seq && linked_time) {
- side_of_frame = false;
- }
+static void sequencer_select_side_of_frame(const bContext *C,
+ const View2D *v2d,
+ const int mval[2],
+ Scene *scene)
+{
+ Editing *ed = SEQ_editing_get(scene);
- /* Select left, right or overlapping the current frame. */
- if (side_of_frame) {
- /* Use different logic for this. */
- if (extend == false) {
- ED_sequencer_deselect_all(scene);
+ const float x = UI_view2d_region_to_view_x(v2d, mval[0]);
+ LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
+ if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) ||
+ ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) {
+ /* Select left or right. */
+ seq_iter->flag |= SELECT;
+ recurs_sel_seq(seq_iter);
}
+ }
- const float x = UI_view2d_region_to_view_x(v2d, mval[0]);
+ {
+ SpaceSeq *sseq = CTX_wm_space_seq(C);
+ if (sseq && sseq->flag & SEQ_MARKER_TRANS) {
+ TimeMarker *tmarker;
- LISTBASE_FOREACH (Sequence *, seq_iter, SEQ_active_seqbase_get(ed)) {
- if (((x < CFRA) && (seq_iter->enddisp <= CFRA)) ||
- ((x >= CFRA) && (seq_iter->startdisp >= CFRA))) {
- /* Select left or right. */
- seq_iter->flag |= SELECT;
- recurs_sel_seq(seq_iter);
+ for (tmarker = scene->markers.first; tmarker; tmarker = tmarker->next) {
+ if (((x < CFRA) && (tmarker->frame <= CFRA)) ||
+ ((x >= CFRA) && (tmarker->frame >= CFRA))) {
+ tmarker->flag |= SELECT;
+ }
+ else {
+ tmarker->flag &= ~SELECT;
+ }
}
}
+ }
+}
- {
- SpaceSeq *sseq = CTX_wm_space_seq(C);
- if (sseq && sseq->flag & SEQ_MARKER_TRANS) {
- TimeMarker *tmarker;
+static void sequencer_select_linked_handle(const bContext *C,
+ Sequence *seq,
+ const int handle_clicked)
+{
+ Scene *scene = CTX_data_scene(C);
+ Editing *ed = SEQ_editing_get(scene);
+ if (!ELEM(handle_clicked, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) {
+ /* First click selects the strip and its adjacent handles (if valid).
+ * Second click selects the strip,
+ * both of its handles and its adjacent handles (if valid). */
+ const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT);
+ seq->flag &= ~SEQ_ALLSEL;
+ seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT;
+ select_surrounding_handles(scene, seq);
+ }
+ else {
+ /* Always select the strip under the cursor. */
+ seq->flag |= SELECT;
- for (tmarker = scene->markers.first; tmarker; tmarker = tmarker->next) {
- if (((x < CFRA) && (tmarker->frame <= CFRA)) ||
- ((x >= CFRA) && (tmarker->frame >= CFRA))) {
- tmarker->flag |= SELECT;
+ /* First click selects adjacent handles on that side.
+ * Second click selects all strips in that direction.
+ * If there are no adjacent strips, it just selects all in that direction.
+ */
+ int sel_side = handle_clicked;
+ Sequence *neighbor = find_neighboring_sequence(scene, seq, sel_side, -1);
+ if (neighbor) {
+ switch (sel_side) {
+ case SEQ_SIDE_LEFT:
+ if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) {
+ seq->flag |= SELECT;
+ select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp);
}
else {
- tmarker->flag &= ~SELECT;
+ seq->flag |= SELECT;
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_RIGHTSEL;
+ seq->flag |= SEQ_LEFTSEL;
}
- }
+ break;
+ case SEQ_SIDE_RIGHT:
+ if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) {
+ seq->flag |= SELECT;
+ select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp);
+ }
+ else {
+ seq->flag |= SELECT;
+ neighbor->flag |= SELECT;
+ recurs_sel_seq(neighbor);
+ neighbor->flag |= SEQ_LEFTSEL;
+ seq->flag |= SEQ_RIGHTSEL;
+ }
+ break;
}
}
+ else {
- ret_value = OPERATOR_FINISHED;
+ select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp);
+ }
}
- else {
- act_orig = ed->act_seq;
-
- if (seq) {
- /* Are we trying to select a handle that's already selected? */
- const bool handle_selected = ((hand == SEQ_SIDE_LEFT) && (seq->flag & SEQ_LEFTSEL)) ||
- ((hand == SEQ_SIDE_RIGHT) && (seq->flag & SEQ_RIGHTSEL));
-
- if (wait_to_deselect_others && (seq->flag & SELECT) &&
- (hand == SEQ_SIDE_NONE || handle_selected)) {
- ret_value = OPERATOR_RUNNING_MODAL;
- }
- else if (!extend && !linked_handle) {
- ED_sequencer_deselect_all(scene);
- ret_value = OPERATOR_FINISHED;
- }
- else {
- ret_value = OPERATOR_FINISHED;
- }
-
- SEQ_select_active_set(scene, seq);
+}
- if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) {
- if (seq->strip) {
- BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR);
- }
- }
- else if (seq->type == SEQ_TYPE_SOUND_RAM) {
- if (seq->strip) {
- BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR);
- }
- }
+static bool element_already_selected(const Sequence *seq, const int handle_clicked)
+{
+ const bool handle_already_selected = ((handle_clicked == SEQ_SIDE_LEFT) &&
+ (seq->flag & SEQ_LEFTSEL)) ||
+ ((handle_clicked == SEQ_SIDE_RIGHT) &&
+ (seq->flag & SEQ_RIGHTSEL));
+ return ((seq->flag & SELECT) && handle_clicked == SEQ_SIDE_NONE) || handle_already_selected;
+}
- /* On Alt selection, select the strip and bordering handles. */
- if (linked_handle) {
- if (!ELEM(hand, SEQ_SIDE_LEFT, SEQ_SIDE_RIGHT)) {
- /* First click selects the strip and its adjacent handles (if valid).
- * Second click selects the strip,
- * both of its handles and its adjacent handles (if valid). */
- const bool is_striponly_selected = ((seq->flag & SEQ_ALLSEL) == SELECT);
+static void sequencer_select_strip_impl(const Editing *ed,
+ Sequence *seq,
+ const int handle_clicked,
+ const bool extend)
+{
+ /* Deselect strip. */
+ if (extend && (seq->flag & SELECT) && ed->act_seq == seq) {
+ switch (handle_clicked) {
+ case SEQ_SIDE_NONE:
+ seq->flag &= ~SEQ_ALLSEL;
+ break;
+ case SEQ_SIDE_LEFT:
+ seq->flag ^= SEQ_LEFTSEL;
+ break;
+ case SEQ_SIDE_RIGHT:
+ seq->flag ^= SEQ_RIGHTSEL;
+ break;
+ }
+ }
+ else { /* Select strip. */
+ seq->flag |= SELECT;
+ if (handle_clicked == SEQ_SIDE_LEFT) {
+ seq->flag |= SEQ_LEFTSEL;
+ }
+ if (handle_clicked == SEQ_SIDE_RIGHT) {
+ seq->flag |= SEQ_RIGHTSEL;
+ }
+ }
+}
- if (!extend) {
- ED_sequencer_deselect_all(scene);
- }
- seq->flag &= ~SEQ_ALLSEL;
- seq->flag |= is_striponly_selected ? SEQ_ALLSEL : SELECT;
- select_surrounding_handles(scene, seq);
- }
- else {
- /* Always select the strip under the cursor. */
- seq->flag |= SELECT;
+static int sequencer_select_exec(bContext *C, wmOperator *op)
+{
+ View2D *v2d = UI_view2d_fromcontext(C);
+ Scene *scene = CTX_data_scene(C);
+ Editing *ed = SEQ_editing_get(scene);
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
- /* First click selects adjacent handles on that side.
- * Second click selects all strips in that direction.
- * If there are no adjacent strips, it just selects all in that direction.
- */
- sel_side = hand;
- neighbor = find_neighboring_sequence(scene, seq, sel_side, -1);
- if (neighbor) {
- switch (sel_side) {
- case SEQ_SIDE_LEFT:
- if ((seq->flag & SEQ_LEFTSEL) && (neighbor->flag & SEQ_RIGHTSEL)) {
- if (extend == 0) {
- ED_sequencer_deselect_all(scene);
- }
- seq->flag |= SELECT;
-
- select_active_side(ed->seqbasep, SEQ_SIDE_LEFT, seq->machine, seq->startdisp);
- }
- else {
- if (extend == 0) {
- ED_sequencer_deselect_all(scene);
- }
- seq->flag |= SELECT;
-
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- neighbor->flag |= SEQ_RIGHTSEL;
- seq->flag |= SEQ_LEFTSEL;
- }
- break;
- case SEQ_SIDE_RIGHT:
- if ((seq->flag & SEQ_RIGHTSEL) && (neighbor->flag & SEQ_LEFTSEL)) {
- if (extend == 0) {
- ED_sequencer_deselect_all(scene);
- }
- seq->flag |= SELECT;
-
- select_active_side(ed->seqbasep, SEQ_SIDE_RIGHT, seq->machine, seq->startdisp);
- }
- else {
- if (extend == 0) {
- ED_sequencer_deselect_all(scene);
- }
- seq->flag |= SELECT;
-
- neighbor->flag |= SELECT;
- recurs_sel_seq(neighbor);
- neighbor->flag |= SEQ_LEFTSEL;
- seq->flag |= SEQ_RIGHTSEL;
- }
- break;
- }
- }
- else {
- if (extend == 0) {
- ED_sequencer_deselect_all(scene);
- }
- select_active_side(ed->seqbasep, sel_side, seq->machine, seq->startdisp);
- }
- }
+ if (ed == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- ret_value = OPERATOR_FINISHED;
- }
- else {
- if (extend && (seq->flag & SELECT) && ed->act_seq == act_orig) {
- switch (hand) {
- case SEQ_SIDE_NONE:
- if (linked_handle == 0) {
- seq->flag &= ~SEQ_ALLSEL;
- }
- break;
- case SEQ_SIDE_LEFT:
- seq->flag ^= SEQ_LEFTSEL;
- break;
- case SEQ_SIDE_RIGHT:
- seq->flag ^= SEQ_RIGHTSEL;
- break;
- }
- ret_value = OPERATOR_FINISHED;
- }
- else {
- seq->flag |= SELECT;
- if (hand == SEQ_SIDE_LEFT) {
- seq->flag |= SEQ_LEFTSEL;
- }
- if (hand == SEQ_SIDE_RIGHT) {
- seq->flag |= SEQ_RIGHTSEL;
- }
- }
- }
+ int mval[2];
+ mval[0] = RNA_int_get(op->ptr, "mouse_x");
+ mval[1] = RNA_int_get(op->ptr, "mouse_y");
- recurs_sel_seq(seq);
+ int handle_clicked;
+ Sequence *seq = find_nearest_seq(scene, v2d, &handle_clicked, mval);
- if (linked_time) {
- select_linked_time(ed->seqbasep, seq);
- }
+ /* NOTE: `side_of_frame` and `linked_time` functionality is designed to be shared on one keymap,
+ * therefore both properties can be true at the same time. */
+ if (seq && RNA_boolean_get(op->ptr, "linked_time")) {
+ if (!extend) {
+ ED_sequencer_deselect_all(scene);
+ }
+ sequencer_select_strip_impl(ed, seq, handle_clicked, extend);
+ select_linked_time(ed->seqbasep, seq);
+ sequencer_select_do_updates(C, scene);
+ sequencer_select_set_active(scene, seq);
+ return OPERATOR_FINISHED;
+ }
- BLI_assert((ret_value & OPERATOR_CANCELLED) == 0);
+ /* Select left, right or overlapping the current frame. */
+ if (RNA_boolean_get(op->ptr, "side_of_frame")) {
+ if (!extend) {
+ ED_sequencer_deselect_all(scene);
}
- else if (deselect_all) {
+ sequencer_select_side_of_frame(C, v2d, mval, scene);
+ sequencer_select_do_updates(C, scene);
+ return OPERATOR_FINISHED;
+ }
+
+ /* On Alt selection, select the strip and bordering handles. */
+ if (seq && RNA_boolean_get(op->ptr, "linked_handle")) {
+ if (!extend) {
ED_sequencer_deselect_all(scene);
- ret_value = OPERATOR_FINISHED;
}
+ sequencer_select_linked_handle(C, seq, handle_clicked);
+ sequencer_select_do_updates(C, scene);
+ sequencer_select_set_active(scene, seq);
+ return OPERATOR_FINISHED;
}
- ED_outliner_select_sync_from_sequence_tag(C);
+ const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
- WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
+ /* Clicking on already selected element falls on modal operation.
+ * All strips are deselected on mouse button release unless extend mode is used. */
+ if (seq && element_already_selected(seq, handle_clicked) && wait_to_deselect_others && !extend) {
+ return OPERATOR_RUNNING_MODAL;
+ }
+
+ int ret_value = OPERATOR_CANCELLED;
+ if (!extend) {
+ ED_sequencer_deselect_all(scene);
+ ret_value = OPERATOR_FINISHED;
+ }
+
+ /* Nothing to select, but strips could be deselected. */
+ if (!seq) {
+ sequencer_select_do_updates(C, scene);
+ return ret_value;
+ }
+
+ /* Do actual selection. */
+ sequencer_select_strip_impl(ed, seq, handle_clicked, extend);
+ ret_value = OPERATOR_FINISHED;
+ sequencer_select_do_updates(C, scene);
+ sequencer_select_set_active(scene, seq);
return ret_value;
}
@@ -764,13 +771,6 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
prop = RNA_def_boolean(ot->srna,
- "deselect_all",
- false,
- "Deselect On Nothing",
- "Deselect all when nothing under the cursor");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
-
- prop = RNA_def_boolean(ot->srna,
"linked_handle",
false,
"Linked Handle",
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index e3f97dd1c63..ff98762e373 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1953,7 +1953,8 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc,
const int mval[2],
eV3DSelectObjectFilter select_filter,
bool do_nearest,
- bool do_nearest_xray_if_supported)
+ bool do_nearest_xray_if_supported,
+ const bool do_material_slot_selection)
{
rcti rect;
int hits15, hits9 = 0, hits5 = 0;
@@ -1972,7 +1973,8 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc,
view3d_opengl_select_cache_begin();
BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter);
+ hits15 = view3d_opengl_select_ex(
+ vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter, do_material_slot_selection);
if (hits15 == 1) {
hits = selectbuffer_ret_hits_15(buffer, hits15);
goto finally;
@@ -2071,7 +2073,8 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc,
do_nearest = do_nearest && !enumerate;
- int hits = mixed_bones_object_selectbuffer(vc, buffer, mval, select_filter, do_nearest, true);
+ int hits = mixed_bones_object_selectbuffer(
+ vc, buffer, mval, select_filter, do_nearest, true, false);
return hits;
}
@@ -2088,12 +2091,14 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
int hits,
Base *startbase,
bool has_bones,
- bool do_nearest)
+ bool do_nearest,
+ int *r_sub_selection)
{
ViewLayer *view_layer = vc->view_layer;
View3D *v3d = vc->v3d;
Base *base, *basact = NULL;
int a;
+ int sub_selection_id = 0;
if (do_nearest) {
uint min = 0xFFFFFFFF;
@@ -2105,6 +2110,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
if (min > buffer[4 * a + 1] && (buffer[4 * a + 3] & 0xFFFF0000)) {
min = buffer[4 * a + 1];
selcol = buffer[4 * a + 3] & 0xFFFF;
+ sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16;
}
}
}
@@ -2118,6 +2124,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) {
min = buffer[4 * a + 1];
selcol = buffer[4 * a + 3] & 0xFFFF;
+ sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16;
}
}
}
@@ -2184,11 +2191,16 @@ static Base *mouse_select_eval_buffer(ViewContext *vc,
}
}
+ if (basact && r_sub_selection) {
+ *r_sub_selection = sub_selection_id;
+ }
+
return basact;
}
-/* mval comes from event->mval, only use within region handlers */
-Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
+static Base *ed_view3d_give_base_under_cursor_ex(bContext *C,
+ const int mval[2],
+ int *r_material_slot)
{
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
ViewContext vc;
@@ -2202,18 +2214,30 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
ED_view3d_viewcontext_init(C, &vc, depsgraph);
const bool do_nearest = !XRAY_ACTIVE(vc.v3d);
+ const bool do_material_slot_selection = r_material_slot != NULL;
const int hits = mixed_bones_object_selectbuffer(
- &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest, false);
+ &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest, false, do_material_slot_selection);
if (hits > 0) {
- const bool has_bones = selectbuffer_has_bones(buffer, hits);
- basact = mouse_select_eval_buffer(
- &vc, buffer, hits, vc.view_layer->object_bases.first, has_bones, do_nearest);
+ const bool has_bones = (r_material_slot == NULL) && selectbuffer_has_bones(buffer, hits);
+ basact = mouse_select_eval_buffer(&vc,
+ buffer,
+ hits,
+ vc.view_layer->object_bases.first,
+ has_bones,
+ do_nearest,
+ r_material_slot);
}
return basact;
}
+/* mval comes from event->mval, only use within region handlers */
+Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
+{
+ return ed_view3d_give_base_under_cursor_ex(C, mval, NULL);
+}
+
Object *ED_view3d_give_object_under_cursor(bContext *C, const int mval[2])
{
Base *base = ED_view3d_give_base_under_cursor(C, mval);
@@ -2223,6 +2247,17 @@ Object *ED_view3d_give_object_under_cursor(bContext *C, const int mval[2])
return NULL;
}
+struct Object *ED_view3d_give_material_slot_under_cursor(struct bContext *C,
+ const int mval[2],
+ int *r_material_slot)
+{
+ Base *base = ed_view3d_give_base_under_cursor_ex(C, mval, r_material_slot);
+ if (base) {
+ return base->object;
+ }
+ return NULL;
+}
+
bool ED_view3d_is_object_under_cursor(bContext *C, const int mval[2])
{
return ED_view3d_give_object_under_cursor(C, mval) != NULL;
@@ -2374,7 +2409,8 @@ static bool ed_object_select_pick(bContext *C,
}
}
else {
- basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, has_bones, do_nearest);
+ basact = mouse_select_eval_buffer(
+ &vc, buffer, hits, startbase, has_bones, do_nearest, NULL);
}
if (has_bones && basact) {
@@ -2436,7 +2472,7 @@ static bool ed_object_select_pick(bContext *C,
if (!changed) {
/* fallback to regular object selection if no new bundles were selected,
* allows to select object parented to reconstruction object */
- basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest);
+ basact = mouse_select_eval_buffer(&vc, buffer, hits, startbase, 0, do_nearest, NULL);
}
}
}
@@ -2677,7 +2713,7 @@ static int view3d_select_exec(bContext *C, wmOperator *op)
uint buffer[MAXPICKBUF];
const int hits = mixed_bones_object_selectbuffer(
- &vc, buffer, location, VIEW3D_SELECT_FILTER_NOP, false, true);
+ &vc, buffer, location, VIEW3D_SELECT_FILTER_NOP, false, true, false);
retval = bone_mouse_select_menu(C, buffer, hits, true, extend, deselect, toggle);
}
if (!retval) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 86a610f8dd9..b9f3706b084 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -964,12 +964,13 @@ static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void
*
* \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
*/
-int view3d_opengl_select(ViewContext *vc,
- uint *buffer,
- uint bufsize,
- const rcti *input,
- eV3DSelectMode select_mode,
- eV3DSelectObjectFilter select_filter)
+int view3d_opengl_select_ex(ViewContext *vc,
+ uint *buffer,
+ uint bufsize,
+ const rcti *input,
+ eV3DSelectMode select_mode,
+ eV3DSelectObjectFilter select_filter,
+ const bool do_material_slot_selection)
{
struct bThemeState theme_state;
const wmWindowManager *wm = CTX_wm_manager(vc->C);
@@ -1119,6 +1120,7 @@ int view3d_opengl_select(ViewContext *vc,
use_obedit_skip,
draw_surface,
use_nearest,
+ do_material_slot_selection,
&rect,
drw_select_loop_pass,
&drw_select_loop_user_data,
@@ -1149,6 +1151,7 @@ int view3d_opengl_select(ViewContext *vc,
use_obedit_skip,
draw_surface,
use_nearest,
+ do_material_slot_selection,
&rect,
drw_select_loop_pass,
&drw_select_loop_user_data,
@@ -1178,6 +1181,16 @@ finally:
return hits;
}
+int view3d_opengl_select(ViewContext *vc,
+ uint *buffer,
+ uint bufsize,
+ const rcti *input,
+ eV3DSelectMode select_mode,
+ eV3DSelectObjectFilter select_filter)
+{
+ return view3d_opengl_select_ex(vc, buffer, bufsize, input, select_mode, select_filter, false);
+}
+
int view3d_opengl_select_with_id_filter(ViewContext *vc,
uint *buffer,
uint bufsize,
diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c
index a54149912a9..e82a00bcc77 100644
--- a/source/blender/editors/transform/transform_snap_sequencer.c
+++ b/source/blender/editors/transform/transform_snap_sequencer.c
@@ -260,7 +260,7 @@ TransSeqSnapData *transform_snap_sequencer_data_alloc(const TransInfo *t)
SeqCollection *snap_sources = SEQ_query_selected_strips(seqbase);
SeqCollection *snap_targets = query_snap_targets(t, snap_sources);
- if (SEQ_collection_len(snap_sources) == 0 || SEQ_collection_len(snap_targets) == 0) {
+ if (SEQ_collection_len(snap_sources) == 0) {
SEQ_collection_free(snap_targets);
SEQ_collection_free(snap_sources);
MEM_freeN(snap_data);
diff --git a/source/blender/io/usd/intern/usd_reader_instance.cc b/source/blender/io/usd/intern/usd_reader_instance.cc
deleted file mode 100644
index e645b0237b9..00000000000
--- a/source/blender/io/usd/intern/usd_reader_instance.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2021 Blender Foundation.
- * All rights reserved.
- */
-
-#include "usd_reader_instance.h"
-
-#include "BKE_object.h"
-#include "DNA_object_types.h"
-
-#include <iostream>
-
-namespace blender::io::usd {
-
-USDInstanceReader::USDInstanceReader(const pxr::UsdPrim &prim,
- const USDImportParams &import_params,
- const ImportSettings &settings)
- : USDXformReader(prim, import_params, settings)
-{
-}
-
-bool USDInstanceReader::valid() const
-{
- return prim_.IsValid() && prim_.IsInstance();
-}
-
-void USDInstanceReader::create_object(Main *bmain, const double /* motionSampleTime */)
-{
- this->object_ = BKE_object_add_only_object(bmain, OB_EMPTY, name_.c_str());
- this->object_->data = nullptr;
- this->object_->transflag |= OB_DUPLICOLLECTION;
-}
-
-void USDInstanceReader::set_instance_collection(Collection *coll)
-{
- if (this->object_) {
- this->object_->instance_collection = coll;
- }
-}
-
-pxr::SdfPath USDInstanceReader::proto_path() const
-{
- if (pxr::UsdPrim master = prim_.GetMaster()) {
- return master.GetPath();
- }
-
- return pxr::SdfPath();
-}
-
-} // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_reader_instance.h b/source/blender/io/usd/intern/usd_reader_instance.h
deleted file mode 100644
index efc1c69a7dd..00000000000
--- a/source/blender/io/usd/intern/usd_reader_instance.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2021 Blender Foundation.
- * All rights reserved.
- */
-#pragma once
-
-#include "usd_reader_xform.h"
-
-#include <pxr/usd/usdGeom/xform.h>
-
-struct Collection;
-
-namespace blender::io::usd {
-
-/* Wraps the UsdGeomXform schema. Creates a Blender Empty object. */
-
-class USDInstanceReader : public USDXformReader {
-
- public:
- USDInstanceReader(const pxr::UsdPrim &prim,
- const USDImportParams &import_params,
- const ImportSettings &settings);
-
- bool valid() const override;
-
- void create_object(Main *bmain, double motionSampleTime) override;
-
- void set_instance_collection(Collection *coll);
-
- pxr::SdfPath proto_path() const;
-};
-
-} // namespace blender::io::usd
diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc
index 233b3d9da4d..8c4cc18a9af 100644
--- a/source/blender/io/usd/intern/usd_reader_stage.cc
+++ b/source/blender/io/usd/intern/usd_reader_stage.cc
@@ -20,7 +20,6 @@
#include "usd_reader_stage.h"
#include "usd_reader_camera.h"
#include "usd_reader_curve.h"
-#include "usd_reader_instance.h"
#include "usd_reader_light.h"
#include "usd_reader_mesh.h"
#include "usd_reader_nurbs.h"
@@ -34,6 +33,7 @@
#include <pxr/usd/usdGeom/mesh.h>
#include <pxr/usd/usdGeom/nurbsCurves.h>
#include <pxr/usd/usdGeom/scope.h>
+#include <pxr/usd/usdGeom/xform.h>
#include <pxr/usd/usdLux/light.h>
#include <iostream>
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 22408687daf..30ca9540735 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -94,11 +94,17 @@ typedef struct RenderSlot {
struct RenderResult *render;
} RenderSlot;
-typedef struct ImageTile_Runtime {
+typedef struct ImageTile_RuntimeTextureSlot {
int tilearray_layer;
int _pad;
int tilearray_offset[2];
int tilearray_size[2];
+} ImageTile_RuntimeTextureSlot;
+
+typedef struct ImageTile_Runtime {
+ /* Data per `eImageTextureResolution`.
+ * Should match `IMA_TEXTURE_RESOLUTION_LEN` */
+ ImageTile_RuntimeTextureSlot slots[2];
} ImageTile_Runtime;
typedef struct ImageTile {
@@ -132,6 +138,15 @@ typedef enum eGPUTextureTarget {
TEXTARGET_COUNT,
} eGPUTextureTarget;
+/* Resolution variations that can be cached for an image. */
+typedef enum eImageTextureResolution {
+ IMA_TEXTURE_RESOLUTION_FULL = 0,
+ IMA_TEXTURE_RESOLUTION_LIMITED,
+
+ /* Not an option, but holds the number of options defined for this struct. */
+ IMA_TEXTURE_RESOLUTION_LEN
+} eImageTextureResolution;
+
typedef struct Image {
ID id;
@@ -140,8 +155,8 @@ typedef struct Image {
/** Not written in file. */
struct MovieCache *cache;
- /** Not written in file 3 = TEXTARGET_COUNT, 2 = stereo eyes. */
- struct GPUTexture *gputexture[3][2];
+ /** Not written in file 3 = TEXTARGET_COUNT, 2 = stereo eyes, 2 = IMA_TEXTURE_RESOLUTION_LEN. */
+ struct GPUTexture *gputexture[3][2][2];
/* sources from: */
ListBase anims;
@@ -233,12 +248,15 @@ enum {
IMA_GPU_PARTIAL_REFRESH = (1 << 1),
/** All mipmap levels in OpenGL texture set? */
IMA_GPU_MIPMAP_COMPLETE = (1 << 2),
- /** Current texture resolution won't be limited by the GL Texture Limit user preference. */
- IMA_GPU_MAX_RESOLUTION = (1 << 3),
+ /* Reuse the max resolution textures as they fit in the limited scale. */
+ IMA_GPU_REUSE_MAX_RESOLUTION = (1 << 3),
+ /* Has any limited scale textures been allocated.
+ * Adds additional checks to reuse max resolution images when they fit inside limited scale. */
+ IMA_GPU_HAS_LIMITED_SCALE_TEXTURES = (1 << 4),
};
/* Image.source, where the image comes from */
-enum {
+typedef enum eImageSource {
/* IMA_SRC_CHECK = 0, */ /* UNUSED */
IMA_SRC_FILE = 1,
IMA_SRC_SEQUENCE = 2,
@@ -246,10 +264,10 @@ enum {
IMA_SRC_GENERATED = 4,
IMA_SRC_VIEWER = 5,
IMA_SRC_TILED = 6,
-};
+} eImageSource;
/* Image.type, how to handle or generate the image */
-enum {
+typedef enum eImageType {
IMA_TYPE_IMAGE = 0,
IMA_TYPE_MULTILAYER = 1,
/* generated */
@@ -257,7 +275,7 @@ enum {
/* viewers */
IMA_TYPE_R_RESULT = 4,
IMA_TYPE_COMPOSITE = 5,
-};
+} eImageType;
/* Image.gen_type */
enum {
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index e44ddb07d53..4a013dc9bd7 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -404,7 +404,7 @@ static void rna_Image_resolution_set(PointerRNA *ptr, const float *values)
static int rna_Image_bindcode_get(PointerRNA *ptr)
{
Image *ima = (Image *)ptr->data;
- GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0];
+ GPUTexture *tex = ima->gputexture[TEXTARGET_2D][0][IMA_TEXTURE_RESOLUTION_FULL];
return (tex) ? GPU_texture_opengl_bindcode(tex) : 0;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
index f5ab9c053c1..72e9e8f5c29 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_point_instance.cc
@@ -38,7 +38,7 @@ static void geo_node_point_instance_declare(NodeDeclarationBuilder &b)
static void geo_node_point_instance_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
{
- uiItemR(layout, ptr, "instance_type", 0, nullptr, ICON_NONE);
+ uiItemR(layout, ptr, "instance_type", 0, "", ICON_NONE);
if (RNA_enum_get(ptr, "instance_type") == GEO_NODE_POINT_INSTANCE_TYPE_COLLECTION) {
uiItemR(layout, ptr, "use_whole_collection", 0, nullptr, ICON_NONE);
}
diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc
index 418fed146fb..ba9a1870b0c 100644
--- a/source/blender/nodes/intern/node_socket_declarations.cc
+++ b/source/blender/nodes/intern/node_socket_declarations.cc
@@ -274,7 +274,7 @@ bNodeSocket &build_id_socket(bNodeTree &ntree,
StringRefNull identifier)
{
bNodeSocket &socket = *nodeAddSocket(
- &ntree, &node, in_out, data.idname, name.c_str(), identifier.c_str());
+ &ntree, &node, in_out, data.idname, identifier.c_str(), name.c_str());
if (data.hide_label) {
socket.flag |= SOCK_HIDE_LABEL;
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index df051328990..81dcc5ccea0 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -552,37 +552,38 @@ static const char *wm_context_member_from_ptr(bContext *C, const PointerRNA *ptr
const View3D *v3d = (View3D *)space_data;
const View3DShading *shading = &v3d->shading;
- TEST_PTR_DATA_TYPE("space_data", RNA_View3DOverlay, ptr, v3d);
- TEST_PTR_DATA_TYPE("space_data", RNA_View3DShading, ptr, shading);
+ TEST_PTR_DATA_TYPE("space_data.overlay", RNA_View3DOverlay, ptr, v3d);
+ TEST_PTR_DATA_TYPE("space_data.shading", RNA_View3DShading, ptr, shading);
break;
}
case SPACE_GRAPH: {
const SpaceGraph *sipo = (SpaceGraph *)space_data;
const bDopeSheet *ads = sipo->ads;
- TEST_PTR_DATA_TYPE("space_data", RNA_DopeSheet, ptr, ads);
+ TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads);
break;
}
case SPACE_FILE: {
const SpaceFile *sfile = (SpaceFile *)space_data;
const FileSelectParams *params = ED_fileselect_get_active_params(sfile);
- TEST_PTR_DATA_TYPE("space_data", RNA_FileSelectParams, ptr, params);
+ TEST_PTR_DATA_TYPE("space_data.params", RNA_FileSelectParams, ptr, params);
break;
}
case SPACE_IMAGE: {
const SpaceImage *sima = (SpaceImage *)space_data;
- TEST_PTR_DATA_TYPE("space_data", RNA_SpaceUVEditor, ptr, sima);
+ TEST_PTR_DATA_TYPE("space_data.overlay", RNA_SpaceImageOverlay, ptr, sima);
+ TEST_PTR_DATA_TYPE("space_data.uv_editor", RNA_SpaceUVEditor, ptr, sima);
break;
}
case SPACE_NLA: {
const SpaceNla *snla = (SpaceNla *)space_data;
const bDopeSheet *ads = snla->ads;
- TEST_PTR_DATA_TYPE("space_data", RNA_DopeSheet, ptr, ads);
+ TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads);
break;
}
case SPACE_ACTION: {
const SpaceAction *sact = (SpaceAction *)space_data;
const bDopeSheet *ads = &sact->ads;
- TEST_PTR_DATA_TYPE("space_data", RNA_DopeSheet, ptr, ads);
+ TEST_PTR_DATA_TYPE("space_data.dopesheet", RNA_DopeSheet, ptr, ads);
break;
}
}