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:
authorYimingWu <xp8110@outlook.com>2019-05-28 10:39:42 +0300
committerYimingWu <xp8110@outlook.com>2019-05-28 10:39:42 +0300
commitf37533fc44cfb8a7eec919df0dae38998de10e2f (patch)
tree264074656a88f96bdc3a4dbf53340277d45dc86a /source/blender/editors
parenta640228d92273154acc644d525b095b5318c248b (diff)
parent1008d9c73567780ec22bea6a0b27f57e60ea403d (diff)
Merge branch 'master' into soc-2019-npr
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/animation/anim_markers.c2
-rw-r--r--source/blender/editors/animation/time_scrub_ui.c46
-rw-r--r--source/blender/editors/curve/editcurve.c406
-rw-r--r--source/blender/editors/curve/editfont.c4
-rw-r--r--source/blender/editors/datafiles/CMakeLists.txt4
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c3
-rw-r--r--source/blender/editors/include/ED_anim_api.h4
-rw-r--r--source/blender/editors/include/ED_mask.h4
-rw-r--r--source/blender/editors/include/ED_mesh.h24
-rw-r--r--source/blender/editors/include/ED_select_buffer_utils.h43
-rw-r--r--source/blender/editors/include/ED_time_scrub_ui.h22
-rw-r--r--source/blender/editors/include/ED_view3d.h16
-rw-r--r--source/blender/editors/include/UI_icons.h10
-rw-r--r--source/blender/editors/include/UI_interface.h35
-rw-r--r--source/blender/editors/include/UI_resources.h2
-rw-r--r--source/blender/editors/include/UI_view2d.h2
-rw-r--r--source/blender/editors/interface/interface.c19
-rw-r--r--source/blender/editors/interface/interface_context_menu.c30
-rw-r--r--source/blender/editors/interface/interface_eyedropper_datablock.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c27
-rw-r--r--source/blender/editors/interface/interface_icons.c6
-rw-r--r--source/blender/editors/interface/interface_intern.h1
-rw-r--r--source/blender/editors/interface/interface_layout.c147
-rw-r--r--source/blender/editors/interface/interface_panel.c82
-rw-r--r--source/blender/editors/interface/interface_region_tooltip.c3
-rw-r--r--source/blender/editors/interface/interface_templates.c10
-rw-r--r--source/blender/editors/interface/interface_widgets.c12
-rw-r--r--source/blender/editors/interface/resources.c4
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/interface/view2d_draw.c10
-rw-r--r--source/blender/editors/io/io_cache.c2
-rw-r--r--source/blender/editors/io/io_collada.c170
-rw-r--r--source/blender/editors/mask/mask_add.c66
-rw-r--r--source/blender/editors/mask/mask_draw.c10
-rw-r--r--source/blender/editors/mask/mask_ops.c111
-rw-r--r--source/blender/editors/mask/mask_select.c12
-rw-r--r--source/blender/editors/mesh/editface.c68
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c6
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c3
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c5
-rw-r--r--source/blender/editors/mesh/editmesh_path.c83
-rw-r--r--source/blender/editors/mesh/editmesh_select.c273
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c23
-rw-r--r--source/blender/editors/mesh/meshtools.c9
-rw-r--r--source/blender/editors/object/object_add.c36
-rw-r--r--source/blender/editors/object/object_bake_api.c8
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_relations.c2
-rw-r--r--source/blender/editors/object/object_transform.c5
-rw-r--r--source/blender/editors/render/render_opengl.c12
-rw-r--r--source/blender/editors/render/render_shading.c6
-rw-r--r--source/blender/editors/screen/area.c8
-rw-r--r--source/blender/editors/screen/screen_context.c59
-rw-r--r--source/blender/editors/screen/screen_edit.c6
-rw-r--r--source/blender/editors/screen/screen_user_menu.c40
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c16
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_action/action_data.c6
-rw-r--r--source/blender/editors/space_action/space_action.c4
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c3
-rw-r--r--source/blender/editors/space_clip/clip_intern.h2
-rw-r--r--source/blender/editors/space_clip/clip_ops.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c17
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c3
-rw-r--r--source/blender/editors/space_graph/graph_edit.c11
-rw-r--r--source/blender/editors/space_graph/space_graph.c6
-rw-r--r--source/blender/editors/space_image/image_buttons.c502
-rw-r--r--source/blender/editors/space_image/image_ops.c7
-rw-r--r--source/blender/editors/space_image/space_image.c3
-rw-r--r--source/blender/editors/space_nla/space_nla.c4
-rw-r--r--source/blender/editors/space_node/drawnode.c5
-rw-r--r--source/blender/editors/space_node/node_add.c2
-rw-r--r--source/blender/editors/space_node/node_select.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c6
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c30
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c10
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_modifier.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c2
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c1
-rw-r--r--source/blender/editors/space_text/text_ops.c4
-rw-r--r--source/blender/editors/space_userpref/userpref_ops.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c167
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c157
-rw-r--r--source/blender/editors/space_view3d/view3d_gizmo_navigate.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c583
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c2
-rw-r--r--source/blender/editors/transform/transform.c1
-rw-r--r--source/blender/editors/transform/transform_generics.c7
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c30
-rw-r--r--source/blender/editors/transform/transform_gizmo_extrude_3d.c3
-rw-r--r--source/blender/editors/transform/transform_ops.c58
-rw-r--r--source/blender/editors/undo/ed_undo.c2
-rw-r--r--source/blender/editors/util/CMakeLists.txt2
-rw-r--r--source/blender/editors/util/select_buffer_utils.c303
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c5
102 files changed, 2352 insertions, 1687 deletions
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 876bc9ae3e4..90632da8a7c 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -482,7 +482,7 @@ static void draw_markers_background(rctf *rect)
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
unsigned char shade[4];
- UI_GetThemeColor4ubv(TH_SCRUBBING_BACKGROUND, shade);
+ UI_GetThemeColor4ubv(TH_TIME_SCRUB_BACKGROUND, shade);
immUniformColor4ubv(shade);
diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c
index 37e7eab74d4..70a9b7ba1fa 100644
--- a/source/blender/editors/animation/time_scrub_ui.c
+++ b/source/blender/editors/animation/time_scrub_ui.c
@@ -46,12 +46,12 @@
#include "RNA_access.h"
-static void get_scrubbing_region_rect(const ARegion *ar, rcti *rect)
+static void get_time_scrub_region_rect(const ARegion *ar, rcti *rect)
{
rect->xmin = 0;
rect->xmax = ar->winx;
rect->ymax = ar->winy;
- rect->ymin = rect->ymax - UI_SCRUBBING_MARGIN_Y;
+ rect->ymin = rect->ymax - UI_TIME_SCRUB_MARGIN_Y;
}
static int get_centered_text_y(const rcti *rect)
@@ -64,7 +64,7 @@ static void draw_background(const rcti *rect)
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColor(TH_SCRUBBING_BACKGROUND);
+ immUniformThemeColor(TH_TIME_SCRUB_BACKGROUND);
GPU_blend(true);
GPU_blend_set_func_separate(
@@ -91,7 +91,7 @@ static void get_current_time_str(
static void draw_current_frame(const Scene *scene,
bool display_seconds,
const View2D *v2d,
- const rcti *scrubbing_region_rect,
+ const rcti *scrub_region_rect,
int current_frame)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
@@ -111,9 +111,9 @@ static void draw_current_frame(const Scene *scene,
UI_draw_roundbox_3fvAlpha(true,
frame_x - box_width / 2 + U.pixelsize / 2,
- scrubbing_region_rect->ymin + box_padding,
+ scrub_region_rect->ymin + box_padding,
frame_x + box_width / 2 + U.pixelsize / 2,
- scrubbing_region_rect->ymax - box_padding,
+ scrub_region_rect->ymax - box_padding,
4 * UI_DPI_FAC,
bg_color,
1.0f);
@@ -121,36 +121,36 @@ static void draw_current_frame(const Scene *scene,
UI_GetThemeColorShade4fv(TH_CFRAME, 5, bg_color);
UI_draw_roundbox_aa(false,
frame_x - box_width / 2 + U.pixelsize / 2,
- scrubbing_region_rect->ymin + box_padding,
+ scrub_region_rect->ymin + box_padding,
frame_x + box_width / 2 + U.pixelsize / 2,
- scrubbing_region_rect->ymax - box_padding,
+ scrub_region_rect->ymax - box_padding,
4 * UI_DPI_FAC,
bg_color);
UI_fontstyle_draw_simple(fstyle,
frame_x - text_width / 2 + U.pixelsize / 2,
- get_centered_text_y(scrubbing_region_rect),
+ get_centered_text_y(scrub_region_rect),
frame_str,
color);
}
-void ED_scrubbing_draw(const ARegion *ar,
- const Scene *scene,
- bool display_seconds,
- bool discrete_frames)
+void ED_time_scrub_draw(const ARegion *ar,
+ const Scene *scene,
+ bool display_seconds,
+ bool discrete_frames)
{
const View2D *v2d = &ar->v2d;
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
- rcti scrubbing_region_rect;
- get_scrubbing_region_rect(ar, &scrubbing_region_rect);
+ rcti scrub_region_rect;
+ get_time_scrub_region_rect(ar, &scrub_region_rect);
- draw_background(&scrubbing_region_rect);
+ draw_background(&scrub_region_rect);
- rcti numbers_rect = scrubbing_region_rect;
- numbers_rect.ymin = get_centered_text_y(&scrubbing_region_rect) - 4 * UI_DPI_FAC;
+ rcti numbers_rect = scrub_region_rect;
+ numbers_rect.ymin = get_centered_text_y(&scrub_region_rect) - 4 * UI_DPI_FAC;
if (discrete_frames) {
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
@@ -160,19 +160,19 @@ void ED_scrubbing_draw(const ARegion *ar,
ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
}
- draw_current_frame(scene, display_seconds, v2d, &scrubbing_region_rect, scene->r.cfra);
+ draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra);
GPU_matrix_pop_projection();
}
-bool ED_event_in_scrubbing_region(const ARegion *ar, const wmEvent *event)
+bool ED_time_scrub_event_in_region(const ARegion *ar, const wmEvent *event)
{
rcti rect = ar->winrct;
- rect.ymin = rect.ymax - UI_SCRUBBING_MARGIN_Y;
+ rect.ymin = rect.ymax - UI_TIME_SCRUB_MARGIN_Y;
return BLI_rcti_isect_pt(&rect, event->x, event->y);
}
-void ED_channel_search_draw(const bContext *C, ARegion *ar, bDopeSheet *dopesheet)
+void ED_time_scrub_channel_search_draw(const bContext *C, ARegion *ar, bDopeSheet *dopesheet)
{
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
@@ -180,7 +180,7 @@ void ED_channel_search_draw(const bContext *C, ARegion *ar, bDopeSheet *dopeshee
rcti rect;
rect.xmin = 0;
rect.xmax = ceilf(ar->sizex * UI_DPI_FAC);
- rect.ymin = ar->sizey * UI_DPI_FAC - UI_SCRUBBING_MARGIN_Y;
+ rect.ymin = ar->sizey * UI_DPI_FAC - UI_TIME_SCRUB_MARGIN_Y;
rect.ymax = ceilf(ar->sizey * UI_DPI_FAC);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 65f502d5cd2..8d131ee28ba 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -2584,33 +2584,42 @@ void CURVE_OT_switch_direction(wmOperatorType *ot)
static int set_goal_weight_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- float weight = RNA_float_get(op->ptr, "weight");
- int a;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
- if (bezt->f2 & SELECT) {
- bezt->weight = weight;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ float weight = RNA_float_get(op->ptr, "weight");
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ bezt->weight = weight;
+ }
}
}
- }
- else if (nu->bp) {
- for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
- if (bp->f1 & SELECT) {
- bp->weight = weight;
+ else if (nu->bp) {
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ if (bp->f1 & SELECT) {
+ bp->weight = weight;
+ }
}
}
}
+
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
}
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -2638,33 +2647,42 @@ void CURVE_OT_spline_weight_set(wmOperatorType *ot)
static int set_radius_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- BezTriple *bezt;
- BPoint *bp;
- float radius = RNA_float_get(op->ptr, "radius");
- int a;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
- if (bezt->f2 & SELECT) {
- bezt->radius = radius;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ BezTriple *bezt;
+ BPoint *bp;
+ float radius = RNA_float_get(op->ptr, "radius");
+ int a;
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) {
+ if (bezt->f2 & SELECT) {
+ bezt->radius = radius;
+ }
}
}
- }
- else if (nu->bp) {
- for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
- if (bp->f1 & SELECT) {
- bp->radius = radius;
+ else if (nu->bp) {
+ for (bp = nu->bp, a = 0; a < nu->pntsu * nu->pntsv; a++, bp++) {
+ if (bp->f1 & SELECT) {
+ bp->radius = radius;
+ }
}
}
}
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
}
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -2743,81 +2761,90 @@ static void smooth_single_bp(BPoint *bp,
static int smooth_exec(bContext *C, wmOperator *UNUSED(op))
{
const float factor = 1.0f / 6.0f;
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
- int a, a_end;
- bool changed = false;
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (nu->bezt) {
- /* duplicate the curve to use in weight calculation */
- const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
- BezTriple *bezt;
- changed = false;
+ int a, a_end;
+ bool changed = false;
- /* check whether its cyclic or not, and set initial & final conditions */
- if (nu->flagu & CU_NURB_CYCLIC) {
- a = 0;
- a_end = nu->pntsu;
- }
- else {
- a = 1;
- a_end = nu->pntsu - 1;
- }
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (nu->bezt) {
+ /* duplicate the curve to use in weight calculation */
+ const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt);
+ BezTriple *bezt;
+ changed = false;
+
+ /* check whether its cyclic or not, and set initial & final conditions */
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
- /* for all the curve points */
- for (; a < a_end; a++) {
- /* respect selection */
- bezt = &nu->bezt[a];
- if (bezt->f2 & SELECT) {
- const BezTriple *bezt_orig_prev, *bezt_orig_next;
+ /* for all the curve points */
+ for (; a < a_end; a++) {
+ /* respect selection */
+ bezt = &nu->bezt[a];
+ if (bezt->f2 & SELECT) {
+ const BezTriple *bezt_orig_prev, *bezt_orig_next;
- bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
- bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
+ bezt_orig_prev = &bezt_orig[mod_i(a - 1, nu->pntsu)];
+ bezt_orig_next = &bezt_orig[mod_i(a + 1, nu->pntsu)];
- smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
+ smooth_single_bezt(bezt, bezt_orig_prev, bezt_orig_next, factor);
- changed = true;
+ changed = true;
+ }
+ }
+ MEM_freeN((void *)bezt_orig);
+ if (changed) {
+ BKE_nurb_handles_calc(nu);
}
}
- MEM_freeN((void *)bezt_orig);
- if (changed) {
- BKE_nurb_handles_calc(nu);
- }
- }
- else if (nu->bp) {
- /* Same as above, keep these the same! */
- const BPoint *bp_orig = MEM_dupallocN(nu->bp);
- BPoint *bp;
+ else if (nu->bp) {
+ /* Same as above, keep these the same! */
+ const BPoint *bp_orig = MEM_dupallocN(nu->bp);
+ BPoint *bp;
- if (nu->flagu & CU_NURB_CYCLIC) {
- a = 0;
- a_end = nu->pntsu;
- }
- else {
- a = 1;
- a_end = nu->pntsu - 1;
- }
+ if (nu->flagu & CU_NURB_CYCLIC) {
+ a = 0;
+ a_end = nu->pntsu;
+ }
+ else {
+ a = 1;
+ a_end = nu->pntsu - 1;
+ }
- for (; a < a_end; a++) {
- bp = &nu->bp[a];
- if (bp->f1 & SELECT) {
- const BPoint *bp_orig_prev, *bp_orig_next;
+ for (; a < a_end; a++) {
+ bp = &nu->bp[a];
+ if (bp->f1 & SELECT) {
+ const BPoint *bp_orig_prev, *bp_orig_next;
- bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
- bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
+ bp_orig_prev = &bp_orig[mod_i(a - 1, nu->pntsu)];
+ bp_orig_next = &bp_orig[mod_i(a + 1, nu->pntsu)];
- smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
+ smooth_single_bp(bp, bp_orig_prev, bp_orig_next, factor);
+ }
}
+ MEM_freeN((void *)bp_orig);
}
- MEM_freeN((void *)bp_orig);
}
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
}
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3023,13 +3050,22 @@ static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, cons
static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
+
+ curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
- curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight));
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3051,13 +3087,22 @@ void CURVE_OT_smooth_weight(wmOperatorType *ot)
static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
- curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
+
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3079,13 +3124,22 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot)
static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op))
{
- Object *obedit = CTX_data_edit_object(C);
- ListBase *editnurb = object_editcurve_get(obedit);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
- curve_smooth_value(editnurb, offsetof(BezTriple, tilt), offsetof(BPoint, tilt));
+ curve_smooth_value(editnurb, offsetof(BezTriple, tilt), offsetof(BPoint, tilt));
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ }
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -3253,7 +3307,8 @@ static int reveal_exec(bContext *C, wmOperator *op)
}
if (changed) {
- DEG_id_tag_update(obedit->data, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT);
+ DEG_id_tag_update(obedit->data,
+ ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
changed_multi = true;
}
@@ -3909,54 +3964,63 @@ static void findselectedNurbvert(
static int set_spline_type_exec(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Object *obedit = CTX_data_edit_object(C);
- View3D *v3d = CTX_wm_view3d(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
- bool changed = false;
- bool changed_size = false;
- const bool use_handles = RNA_boolean_get(op->ptr, "use_handles");
- const int type = RNA_enum_get(op->ptr, "type");
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ int ret_value = OPERATOR_CANCELLED;
- if (type == CU_CARDINAL || type == CU_BSPLINE) {
- BKE_report(op->reports, RPT_ERROR, "Not yet implemented");
- return OPERATOR_CANCELLED;
- }
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ Main *bmain = CTX_data_main(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ ListBase *editnurb = object_editcurve_get(obedit);
+ Nurb *nu;
+ bool changed = false;
+ bool changed_size = false;
+ const bool use_handles = RNA_boolean_get(op->ptr, "use_handles");
+ const int type = RNA_enum_get(op->ptr, "type");
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- const int pntsu_prev = nu->pntsu;
- if (BKE_nurb_type_convert(nu, type, use_handles)) {
- changed = true;
- if (pntsu_prev != nu->pntsu) {
- changed_size = true;
+ if (type == CU_CARDINAL || type == CU_BSPLINE) {
+ BKE_report(op->reports, RPT_ERROR, "Not yet implemented");
+ continue;
+ }
+
+ for (nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ const int pntsu_prev = nu->pntsu;
+ if (BKE_nurb_type_convert(nu, type, use_handles)) {
+ changed = true;
+ if (pntsu_prev != nu->pntsu) {
+ changed_size = true;
+ }
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No conversion possible");
}
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No conversion possible");
}
}
- }
- if (changed) {
- if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
- }
+ if (changed) {
+ if (ED_curve_updateAnimPaths(bmain, obedit->data)) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit);
+ }
- DEG_id_tag_update(obedit->data, 0);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- if (changed_size) {
- Curve *cu = obedit->data;
- cu->actvert = CU_ACT_NONE;
- }
+ if (changed_size) {
+ Curve *cu = obedit->data;
+ cu->actvert = CU_ACT_NONE;
+ }
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
+ ret_value = OPERATOR_FINISHED;
+ }
}
+
+ MEM_freeN(objects);
+
+ return ret_value;
}
void CURVE_OT_spline_type_set(wmOperatorType *ot)
@@ -6747,31 +6811,41 @@ void CURVE_OT_decimate(wmOperatorType *ot)
static int shade_smooth_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
View3D *v3d = CTX_wm_view3d(C);
- ListBase *editnurb = object_editcurve_get(obedit);
- Nurb *nu;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
int clear = (STREQ(op->idname, "CURVE_OT_shade_flat"));
+ uint objects_len;
+ Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
+ view_layer, CTX_wm_view3d(C), &objects_len);
+ int ret_value = OPERATOR_CANCELLED;
- if (obedit->type != OB_CURVE) {
- return OPERATOR_CANCELLED;
- }
+ for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
+ Object *obedit = objects[ob_index];
+ ListBase *editnurb = object_editcurve_get(obedit);
- for (nu = editnurb->first; nu; nu = nu->next) {
- if (ED_curve_nurb_select_check(v3d, nu)) {
- if (!clear) {
- nu->flag |= CU_SMOOTH;
- }
- else {
- nu->flag &= ~CU_SMOOTH;
+ if (obedit->type != OB_CURVE) {
+ continue;
+ }
+
+ for (Nurb *nu = editnurb->first; nu; nu = nu->next) {
+ if (ED_curve_nurb_select_check(v3d, nu)) {
+ if (!clear) {
+ nu->flag |= CU_SMOOTH;
+ }
+ else {
+ nu->flag &= ~CU_SMOOTH;
+ }
}
}
+
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
+ DEG_id_tag_update(obedit->data, 0);
+ ret_value = OPERATOR_FINISHED;
}
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
- DEG_id_tag_update(obedit->data, 0);
+ MEM_freeN(objects);
- return OPERATOR_FINISHED;
+ return ret_value;
}
void CURVE_OT_shade_smooth(wmOperatorType *ot)
@@ -7026,7 +7100,7 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op))
int a;
if (object->runtime.curve_cache == NULL) {
- BKE_displist_make_curveTypes(depsgraph, scene, object, false, false, NULL);
+ BKE_displist_make_curveTypes(depsgraph, scene, object, false, false);
}
INIT_MINMAX(min, max);
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 0759b64d14a..ffbfb692ca9 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -2007,7 +2007,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
id_us_min(&font->id);
RNA_id_pointer_create(&font->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
@@ -2090,7 +2090,7 @@ static int font_unlink_exec(bContext *C, wmOperator *op)
builtin_font = BKE_vfont_builtin_get();
RNA_id_pointer_create(&builtin_font->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop.ptr, pprop.prop, idptr);
+ RNA_property_pointer_set(&pprop.ptr, pprop.prop, idptr, NULL);
RNA_property_update(C, &pprop.ptr, pprop.prop);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt
index 316ad3f91d6..d2d0095bdb2 100644
--- a/source/blender/editors/datafiles/CMakeLists.txt
+++ b/source/blender/editors/datafiles/CMakeLists.txt
@@ -569,9 +569,9 @@ set(ICON_NAMES
loop_forwards
back
forward
+ file_cache
file_volume
- alembic
- volume
+ file_3d
file_hidden
file_backup
disk_drive
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 96f405fab2f..bf15b846bb6 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -401,7 +401,8 @@ static bool gp_render_offscreen(tGPDfill *tgpf)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- ED_view3d_update_viewmat(tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, NULL, winmat, NULL);
+ ED_view3d_update_viewmat(
+ tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->ar, NULL, winmat, NULL, true);
/* set for opengl */
GPU_matrix_projection_set(tgpf->rv3d->winmat);
GPU_matrix_set(tgpf->rv3d->viewmat);
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index cd68981dee3..7a29e6b5e66 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -404,7 +404,7 @@ typedef enum eAnimFilter_Flags {
/* channel heights */
#define ACHANNEL_FIRST_TOP(ac) \
- (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - ACHANNEL_SKIP)
+ (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_TIME_SCRUB_MARGIN_Y - ACHANNEL_SKIP)
#define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit)
#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP)
@@ -422,7 +422,7 @@ typedef enum eAnimFilter_Flags {
/* NLA channel heights */
#define NLACHANNEL_FIRST_TOP(ac) \
- (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - NLACHANNEL_SKIP)
+ (UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_TIME_SCRUB_MARGIN_Y - NLACHANNEL_SKIP)
#define NLACHANNEL_HEIGHT(snla) \
((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit))
#define NLACHANNEL_SKIP (0.1f * U.widget_unit)
diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h
index c3883de0722..3322cf0a863 100644
--- a/source/blender/editors/include/ED_mask.h
+++ b/source/blender/editors/include/ED_mask.h
@@ -24,6 +24,7 @@
#ifndef __ED_MASK_H__
#define __ED_MASK_H__
+struct Depsgraph;
struct KeyframeEditData;
struct MaskLayer;
struct MaskLayerShape;
@@ -55,7 +56,8 @@ void ED_operatormacros_mask(void);
/* mask_draw.c */
void ED_mask_draw(const struct bContext *C, const char draw_flag, const char draw_type);
-void ED_mask_draw_region(struct Mask *mask,
+void ED_mask_draw_region(struct Depsgraph *depsgraph,
+ struct Mask *mask,
struct ARegion *ar,
const char draw_flag,
const char draw_type,
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index 4e6bf7d4df5..0a8304f3f8a 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -152,24 +152,16 @@ struct BMElem *EDBM_select_id_bm_elem_get(struct EDBMSelectID_Context *sel_id_ct
const uint sel_id,
uint *r_base_index);
+uint EDBM_select_id_context_offset_for_object_elem(const struct EDBMSelectID_Context *sel_id_ctx,
+ int base_index,
+ char htype);
+
+uint EDBM_select_id_context_elem_len(const struct EDBMSelectID_Context *sel_id_ctx);
+
void EDBM_select_mirrored(
struct BMEditMesh *em, const int axis, const bool extend, int *r_totmirr, int *r_totfail);
void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update, const char hflag);
-bool EDBM_backbuf_border_init(
- struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
-bool EDBM_backbuf_check(unsigned int index);
-void EDBM_backbuf_free(void);
-
-bool EDBM_backbuf_border_mask_init(struct ViewContext *vc,
- const int mcords[][2],
- short tot,
- short xmin,
- short ymin,
- short xmax,
- short ymax);
-bool EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads);
-
struct BMVert *EDBM_vert_find_nearest_ex(struct ViewContext *vc,
float *r_dist,
const bool use_select_bias,
@@ -249,9 +241,6 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename
bool EDBM_mesh_deselect_all_multi_ex(struct Base **bases, const uint bases_len);
bool EDBM_mesh_deselect_all_multi(struct bContext *C);
-/* Only use for modes that don't support multi-edit-modes (painting). */
-extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
-
/* editmesh_preselect_edgering.c */
struct EditMesh_PreSelEdgeRing;
struct EditMesh_PreSelEdgeRing *EDBM_preselect_edgering_create(void);
@@ -291,7 +280,6 @@ bool paintface_mouse_select(struct bContext *C,
bool extend,
bool deselect,
bool toggle);
-bool do_paintface_box_select(struct ViewContext *vc, const struct rcti *rect, int sel_op);
bool paintface_deselect_all_visible(struct bContext *C,
struct Object *ob,
int action,
diff --git a/source/blender/editors/include/ED_select_buffer_utils.h b/source/blender/editors/include/ED_select_buffer_utils.h
new file mode 100644
index 00000000000..af745cee676
--- /dev/null
+++ b/source/blender/editors/include/ED_select_buffer_utils.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+/** \file
+ * \ingroup editors
+ */
+
+#ifndef __ED_SELECT_BUFFER_UTILS_H__
+#define __ED_SELECT_BUFFER_UTILS_H__
+
+struct rcti;
+
+/* Boolean array from selection ID's. */
+uint *ED_select_buffer_bitmap_from_rect(const uint bitmap_len, const struct rcti *rect);
+uint *ED_select_buffer_bitmap_from_circle(const uint bitmap_len,
+ const int center[2],
+ const int radius);
+uint *ED_select_buffer_bitmap_from_poly(const uint bitmap_len,
+ const int poly[][2],
+ const int poly_len,
+ const rcti *rect);
+
+/* Single result from selection ID's. */
+uint ED_select_buffer_sample_point(const int center[2]);
+uint ED_select_buffer_find_nearest_to_point(const int center[2],
+ const uint id_min,
+ const uint id_max,
+ uint *dist);
+
+#endif /* __ED_SELECT_BUFFER_UTILS_H__ */
diff --git a/source/blender/editors/include/ED_time_scrub_ui.h b/source/blender/editors/include/ED_time_scrub_ui.h
index a2e3098e949..b43e674224c 100644
--- a/source/blender/editors/include/ED_time_scrub_ui.h
+++ b/source/blender/editors/include/ED_time_scrub_ui.h
@@ -21,23 +21,23 @@
* \ingroup editors
*/
-#ifndef __ED_SCRUBBING_H__
-#define __ED_SCRUBBING_H__
+#ifndef __ED_TIME_SCRUB_UI_H__
+#define __ED_TIME_SCRUB_UI_H__
struct View2DGrid;
struct bContext;
struct bDopeSheet;
struct wmEvent;
-void ED_scrubbing_draw(const struct ARegion *ar,
- const struct Scene *scene,
- bool display_seconds,
- bool discrete_frames);
+void ED_time_scrub_draw(const struct ARegion *ar,
+ const struct Scene *scene,
+ bool display_seconds,
+ bool discrete_frames);
-bool ED_event_in_scrubbing_region(const struct ARegion *ar, const struct wmEvent *event);
+bool ED_time_scrub_event_in_region(const struct ARegion *ar, const struct wmEvent *event);
-void ED_channel_search_draw(const struct bContext *C,
- struct ARegion *ar,
- struct bDopeSheet *dopesheet);
+void ED_time_scrub_channel_search_draw(const struct bContext *C,
+ struct ARegion *ar,
+ struct bDopeSheet *dopesheet);
-#endif /* __ED_SCRUBBING_H__ */
+#endif /* __ED_TIME_SCRUB_UI_H__ */
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index cd4cefe8891..5ce9133a531 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -42,6 +42,7 @@ struct GPUFX;
struct GPUFXSettings;
struct GPUOffScreen;
struct GPUViewport;
+struct ID;
struct ImBuf;
struct MVert;
struct Main;
@@ -449,16 +450,9 @@ void ED_view3d_backbuf_depth_validate(struct ViewContext *vc);
int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist);
void ED_view3d_select_id_validate(struct ViewContext *vc);
-void ED_view3d_select_id_validate_with_select_mode(struct ViewContext *vc, short select_mode);
-uint ED_view3d_select_id_sample(struct ViewContext *vc, int x, int y);
-uint *ED_view3d_select_id_read(
- struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax, uint *r_buf_len);
-uint *ED_view3d_select_id_read_rect(struct ViewContext *vc,
- const struct rcti *rect,
- uint *r_buf_len);
-uint ED_view3d_select_id_read_nearest(
- struct ViewContext *vc, const int mval[2], const uint min, const uint max, uint *r_dist);
+uint *ED_view3d_select_id_read(int xmin, int ymin, int xmax, int ymax, uint *r_buf_len);
+uint *ED_view3d_select_id_read_rect(const struct rcti *rect, uint *r_buf_len);
bool ED_view3d_autodist(struct Depsgraph *depsgraph,
struct ARegion *ar,
@@ -590,7 +584,6 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Depsgraph *depsgraph,
int sizex,
int sizey,
unsigned int flag,
- unsigned int draw_flags,
int alpha_mode,
int samples,
const char *viewname,
@@ -621,7 +614,8 @@ void ED_view3d_update_viewmat(struct Depsgraph *depsgraph,
struct ARegion *ar,
float viewmat[4][4],
float winmat[4][4],
- const struct rcti *rect);
+ const struct rcti *rect,
+ bool offscreen);
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
char ED_view3d_lock_view_from_index(int index);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index f54e4d1c61b..048f30bdf26 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -96,8 +96,8 @@ DEF_ICON(PINNED)
DEF_ICON(SCREEN_BACK)
DEF_ICON(RIGHTARROW)
DEF_ICON(DOWNARROW_HLT)
-DEF_ICON_BLANK(103)
-DEF_ICON_BLANK(104)
+DEF_ICON(FCURVE_SNAPSHOT)
+DEF_ICON(OBJECT_HIDDEN)
DEF_ICON_BLANK(105)
DEF_ICON_BLANK(106)
DEF_ICON(PLUGIN)
@@ -699,8 +699,8 @@ DEF_ICON(VIS_SEL_10)
DEF_ICON(VIS_SEL_01)
DEF_ICON(VIS_SEL_00)
DEF_ICON_BLANK(231)
-DEF_ICON(AUTOMERGE_ON)
DEF_ICON(AUTOMERGE_OFF)
+DEF_ICON(AUTOMERGE_ON)
DEF_ICON_BLANK(234)
DEF_ICON(UV_VERTEXSEL)
DEF_ICON(UV_EDGESEL)
@@ -821,9 +821,9 @@ DEF_ICON(FORWARD)
DEF_ICON_BLANK(825)
DEF_ICON_BLANK(826)
DEF_ICON_BLANK(827)
+DEF_ICON(FILE_CACHE)
DEF_ICON(FILE_VOLUME)
-DEF_ICON(ALEMBIC)
-DEF_ICON(VOLUME)
+DEF_ICON(FILE_3D)
DEF_ICON(FILE_HIDDEN)
DEF_ICON(FILE_BACKUP)
DEF_ICON(DISK_DRIVE)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 14d681ee817..bf728ec7772 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -281,6 +281,9 @@ enum {
/** Value is animated, but the current value differs from the animated one. */
UI_BUT_ANIMATED_CHANGED = 1 << 25,
+
+ /* Draw the checkbox buttons inverted. */
+ UI_BUT_CHECKBOX_INVERT = 1 << 26,
};
/* scale fixed button widths by this to account for DPI */
@@ -1627,7 +1630,7 @@ struct Panel *UI_panel_begin(struct ScrArea *sa,
struct PanelType *pt,
struct Panel *pa,
bool *r_open);
-void UI_panel_end(uiBlock *block, int width, int height);
+void UI_panel_end(uiBlock *block, int width, int height, bool open);
void UI_panels_scale(struct ARegion *ar, float new_width);
void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y);
int UI_panel_size_y(const struct Panel *pa);
@@ -1638,6 +1641,7 @@ struct PanelCategoryDyn *UI_panel_category_find(struct ARegion *ar, const char *
struct PanelCategoryStack *UI_panel_category_active_find(struct ARegion *ar, const char *idname);
const char *UI_panel_category_active_get(struct ARegion *ar, bool set_fallback);
void UI_panel_category_active_set(struct ARegion *ar, const char *idname);
+void UI_panel_category_active_set_default(struct ARegion *ar, const char *idname);
struct PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(struct ARegion *ar,
const int x,
const int y);
@@ -1711,14 +1715,28 @@ enum {
UI_ITEM_O_RETURN_PROPS = 1 << 0,
UI_ITEM_R_EXPAND = 1 << 1,
UI_ITEM_R_SLIDER = 1 << 2,
+ /**
+ * Use for booleans, causes the button to draw with an outline (emboss),
+ * instead of text with a checkbox.
+ * This is implied when toggle buttons have an icon
+ * unless #UI_ITEM_R_ICON_NEVER flag is set.
+ */
UI_ITEM_R_TOGGLE = 1 << 3,
- UI_ITEM_R_ICON_ONLY = 1 << 4,
- UI_ITEM_R_EVENT = 1 << 5,
- UI_ITEM_R_FULL_EVENT = 1 << 6,
- UI_ITEM_R_NO_BG = 1 << 7,
- UI_ITEM_R_IMMEDIATE = 1 << 8,
- UI_ITEM_O_DEPRESS = 1 << 9,
- UI_ITEM_R_COMPACT = 1 << 10,
+ /**
+ * Don't attempt to use an icon when the icon is set to #ICON_NONE.
+ *
+ * Use for boolean's, causes the buttons to always show as a checkbox
+ * even when there is an icon (which would normally show the button as a toggle).
+ */
+ UI_ITEM_R_ICON_NEVER = 1 << 4,
+ UI_ITEM_R_ICON_ONLY = 1 << 5,
+ UI_ITEM_R_EVENT = 1 << 6,
+ UI_ITEM_R_FULL_EVENT = 1 << 7,
+ UI_ITEM_R_NO_BG = 1 << 8,
+ UI_ITEM_R_IMMEDIATE = 1 << 9,
+ UI_ITEM_O_DEPRESS = 1 << 10,
+ UI_ITEM_R_COMPACT = 1 << 11,
+ UI_ITEM_R_CHECKBOX_INVERT = 1 << 12,
};
#define UI_HEADER_OFFSET ((void)0, 0.4f * UI_UNIT_X)
@@ -2233,6 +2251,7 @@ void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
/* label icon for dragging */
void uiItemLDrag(uiLayout *layout, struct PointerRNA *ptr, const char *name, int icon);
/* menu */
+void uiItemM_ptr(uiLayout *layout, struct MenuType *mt, const char *name, int icon);
void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon);
/* menu contents */
void uiItemMContents(uiLayout *layout, const char *menuname);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 6dc632921ad..db6bb35560d 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -105,7 +105,7 @@ typedef enum ThemeColorID {
TH_FACE_DOT,
TH_FACEDOT_SIZE,
TH_CFRAME,
- TH_SCRUBBING_BACKGROUND,
+ TH_TIME_SCRUB_BACKGROUND,
TH_TIME_KEYFRAME,
TH_TIME_GP_KEYFRAME,
TH_NURB_ULINE,
diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h
index d03d4b1b4f5..42ac3bb30d8 100644
--- a/source/blender/editors/include/UI_view2d.h
+++ b/source/blender/editors/include/UI_view2d.h
@@ -260,6 +260,6 @@ void UI_view2d_smooth_view(struct bContext *C,
const int smooth_viewtx);
#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC)
-#define UI_SCRUBBING_MARGIN_Y (23 * UI_DPI_FAC)
+#define UI_TIME_SCRUB_MARGIN_Y (23 * UI_DPI_FAC)
#endif /* __UI_VIEW2D_H__ */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index f1724d92402..931a4faa1c0 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1845,6 +1845,9 @@ int ui_but_is_pushed_ex(uiBut *but, double *value)
}
}
+ if ((but->drawflag & UI_BUT_CHECKBOX_INVERT) && (is_push != -1)) {
+ is_push = !((bool)is_push);
+ }
return is_push;
}
int ui_but_is_pushed(uiBut *but)
@@ -2772,7 +2775,7 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
}
else if (type == PROP_POINTER) {
if (str[0] == '\0') {
- RNA_property_pointer_set(NULL, &but->rnapoin, but->rnaprop, PointerRNA_NULL);
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, PointerRNA_NULL, NULL);
return true;
}
else {
@@ -2788,14 +2791,14 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
* Fact remains, using editstr as main 'reference' over whole search button thingy
* is utterly weak and should be redesigned imho, but that's not a simple task. */
if (prop && RNA_property_collection_lookup_string(&ptr, prop, str, &rptr)) {
- RNA_property_pointer_set(NULL, &but->rnapoin, but->rnaprop, rptr);
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
else if (but->func_arg2 != NULL) {
RNA_pointer_create(NULL,
RNA_property_pointer_type(&but->rnapoin, but->rnaprop),
but->func_arg2,
&rptr);
- RNA_property_pointer_set(NULL, &but->rnapoin, but->rnaprop, rptr);
+ RNA_property_pointer_set(&but->rnapoin, but->rnaprop, rptr, NULL);
}
return true;
@@ -3735,6 +3738,16 @@ void ui_def_but_icon(uiBut *but, const int icon, const int flag)
}
}
+/**
+ * Avoid using this where possible since it's better not to ask for an icon in the first place.
+ */
+void ui_def_but_icon_clear(uiBut *but)
+{
+ but->icon = ICON_NONE;
+ but->flag &= ~UI_HAS_ICON;
+ but->drawflag &= ~UI_BUT_ICON_LEFT;
+}
+
static void ui_def_but_rna__disable(uiBut *but, const char *info)
{
but->flag |= UI_BUT_DISABLED;
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 9ef98db49f5..ca35689112f 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -47,6 +47,8 @@
#include "RNA_access.h"
+#include "BPY_extern.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -92,7 +94,7 @@ static const char *shortcut_get_operator_property(bContext *C, uiBut *but, IDPro
{
if (but->optype) {
/* Operator */
- *prop = (but->opptr) ? IDP_CopyProperty(but->opptr->data) : NULL;
+ *prop = (but->opptr && but->opptr->data) ? IDP_CopyProperty(but->opptr->data) : NULL;
return but->optype->idname;
}
else if (but->rnaprop) {
@@ -358,7 +360,31 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um)
if (drawstr[0] == '\0') {
/* Hard code overrides for generic operators. */
if (UI_but_is_tool(but)) {
- RNA_string_get(but->opptr, "name", drawstr);
+ char idname[64];
+ RNA_string_get(but->opptr, "name", idname);
+#ifdef WITH_PYTHON
+ {
+ const char *expr_imports[] = {"bpy", "bl_ui", NULL};
+ char expr[256];
+ SNPRINTF(expr,
+ "bl_ui.space_toolsystem_common.item_from_id("
+ "bpy.context, "
+ "bpy.context.space_data.type, "
+ "'%s').label",
+ idname);
+ char *expr_result = NULL;
+ if (BPY_execute_string_as_string(C, expr_imports, expr, true, &expr_result)) {
+ STRNCPY(drawstr, expr_result);
+ MEM_freeN(expr_result);
+ }
+ else {
+ BLI_assert(0);
+ STRNCPY(drawstr, idname);
+ }
+ }
+#else
+ STRNCPY(drawstr, idname);
+#endif
}
}
ED_screen_user_menu_item_add_operator(
diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c
index 4a2d59c05de..658aa4f67f9 100644
--- a/source/blender/editors/interface/interface_eyedropper_datablock.c
+++ b/source/blender/editors/interface/interface_eyedropper_datablock.c
@@ -207,7 +207,7 @@ static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id)
RNA_id_pointer_create(id, &ptr_value);
- RNA_property_pointer_set(NULL, &ddr->ptr, ddr->prop, ptr_value);
+ RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value, NULL);
RNA_property_update(C, &ddr->ptr, ddr->prop);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index a3b438ece42..b8e97f58c2f 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -556,18 +556,9 @@ static void ui_but_update_preferences_dirty(uiBut *but)
/* Not very elegant, but ensures preference changes force re-save. */
bool tag = false;
if (but->rnaprop) {
- if (but->rnapoin.data == &U) {
- /* Exclude navigation from setting dirty. */
- extern PropertyRNA rna_Preferences_active_section;
- if (!ELEM(but->rnaprop, &rna_Preferences_active_section)) {
- tag = true;
- }
- }
- else {
- StructRNA *base = RNA_struct_base(but->rnapoin.type);
- if (ELEM(base, &RNA_AddonPreferences, &RNA_KeyConfigPreferences)) {
- tag = true;
- }
+ StructRNA *base = RNA_struct_base(but->rnapoin.type);
+ if (ELEM(base, &RNA_AddonPreferences, &RNA_KeyConfigPreferences, &RNA_KeyMapItem)) {
+ tag = true;
}
}
@@ -1744,7 +1735,7 @@ static void ui_selectcontext_apply(bContext *C,
}
else if (rna_type == PROP_POINTER) {
const PointerRNA other_value = delta.p;
- RNA_property_pointer_set(NULL, &lptr, lprop, other_value);
+ RNA_property_pointer_set(&lptr, lprop, other_value, NULL);
}
RNA_property_update(C, &lptr, prop);
@@ -5572,9 +5563,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
if ((int)(but->a1) == UI_PALETTE_COLOR) {
if (!event->ctrl) {
float color[3];
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Paint *paint = BKE_paint_get_active(scene, view_layer);
+ Paint *paint = BKE_paint_get_active_from_context(C);
Brush *brush = BKE_paint_brush(paint);
if (brush->flag & BRUSH_USE_GRADIENT) {
@@ -5589,6 +5578,8 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
}
else {
+ Scene *scene = CTX_data_scene(C);
+
if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
RNA_property_float_get_array(&but->rnapoin, but->rnaprop, color);
BKE_brush_color_set(scene, brush, color);
@@ -6530,7 +6521,7 @@ static int ui_do_but_CURVE(
CurveMap *cuma = cumap->cm + cumap->cur;
CurveMapPoint *cmp;
const float m_xy[2] = {mx, my};
- float dist_min_sq = SQUARE(14.0f); /* 14 pixels radius */
+ float dist_min_sq = SQUARE(U.dpi_fac * 14.0f); /* 14 pixels radius */
int sel = -1;
if (event->ctrl) {
@@ -6565,7 +6556,7 @@ static int ui_do_but_CURVE(
BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[0].x);
/* with 160px height 8px should translate to the old 0.05 coefficient at no zoom */
- dist_min_sq = SQUARE(8.0f);
+ dist_min_sq = SQUARE(U.dpi_fac * 8.0f);
/* loop through the curve segment table and find what's near the mouse. */
for (i = 1; i <= CM_TABLE; i++) {
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index e53e9694617..fa3605269ff 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1086,6 +1086,12 @@ static void free_iconfile_list(struct ListBase *list)
}
}
+#else
+
+void UI_icons_reload_internal_textures(void)
+{
+}
+
#endif /* WITH_HEADLESS */
int UI_iconfile_get_index(const char *filename)
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 33288df15ba..8a2b28ee2d4 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -500,6 +500,7 @@ extern int ui_but_string_get_max_length(uiBut *but);
extern uiBut *ui_but_drag_multi_edit_get(uiBut *but);
void ui_def_but_icon(uiBut *but, const int icon, const int flag);
+void ui_def_but_icon_clear(uiBut *but);
extern uiButExtraIconType ui_but_icon_extra_get(uiBut *but);
extern void ui_but_default_set(struct bContext *C, const bool all, const bool use_afterfunc);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index dc57be4f07f..b89767171ab 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -484,7 +484,7 @@ static void ui_item_array(uiLayout *layout,
int UNUSED(h),
bool expand,
bool slider,
- bool toggle,
+ int toggle,
bool icon_only,
bool compact,
bool show_text)
@@ -691,7 +691,7 @@ static void ui_item_array(uiLayout *layout,
if (slider && but->type == UI_BTYPE_NUM) {
but->type = UI_BTYPE_NUM_SLIDER;
}
- if (toggle && but->type == UI_BTYPE_CHECKBOX) {
+ if ((toggle == 1) && but->type == UI_BTYPE_CHECKBOX) {
but->type = UI_BTYPE_TOGGLE;
}
if ((a == 0) && (subtype == PROP_AXISANGLE)) {
@@ -1858,12 +1858,7 @@ void uiItemFullR(uiLayout *layout,
int icon)
{
uiBlock *block = layout->root->block;
- uiBut *but = NULL;
- PropertyType type;
char namestr[UI_MAX_NAME_STR];
- int len, w, h;
- bool slider, toggle, expand, icon_only, no_bg, compact;
- bool is_array;
const bool use_prop_sep = ((layout->item.flag & UI_ITEM_PROP_SEP) != 0);
/* By default 'use_prop_sep' uses a separate column for labels.
@@ -1888,11 +1883,15 @@ void uiItemFullR(uiLayout *layout,
UI_block_layout_set_current(block, layout);
/* retrieve info */
- type = RNA_property_type(prop);
- is_array = RNA_property_array_check(prop);
- len = (is_array) ? RNA_property_array_length(ptr, prop) : 0;
+ const PropertyType type = RNA_property_type(prop);
+ const bool is_array = RNA_property_array_check(prop);
+ const int len = (is_array) ? RNA_property_array_length(ptr, prop) : 0;
+
+ const bool icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
- icon_only = (flag & UI_ITEM_R_ICON_ONLY) != 0;
+ /* Boolean with -1 to signify that the value depends on the presence of an icon. */
+ const int toggle = ((flag & UI_ITEM_R_TOGGLE) ? 1 : ((flag & UI_ITEM_R_ICON_NEVER) ? 0 : -1));
+ const bool no_icon = (toggle == 0);
/* set name and icon */
if (!name) {
@@ -1904,8 +1903,8 @@ void uiItemFullR(uiLayout *layout,
}
}
- if (icon == ICON_NONE) {
- icon = RNA_property_ui_icon(prop);
+ if (type != PROP_BOOLEAN) {
+ flag &= ~UI_ITEM_R_CHECKBOX_INVERT;
}
if (flag & UI_ITEM_R_ICON_ONLY) {
@@ -1932,56 +1931,66 @@ void uiItemFullR(uiLayout *layout,
}
}
-#ifdef UI_PROP_SEP_ICON_WIDTH_EXCEPTION
- if (use_prop_sep) {
- if (type == PROP_BOOLEAN && (icon == ICON_NONE) && !icon_only) {
- use_prop_sep_split_label = false;
+ if (no_icon == false) {
+ if (icon == ICON_NONE) {
+ icon = RNA_property_ui_icon(prop);
}
- }
-#endif
- /* menus and pie-menus don't show checkbox without this */
- if ((layout->root->type == UI_LAYOUT_MENU) ||
- /* use checkboxes only as a fallback in pie-menu's, when no icon is defined */
- ((layout->root->type == UI_LAYOUT_PIEMENU) && (icon == ICON_NONE))) {
- int prop_flag = RNA_property_flag(prop);
- if (type == PROP_BOOLEAN && ((is_array == false) || (index != RNA_NO_INDEX))) {
- if (prop_flag & PROP_ICONS_CONSECUTIVE) {
- icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
- }
- else if (is_array) {
- icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT :
- ICON_CHECKBOX_DEHLT;
+ /* Menus and pie-menus don't show checkbox without this. */
+ if ((layout->root->type == UI_LAYOUT_MENU) ||
+ /* Use checkboxes only as a fallback in pie-menu's, when no icon is defined. */
+ ((layout->root->type == UI_LAYOUT_PIEMENU) && (icon == ICON_NONE))) {
+ int prop_flag = RNA_property_flag(prop);
+ if (type == PROP_BOOLEAN) {
+ if ((is_array == false) || (index != RNA_NO_INDEX)) {
+ if (prop_flag & PROP_ICONS_CONSECUTIVE) {
+ icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
+ }
+ else if (is_array) {
+ icon = (RNA_property_boolean_get_index(ptr, prop, index)) ? ICON_CHECKBOX_HLT :
+ ICON_CHECKBOX_DEHLT;
+ }
+ else {
+ icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ }
}
- else {
- icon = (RNA_property_boolean_get(ptr, prop)) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ else if (type == PROP_ENUM) {
+ if (index == RNA_ENUM_VALUE) {
+ int enum_value = RNA_property_enum_get(ptr, prop);
+ if (prop_flag & PROP_ICONS_CONSECUTIVE) {
+ icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
+ }
+ else if (prop_flag & PROP_ENUM_FLAG) {
+ icon = (enum_value & value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ else {
+ icon = (enum_value == value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
+ }
+ }
}
}
- else if (type == PROP_ENUM && index == RNA_ENUM_VALUE) {
- int enum_value = RNA_property_enum_get(ptr, prop);
- if (prop_flag & PROP_ICONS_CONSECUTIVE) {
- icon = ICON_CHECKBOX_DEHLT; /* but->iconadd will set to correct icon */
- }
- else if (prop_flag & PROP_ENUM_FLAG) {
- icon = (enum_value & value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
- else {
- icon = (enum_value == value) ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
- }
+ }
+
+#ifdef UI_PROP_SEP_ICON_WIDTH_EXCEPTION
+ if (use_prop_sep) {
+ if (type == PROP_BOOLEAN && (icon == ICON_NONE) && !icon_only) {
+ use_prop_sep_split_label = false;
}
}
+#endif
if ((type == PROP_ENUM) && (RNA_property_flag(prop) & PROP_ENUM_FLAG)) {
flag |= UI_ITEM_R_EXPAND;
}
- slider = (flag & UI_ITEM_R_SLIDER) != 0;
- toggle = (flag & UI_ITEM_R_TOGGLE) != 0;
- expand = (flag & UI_ITEM_R_EXPAND) != 0;
- no_bg = (flag & UI_ITEM_R_NO_BG) != 0;
- compact = (flag & UI_ITEM_R_COMPACT) != 0;
+ const bool slider = (flag & UI_ITEM_R_SLIDER) != 0;
+ const bool expand = (flag & UI_ITEM_R_EXPAND) != 0;
+ const bool no_bg = (flag & UI_ITEM_R_NO_BG) != 0;
+ const bool compact = (flag & UI_ITEM_R_COMPACT) != 0;
/* get size */
+ int w, h;
ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h);
int prev_emboss = layout->emboss;
@@ -1989,6 +1998,8 @@ void uiItemFullR(uiLayout *layout,
layout->emboss = UI_EMBOSS_NONE;
}
+ uiBut *but = NULL;
+
/* Split the label / property. */
uiLayout *layout_parent = layout;
if (use_prop_sep) {
@@ -2156,7 +2167,13 @@ void uiItemFullR(uiLayout *layout,
but->type = UI_BTYPE_NUM_SLIDER;
}
- if (toggle && but->type == UI_BTYPE_CHECKBOX) {
+ if (flag & UI_ITEM_R_CHECKBOX_INVERT) {
+ if (ELEM(but->type, UI_BTYPE_CHECKBOX, UI_BTYPE_CHECKBOX_N)) {
+ but->drawflag |= UI_BUT_CHECKBOX_INVERT;
+ }
+ }
+
+ if ((toggle == 1) && but->type == UI_BTYPE_CHECKBOX) {
but->type = UI_BTYPE_TOGGLE;
}
@@ -2175,6 +2192,18 @@ void uiItemFullR(uiLayout *layout,
}
}
+ /* The resulting button may have the icon set since boolean button drawing
+ * is being 'helpful' and adding an icon for us.
+ * In this case we want the ability not to have an icon.
+ *
+ * We could pass an argument not to set the icon to begin with however this is the one case
+ * the functionality is needed. */
+ if (but && no_icon) {
+ if ((icon == ICON_NONE) && (but->icon != ICON_NONE)) {
+ ui_def_but_icon_clear(but);
+ }
+ }
+
/* Mark non-embossed textfields inside a listbox. */
if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == UI_BTYPE_TEXT) &&
(but->dt & UI_EMBOSS_NONE)) {
@@ -2744,14 +2773,8 @@ static uiBut *ui_item_menu(uiLayout *layout,
return but;
}
-void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
+void uiItemM_ptr(uiLayout *layout, MenuType *mt, const char *name, int icon)
{
- MenuType *mt = WM_menutype_find(menuname, false);
- if (mt == NULL) {
- RNA_warning("not found %s", menuname);
- return;
- }
-
if (!name) {
name = CTX_IFACE_(mt->translation_context, mt->label);
}
@@ -2770,6 +2793,16 @@ void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
false);
}
+void uiItemM(uiLayout *layout, const char *menuname, const char *name, int icon)
+{
+ MenuType *mt = WM_menutype_find(menuname, false);
+ if (mt == NULL) {
+ RNA_warning("not found %s", menuname);
+ return;
+ }
+ uiItemM_ptr(layout, mt, name, icon);
+}
+
void uiItemMContents(uiLayout *layout, const char *menuname)
{
MenuType *mt = WM_menutype_find(menuname, false);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index aa7ff015bad..9c5ce0c9d2c 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -367,7 +367,7 @@ Panel *UI_panel_begin(
return pa;
}
-void UI_panel_end(uiBlock *block, int width, int height)
+void UI_panel_end(uiBlock *block, int width, int height, bool open)
{
Panel *pa = block->panel;
@@ -390,21 +390,21 @@ void UI_panel_end(uiBlock *block, int width, int height)
pa->sizey = height;
}
else {
- /* check if we need to do an animation */
- if (!ELEM(width, 0, pa->sizex) || !ELEM(height, 0, pa->sizey)) {
- pa->runtime_flag |= PNL_ANIM_ALIGN;
- if (height != 0) {
- pa->ofsy += pa->sizey - height;
- }
- }
+ int old_sizex = pa->sizex, old_sizey = pa->sizey;
/* update width/height if non-zero */
if (width != 0) {
pa->sizex = width;
}
- if (height != 0) {
+ if (height != 0 || open) {
pa->sizey = height;
}
+
+ /* check if we need to do an animation */
+ if (pa->sizex != old_sizex || pa->sizey != old_sizey) {
+ pa->runtime_flag |= PNL_ANIM_ALIGN;
+ pa->ofsy += old_sizey - pa->sizey;
+ }
}
}
@@ -1676,28 +1676,7 @@ PanelCategoryStack *UI_panel_category_active_find(ARegion *ar, const char *idnam
return BLI_findstring(&ar->panels_category_active, idname, offsetof(PanelCategoryStack, idname));
}
-const char *UI_panel_category_active_get(ARegion *ar, bool set_fallback)
-{
- PanelCategoryStack *pc_act;
-
- for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) {
- if (UI_panel_category_find(ar, pc_act->idname)) {
- return pc_act->idname;
- }
- }
-
- if (set_fallback) {
- PanelCategoryDyn *pc_dyn = ar->panels_category.first;
- if (pc_dyn) {
- UI_panel_category_active_set(ar, pc_dyn->idname);
- return pc_dyn->idname;
- }
- }
-
- return NULL;
-}
-
-void UI_panel_category_active_set(ARegion *ar, const char *idname)
+static void ui_panel_category_active_set(ARegion *ar, const char *idname, bool fallback)
{
ListBase *lb = &ar->panels_category_active;
PanelCategoryStack *pc_act = UI_panel_category_active_find(ar, idname);
@@ -1710,7 +1689,13 @@ void UI_panel_category_active_set(ARegion *ar, const char *idname)
BLI_strncpy(pc_act->idname, idname, sizeof(pc_act->idname));
}
- BLI_addhead(lb, pc_act);
+ if (fallback) {
+ /* For fallbacks, add at the end so explicitly chosen categories have priority. */
+ BLI_addtail(lb, pc_act);
+ }
+ else {
+ BLI_addhead(lb, pc_act);
+ }
/* validate all active panels, we could do this on load,
* they are harmless - but we should remove somewhere.
@@ -1729,6 +1714,39 @@ void UI_panel_category_active_set(ARegion *ar, const char *idname)
}
}
+void UI_panel_category_active_set(ARegion *ar, const char *idname)
+{
+ ui_panel_category_active_set(ar, idname, false);
+}
+
+void UI_panel_category_active_set_default(ARegion *ar, const char *idname)
+{
+ if (!UI_panel_category_active_find(ar, idname)) {
+ ui_panel_category_active_set(ar, idname, true);
+ }
+}
+
+const char *UI_panel_category_active_get(ARegion *ar, bool set_fallback)
+{
+ PanelCategoryStack *pc_act;
+
+ for (pc_act = ar->panels_category_active.first; pc_act; pc_act = pc_act->next) {
+ if (UI_panel_category_find(ar, pc_act->idname)) {
+ return pc_act->idname;
+ }
+ }
+
+ if (set_fallback) {
+ PanelCategoryDyn *pc_dyn = ar->panels_category.first;
+ if (pc_dyn) {
+ ui_panel_category_active_set(ar, pc_dyn->idname, true);
+ return pc_dyn->idname;
+ }
+ }
+
+ return NULL;
+}
+
PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(ARegion *ar, const int x, const int y)
{
PanelCategoryDyn *ptd;
diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c
index 5b205de21b8..6c780482777 100644
--- a/source/blender/editors/interface/interface_region_tooltip.c
+++ b/source/blender/editors/interface/interface_region_tooltip.c
@@ -883,8 +883,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz)
/* Operator Actions */
{
- bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
-
+ const bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part;
const struct {
int part;
const char *prefix;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 3dbfd3d2f6a..33602818fd4 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -298,7 +298,7 @@ static void template_ID_set_property_cb(bContext *C, void *arg_template, void *i
PointerRNA idptr;
RNA_id_pointer_create(item, &idptr);
- RNA_property_pointer_set(NULL, &template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
}
}
@@ -489,7 +489,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break;
case UI_ID_DELETE:
memset(&idptr, 0, sizeof(idptr));
- RNA_property_pointer_set(NULL, &template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
if (id && CTX_wm_window(C)->eventstate->shift) {
@@ -532,7 +532,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
}
}
- RNA_property_pointer_set(NULL, &template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
}
break;
@@ -541,7 +541,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
BKE_override_static_free(&id->override_static);
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop);
- RNA_property_pointer_set(NULL, &template_ui->ptr, template_ui->prop, idptr);
+ RNA_property_pointer_set(&template_ui->ptr, template_ui->prop, idptr, NULL);
RNA_property_update(C, &template_ui->ptr, template_ui->prop);
}
break;
@@ -1455,7 +1455,7 @@ static void template_search_handle_cb(bContext *C, void *arg_template, void *ite
PointerRNA item_ptr;
RNA_pointer_create(NULL, type, item, &item_ptr);
- RNA_property_pointer_set(NULL, &coll_search->target_ptr, coll_search->target_prop, item_ptr);
+ RNA_property_pointer_set(&coll_search->target_ptr, coll_search->target_prop, item_ptr, NULL);
RNA_property_update(C, &coll_search->target_ptr, coll_search->target_prop);
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 594793371ae..71629d6297c 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1261,7 +1261,9 @@ void UI_widgetbase_draw_cache_flush(void)
(float *)g_widget_base_batch.params);
GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params);
GPU_matrix_bind(batch->interface);
- GPU_batch_draw_range_ex(batch, 0, g_widget_base_batch.count, true);
+ GPU_batch_bind(batch);
+ GPU_batch_draw_advanced(batch, 0, 0, 0, g_widget_base_batch.count);
+
GPU_batch_program_use_end(batch);
}
g_widget_base_batch.count = 0;
@@ -1946,9 +1948,9 @@ static void ui_text_clip_right_label(const uiFontStyle *fstyle, uiBut *but, cons
}
#ifdef WITH_INPUT_IME
-static void widget_draw_text_ime_underline(uiFontStyle *fstyle,
- uiWidgetColors *wcol,
- uiBut *but,
+static void widget_draw_text_ime_underline(const uiFontStyle *fstyle,
+ const uiWidgetColors *wcol,
+ const uiBut *but,
const rcti *rect,
const wmIMEData *ime_data,
const char *drawstr)
@@ -2183,7 +2185,7 @@ static void widget_draw_text(const uiFontStyle *fstyle,
ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) &&
/* if we're editing or multi-drag (fake editing), then use left alignment */
(but->editstr == NULL) && (drawstr == but->drawstr)) {
- drawstr_right = strchr(drawstr + but->ofs, ':');
+ drawstr_right = strrchr(drawstr + but->ofs, ':');
if (drawstr_right) {
drawstr_right++;
drawstr_left_len = (drawstr_right - drawstr);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 06acf59e07c..26beb08dd28 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -309,8 +309,8 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_GRID:
cp = ts->grid;
break;
- case TH_SCRUBBING_BACKGROUND:
- cp = ts->scrubbing_background;
+ case TH_TIME_SCRUB_BACKGROUND:
+ cp = ts->time_scrub_background;
break;
case TH_VIEW_OVERLAY:
cp = ts->view_overlay;
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index f2d4faff479..36b984e229b 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -190,7 +190,7 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
* also have the scrubbing area at the top.
* So the scrollbar has to move down a bit. */
if (scroll & V2D_SCROLL_VERTICAL_HANDLES) {
- v2d->vert.ymax -= UI_SCRUBBING_MARGIN_Y;
+ v2d->vert.ymax -= UI_TIME_SCRUB_MARGIN_Y;
}
/* horizontal scroller */
diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c
index 2568193ee23..43b49825219 100644
--- a/source/blender/editors/interface/view2d_draw.c
+++ b/source/blender/editors/interface/view2d_draw.c
@@ -53,7 +53,7 @@
/* Compute display grid resolution
********************************************************/
-#define MIN_MAJOR_LINE_DISTANCE (UI_DPI_FAC * 50)
+#define MIN_MAJOR_LINE_DISTANCE (U.v2d_min_gridsize * UI_DPI_FAC)
static float select_major_distance(const float *possible_distances,
uint amount,
@@ -267,6 +267,10 @@ static void draw_horizontal_scale_indicators(const ARegion *ar,
void *to_string_data,
int colorid)
{
+ if (UI_view2d_scale_get_x(v2d) <= 0.0f) {
+ return;
+ }
+
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
@@ -318,6 +322,10 @@ static void draw_vertical_scale_indicators(const ARegion *ar,
void *to_string_data,
int colorid)
{
+ if (UI_view2d_scale_get_y(v2d) <= 0.0f) {
+ return;
+ }
+
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index e2b3b6aa8c6..9fdcec71cfd 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -108,7 +108,7 @@ static int cachefile_open_exec(bContext *C, wmOperator *op)
PointerRNA idptr;
RNA_id_pointer_create(&cache_file->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 9796bf89cf3..1f844961d19 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -81,6 +81,9 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
{
char filepath[FILE_MAX];
int apply_modifiers;
+ int global_forward;
+ int global_up;
+ int apply_global_orientation;
int export_mesh_type;
int selected;
int include_children;
@@ -103,7 +106,8 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int use_object_instantiation;
int use_blender_profile;
int sort_by_name;
- int export_transformation_type;
+ int export_object_transformation_type;
+ int export_animation_transformation_type;
int open_sim;
int limit_precision;
@@ -140,6 +144,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
/* Options panel */
apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers");
export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection");
+ global_forward = RNA_enum_get(op->ptr, "export_global_forward_selection");
+ global_up = RNA_enum_get(op->ptr, "export_global_up_selection");
+ apply_global_orientation = RNA_boolean_get(op->ptr, "apply_global_orientation");
+
selected = RNA_boolean_get(op->ptr, "selected");
include_children = RNA_boolean_get(op->ptr, "include_children");
include_armatures = RNA_boolean_get(op->ptr, "include_armatures");
@@ -163,9 +171,13 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
use_blender_profile = RNA_boolean_get(op->ptr, "use_blender_profile");
sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
- export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection");
- open_sim = RNA_boolean_get(op->ptr, "open_sim");
+ export_object_transformation_type = RNA_enum_get(op->ptr,
+ "export_object_transformation_type_selection");
+ export_animation_transformation_type = RNA_enum_get(
+ op->ptr, "export_animation_transformation_type_selection");
+
+ open_sim = RNA_boolean_get(op->ptr, "open_sim");
limit_precision = RNA_boolean_get(op->ptr, "limit_precision");
keep_bind_info = RNA_boolean_get(op->ptr, "keep_bind_info");
@@ -181,6 +193,10 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
export_settings.filepath = filepath;
export_settings.apply_modifiers = apply_modifiers != 0;
+ export_settings.global_forward = global_forward;
+ export_settings.global_up = global_up;
+ export_settings.apply_global_orientation = apply_global_orientation != 0;
+
export_settings.export_mesh_type = export_mesh_type;
export_settings.selected = selected != 0;
export_settings.include_children = include_children != 0;
@@ -201,23 +217,24 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
export_settings.use_object_instantiation = use_object_instantiation != 0;
export_settings.use_blender_profile = use_blender_profile != 0;
export_settings.sort_by_name = sort_by_name != 0;
+ export_settings.object_transformation_type = export_object_transformation_type;
+ export_settings.animation_transformation_type = export_animation_transformation_type;
+ export_settings.keep_smooth_curves = keep_smooth_curves != 0;
- if (export_animation_type == BC_ANIMATION_EXPORT_SAMPLES) {
- export_settings.export_transformation_type = export_transformation_type;
- }
- else {
+ if (export_animation_type != BC_ANIMATION_EXPORT_SAMPLES) {
// When curves are exported then we can not export as matrix
- export_settings.export_transformation_type = BC_TRANSFORMATION_TYPE_TRANSROTLOC;
+ export_settings.animation_transformation_type = BC_TRANSFORMATION_TYPE_DECOMPOSED;
}
- if (export_settings.export_transformation_type == BC_TRANSFORMATION_TYPE_TRANSROTLOC) {
- export_settings.keep_smooth_curves = keep_smooth_curves != 0;
- }
- else {
+ if (export_settings.animation_transformation_type != BC_TRANSFORMATION_TYPE_DECOMPOSED) {
// Can not export smooth curves when Matrix export is enabled.
export_settings.keep_smooth_curves = false;
}
+ if (include_animations) {
+ export_settings.object_transformation_type = export_settings.animation_transformation_type;
+ }
+
export_settings.open_sim = open_sim != 0;
export_settings.limit_precision = limit_precision != 0;
export_settings.keep_bind_info = keep_bind_info != 0;
@@ -250,14 +267,15 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
{
- uiLayout *box, *row, *col, *split;
+ uiLayout *bbox, *box, *row, *col, *split;
bool include_animations = RNA_boolean_get(imfptr, "include_animations");
int ui_section = RNA_enum_get(imfptr, "prop_bc_export_ui_section");
BC_export_animation_type animation_type = RNA_enum_get(imfptr,
"export_animation_type_selection");
- BC_export_transformation_type transformation_type = RNA_enum_get(
- imfptr, "export_transformation_type_selection");
+
+ BC_export_transformation_type animation_transformation_type = RNA_enum_get(
+ imfptr, "export_animation_transformation_type_selection");
bool sampling = animation_type == BC_ANIMATION_EXPORT_SAMPLES;
@@ -272,6 +290,18 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
/* Export Data options */
/* =================== */
+ bbox = uiLayoutBox(layout);
+ row = uiLayoutRow(bbox, false);
+ uiItemL(row, IFACE_("Global Orientation:"), ICON_ORIENTATION_GLOBAL);
+ row = uiLayoutRow(bbox, false);
+ uiItemR(row, imfptr, "export_global_forward_selection", 0, "", ICON_NONE);
+
+ row = uiLayoutRow(bbox, false);
+ uiItemR(row, imfptr, "export_global_up_selection", 0, "", ICON_NONE);
+
+ row = uiLayoutRow(bbox, false);
+ uiItemR(row, imfptr, "apply_global_orientation", 0, NULL, ICON_NONE);
+
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "selected", 0, NULL, ICON_NONE);
@@ -287,6 +317,8 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "include_shapekeys", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row, RNA_boolean_get(imfptr, "selected"));
+ row = uiLayoutRow(box, false);
+
/* Texture options */
box = uiLayoutBox(layout);
row = uiLayoutRow(box, false);
@@ -304,13 +336,26 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
+
col = uiLayoutColumn(split, false);
uiItemR(col, imfptr, "apply_modifiers", 0, NULL, ICON_NONE);
+
col = uiLayoutColumn(split, false);
uiItemR(col, imfptr, "export_mesh_type_selection", 0, "", ICON_NONE);
uiLayoutSetEnabled(col, RNA_boolean_get(imfptr, "apply_modifiers"));
+
+ col = uiLayoutColumn(box, false);
+ uiItemR(col, imfptr, "triangulate", 1, NULL, ICON_NONE);
+
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "triangulate", 1, NULL, ICON_NONE);
+ split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
+ uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
+ if (RNA_boolean_get(imfptr, "include_animations")) {
+ uiItemR(split, imfptr, "export_animation_transformation_type_selection", 0, "", ICON_NONE);
+ }
+ else {
+ uiItemR(split, imfptr, "export_object_transformation_type_selection", 0, "", ICON_NONE);
+ }
}
else if (ui_section == BC_UI_SECTION_ARMATURE) {
/* Armature options */
@@ -335,18 +380,24 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "export_animation_type_selection", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ uiLayoutSetEnabled(row, include_animations);
row = uiLayoutRow(box, false);
split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
- uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
- uiLayoutSetEnabled(row, animation_type == BC_ANIMATION_EXPORT_SAMPLES);
+ if (RNA_boolean_get(imfptr, "include_animations")) {
+ uiItemR(split, imfptr, "export_animation_transformation_type_selection", 0, "", ICON_NONE);
+ }
+ else {
+ uiItemR(split, imfptr, "export_object_transformation_type_selection", 0, "", ICON_NONE);
+ }
+ uiLayoutSetEnabled(row, include_animations && animation_type == BC_ANIMATION_EXPORT_SAMPLES);
row = uiLayoutColumn(box, false);
uiItemR(row, imfptr, "keep_smooth_curves", 0, NULL, ICON_NONE);
uiLayoutSetEnabled(row,
include_animations &&
- (transformation_type == BC_TRANSFORMATION_TYPE_TRANSROTLOC ||
+ (animation_transformation_type == BC_TRANSFORMATION_TYPE_DECOMPOSED ||
animation_type == BC_ANIMATION_EXPORT_KEYS));
row = uiLayoutColumn(box, false);
@@ -359,6 +410,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutColumn(box, false);
uiItemR(row, imfptr, "keep_flat_curves", 0, NULL, ICON_NONE);
+ uiLayoutSetEnabled(row, include_animations);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "include_all_actions", 0, NULL, ICON_NONE);
@@ -418,17 +470,37 @@ void WM_OT_collada_export(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL},
};
+ static const EnumPropertyItem prop_bc_export_global_forward[] = {
+ {BC_GLOBAL_FORWARD_X, "X", 0, "X Forward", "Global Forward is positive X Axis"},
+ {BC_GLOBAL_FORWARD_Y, "Y", 0, "Y Forward", "Global Forward is positive Y Axis"},
+ {BC_GLOBAL_FORWARD_Z, "Z", 0, "Z Forward", "Global Forward is positive Z Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_X, "-X", 0, "-X Forward", "Global Forward is negative X Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_Y, "-Y", 0, "-Y Forward", "Global Forward is negative Y Axis"},
+ {BC_GLOBAL_FORWARD_MINUS_Z, "-Z", 0, "-Z Forward", "Global Forward is negative Z Axis"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ static const EnumPropertyItem prop_bc_export_global_up[] = {
+ {BC_GLOBAL_UP_X, "X", 0, "X Up", "Global UP is positive X Axis"},
+ {BC_GLOBAL_UP_Y, "Y", 0, "Y Up", "Global UP is positive Y Axis"},
+ {BC_GLOBAL_UP_Z, "Z", 0, "Z Up", "Global UP is positive Z Axis"},
+ {BC_GLOBAL_UP_MINUS_X, "-X", 0, "-X Up", "Global UP is negative X Axis"},
+ {BC_GLOBAL_UP_MINUS_Y, "-Y", 0, "-Y Up", "Global UP is negative Y Axis"},
+ {BC_GLOBAL_UP_MINUS_Z, "-Z", 0, "-Z Up", "Global UP is negative Z Axis"},
+ {0, NULL, 0, NULL, NULL},
+ };
+
static const EnumPropertyItem prop_bc_export_transformation_type[] = {
{BC_TRANSFORMATION_TYPE_MATRIX,
"matrix",
0,
"Matrix",
- "Use <matrix> to specify transformations"},
- {BC_TRANSFORMATION_TYPE_TRANSROTLOC,
- "transrotloc",
+ "Use <matrix> representation for exported transformations"},
+ {BC_TRANSFORMATION_TYPE_DECOMPOSED,
+ "decomposed",
0,
- "TransRotLoc",
- "Use <translate>, <rotate>, <scale> to specify transformations"},
+ "Decomposed",
+ "Use <rotate>, <translate> and <scale> representation for exported transformations"},
{0, NULL, 0, NULL, NULL}};
static const EnumPropertyItem prop_bc_export_animation_type[] = {
@@ -503,6 +575,27 @@ void WM_OT_collada_export(wmOperatorType *ot)
"Resolution",
"Modifier resolution for export");
+ RNA_def_enum(func,
+ "export_global_forward_selection",
+ prop_bc_export_global_forward,
+ BC_DEFAULT_FORWARD,
+ "Global Forward Axis",
+ "Global Forward axis for export");
+
+ RNA_def_enum(func,
+ "export_global_up_selection",
+ prop_bc_export_global_up,
+ BC_DEFAULT_UP,
+ "Global Up Axis",
+ "Global Up axis for export");
+
+ RNA_def_boolean(func,
+ "apply_global_orientation",
+ false,
+ "Apply Global Orientation",
+ "enabled: Rotate all root objects to match the global orientation "
+ "settings.\ndisabled: set global orientation in Collada assets");
+
RNA_def_boolean(func, "selected", false, "Selection Only", "Export only selected elements");
RNA_def_boolean(func,
@@ -611,21 +704,42 @@ void WM_OT_collada_export(wmOperatorType *ot)
func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name");
RNA_def_int(func,
- "export_transformation_type",
+ "export_object_transformation_type",
+ 0,
+ INT_MIN,
+ INT_MAX,
+ "Transform",
+ "Object Transformation type for translation, scale and rotation",
+ INT_MIN,
+ INT_MAX);
+
+ RNA_def_enum(func,
+ "export_object_transformation_type_selection",
+ prop_bc_export_transformation_type,
+ 0,
+ "Transform",
+ "Object Transformation type for translation, scale and rotation");
+
+ RNA_def_int(func,
+ "export_animation_transformation_type",
0,
INT_MIN,
INT_MAX,
"Transform",
- "Transformation type for translation, scale and rotation",
+ "Transformation type for translation, scale and rotation\n"
+ "Note: The Animation transformation type in the Anim Tab\n"
+ "is always equal to the Object transformation type in the Geom tab",
INT_MIN,
INT_MAX);
RNA_def_enum(func,
- "export_transformation_type_selection",
+ "export_animation_transformation_type_selection",
prop_bc_export_transformation_type,
0,
"Transform",
- "Transformation type for translation, scale and rotation");
+ "Transformation type for translation, scale and rotation\n"
+ "Note: The Animation transformation type in the Anim Tab\n"
+ "is always equal to the Object transformation type in the Geom tab");
RNA_def_boolean(func,
"open_sim",
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 3c456f9e2e2..fc85eab6e66 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -29,6 +29,7 @@
#include "BKE_mask.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -47,7 +48,7 @@
#include "mask_intern.h" /* own include */
bool ED_mask_find_nearest_diff_point(const bContext *C,
- struct Mask *mask,
+ struct Mask *mask_orig,
const float normal_co[2],
int threshold,
bool feather,
@@ -63,7 +64,7 @@ bool ED_mask_find_nearest_diff_point(const bContext *C,
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- MaskLayer *masklay, *point_masklay;
+ MaskLayer *point_masklay;
MaskSpline *point_spline;
MaskSplinePoint *point = NULL;
float dist_best_sq = FLT_MAX, co[2];
@@ -71,31 +72,36 @@ bool ED_mask_find_nearest_diff_point(const bContext *C,
float u = 0.0f;
float scalex, scaley;
+ Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
ED_mask_get_size(sa, &width, &height);
ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);
co[0] = normal_co[0] * scalex;
co[1] = normal_co[1] * scaley;
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- MaskSpline *spline;
-
- if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ for (MaskLayer *masklay_orig = mask_orig->masklayers.first,
+ *masklay_eval = mask_eval->masklayers.first;
+ masklay_orig != NULL;
+ masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) {
+ if (masklay_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
continue;
}
- for (spline = masklay->splines.first; spline; spline = spline->next) {
+ for (MaskSpline *spline_orig = masklay_orig->splines.first,
+ *spline_eval = masklay_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
int i;
- MaskSplinePoint *cur_point;
+ MaskSplinePoint *cur_point_eval;
- for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points;
- i < spline->tot_point;
- i++, cur_point++) {
- float *diff_points;
+ for (i = 0, cur_point_eval = use_deform ? spline_eval->points_deform : spline_eval->points;
+ i < spline_eval->tot_point;
+ i++, cur_point_eval++) {
unsigned int tot_diff_point;
-
- diff_points = BKE_mask_point_segment_diff(
- spline, cur_point, width, height, &tot_diff_point);
+ float *diff_points = BKE_mask_point_segment_diff(
+ spline_eval, cur_point_eval, width, height, &tot_diff_point);
if (diff_points) {
int j, tot_point;
@@ -104,7 +110,7 @@ bool ED_mask_find_nearest_diff_point(const bContext *C,
if (feather) {
feather_points = BKE_mask_point_segment_feather_diff(
- spline, cur_point, width, height, &tot_feather_point);
+ spline_eval, cur_point_eval, width, height, &tot_feather_point);
points = feather_points;
tot_point = tot_feather_point;
@@ -130,19 +136,19 @@ bool ED_mask_find_nearest_diff_point(const bContext *C,
sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]);
}
- point_masklay = masklay;
- point_spline = spline;
- point = use_deform ? &spline->points[(cur_point - spline->points_deform)] :
- cur_point;
+ point_masklay = masklay_orig;
+ point_spline = spline_orig;
+ point = use_deform ?
+ &spline_orig->points[(cur_point_eval - spline_eval->points_deform)] :
+ &spline_orig->points[(cur_point_eval - spline_eval->points)];
dist_best_sq = dist_sq;
u = (float)j / tot_point;
}
}
- if (feather_points) {
+ if (feather_points != NULL) {
MEM_freeN(feather_points);
}
-
MEM_freeN(diff_points);
}
}
@@ -580,7 +586,6 @@ static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, co
static int add_vertex_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *masklay;
@@ -626,8 +631,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
BKE_mask_calc_handle_point_auto(spline, point, false);
BKE_mask_calc_handle_point_auto(spline, point_other, false);
- /* TODO: only update this spline */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
return OPERATOR_FINISHED;
@@ -648,8 +652,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
}
}
- /* TODO: only update this spline */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
return OPERATOR_FINISHED;
}
@@ -716,7 +719,6 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op)
if (ED_mask_find_nearest_diff_point(
C, mask, co, threshold, true, NULL, true, true, &masklay, &spline, &point, &u, NULL)) {
- Scene *scene = CTX_data_scene(C);
float w = BKE_mask_point_weight(spline, point, u);
float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u);
@@ -726,12 +728,10 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op)
BKE_mask_point_add_uw(point, u, w);
- BKE_mask_update_display(mask, scene->r.cfra);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- DEG_id_tag_update(&mask->id, 0);
-
return OPERATOR_FINISHED;
}
@@ -786,7 +786,6 @@ static int create_primitive_from_points(
bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type)
{
ScrArea *sa = CTX_wm_area(C);
- Scene *scene = CTX_data_scene(C);
Mask *mask;
MaskLayer *mask_layer;
MaskSpline *new_spline;
@@ -848,8 +847,7 @@ static int create_primitive_from_points(
}
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
- /* TODO: only update this spline */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 305e3a328ab..33e89b1a7c5 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -52,6 +52,8 @@
#include "UI_resources.h"
#include "UI_view2d.h"
+#include "DEG_depsgraph_query.h"
+
#include "mask_intern.h" /* own include */
static void mask_spline_color_get(MaskLayer *masklay,
@@ -672,7 +674,8 @@ static float *mask_rasterize(Mask *mask, const int width, const int height)
/* sets up the opengl context.
* width, height are to match the values from ED_mask_get_size() */
void ED_mask_draw_region(
- Mask *mask,
+ Depsgraph *depsgraph,
+ Mask *mask_,
ARegion *ar,
const char draw_flag,
const char draw_type,
@@ -690,6 +693,7 @@ void ED_mask_draw_region(
const bContext *C)
{
struct View2D *v2d = &ar->v2d;
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_->id);
/* aspect always scales vertically in movie and image spaces */
const float width = width_i, height = (float)height_i * (aspy / aspx);
@@ -735,7 +739,7 @@ void ED_mask_draw_region(
if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
float red[4] = {1.0f, 0.0f, 0.0f, 0.0f};
- float *buffer = mask_rasterize(mask, width, height);
+ float *buffer = mask_rasterize(mask_eval, width, height);
if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
/* More blending types could be supported in the future. */
@@ -779,7 +783,7 @@ void ED_mask_draw_region(
}
/* draw! */
- draw_masklays(C, mask, draw_flag, draw_type, width, height);
+ draw_masklays(C, mask_eval, draw_flag, draw_type, width, height);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 1f825c0bb31..5a7a84dbbc8 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -31,6 +31,7 @@
#include "BKE_mask.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
@@ -65,7 +66,7 @@ static void mask_point_scaled_handle(/*const*/ MaskSplinePoint *point,
}
MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
- Mask *mask,
+ Mask *mask_orig,
const float normal_co[2],
const float threshold,
MaskLayer **masklay_r,
@@ -76,7 +77,6 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- MaskLayer *masklay;
MaskLayer *point_masklay = NULL;
MaskSpline *point_spline = NULL;
MaskSplinePoint *point = NULL;
@@ -86,29 +86,35 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE;
int width, height;
+ Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
ED_mask_get_size(sa, &width, &height);
ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);
co[0] = normal_co[0] * scalex;
co[1] = normal_co[1] * scaley;
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- MaskSpline *spline;
+ for (MaskLayer *masklay_orig = mask_orig->masklayers.first,
+ *masklay_eval = mask_eval->masklayers.first;
+ masklay_orig != NULL;
+ masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) {
- if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ if (masklay_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
continue;
}
- for (spline = masklay->splines.first; spline; spline = spline->next) {
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
-
- int i;
+ for (MaskSpline *spline_orig = masklay_orig->splines.first,
+ *spline_eval = masklay_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval);
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *cur_point = &spline->points[i];
- MaskSplinePoint *cur_point_deform = &points_array[i];
+ for (int i = 0; i < spline_orig->tot_point; i++) {
+ MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
+ MaskSplinePoint *cur_point_deform_eval = &points_array[i];
eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE;
- BezTriple *bezt = &cur_point_deform->bezt;
+ BezTriple *bezt = &cur_point_deform_eval->bezt;
float cur_len_sq, vec[2];
vec[0] = bezt->vec[1][0] * scalex;
@@ -117,17 +123,17 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
cur_len_sq = len_squared_v2v2(co, vec);
if (cur_len_sq < len_sq) {
- point_spline = spline;
- point_masklay = masklay;
- point = cur_point;
+ point_spline = spline_orig;
+ point_masklay = masklay_orig;
+ point = cur_point_orig;
len_sq = cur_len_sq;
which_handle = MASK_WHICH_HANDLE_NONE;
}
- if (BKE_mask_point_handles_mode_get(cur_point_deform) == MASK_HANDLE_MODE_STICK) {
+ if (BKE_mask_point_handles_mode_get(cur_point_deform_eval) == MASK_HANDLE_MODE_STICK) {
float handle[2];
mask_point_scaled_handle(
- cur_point_deform, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle);
+ cur_point_deform_eval, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle);
cur_len_sq = len_squared_v2v2(co, handle);
cur_which_handle = MASK_WHICH_HANDLE_STICK;
}
@@ -135,9 +141,9 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
float handle_left[2], handle_right[2];
float len_left_sq, len_right_sq;
mask_point_scaled_handle(
- cur_point_deform, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left);
+ cur_point_deform_eval, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left);
mask_point_scaled_handle(
- cur_point_deform, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right);
+ cur_point_deform_eval, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right);
len_left_sq = len_squared_v2v2(co, handle_left);
len_right_sq = len_squared_v2v2(co, handle_right);
@@ -168,9 +174,9 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
}
if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) {
- point_masklay = masklay;
- point_spline = spline;
- point = cur_point;
+ point_masklay = masklay_orig;
+ point_spline = spline_orig;
+ point = cur_point_orig;
len_sq = cur_len_sq;
which_handle = cur_which_handle;
}
@@ -214,7 +220,7 @@ MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C,
}
bool ED_mask_feather_find_nearest(const bContext *C,
- Mask *mask,
+ Mask *mask_orig,
const float normal_co[2],
const float threshold,
MaskLayer **masklay_r,
@@ -226,7 +232,7 @@ bool ED_mask_feather_find_nearest(const bContext *C,
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
- MaskLayer *masklay, *point_masklay = NULL;
+ MaskLayer *point_masklay = NULL;
MaskSpline *point_spline = NULL;
MaskSplinePoint *point = NULL;
MaskSplinePointUW *uw = NULL;
@@ -235,32 +241,41 @@ bool ED_mask_feather_find_nearest(const bContext *C,
float scalex, scaley;
int width, height;
+ Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C);
+ Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id);
+
ED_mask_get_size(sa, &width, &height);
ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley);
co[0] = normal_co[0] * scalex;
co[1] = normal_co[1] * scaley;
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- MaskSpline *spline;
+ for (MaskLayer *masklay_orig = mask_orig->masklayers.first,
+ *masklay_eval = mask_eval->masklayers.first;
+ masklay_orig != NULL;
+ masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) {
- for (spline = masklay->splines.first; spline; spline = spline->next) {
+ for (MaskSpline *spline_orig = masklay_orig->splines.first,
+ *spline_eval = masklay_eval->splines.first;
+ spline_orig != NULL;
+ spline_orig = spline_orig->next, spline_eval = spline_eval->next) {
// MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
int i, tot_feather_point;
float(*feather_points)[2], (*fp)[2];
- if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
+ if (masklay_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
continue;
}
- feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point);
+ feather_points = fp = BKE_mask_spline_feather_points(spline_eval, &tot_feather_point);
- for (i = 0; i < spline->tot_point; i++) {
+ for (i = 0; i < spline_orig->tot_point; i++) {
int j;
- MaskSplinePoint *cur_point = &spline->points[i];
+ MaskSplinePoint *cur_point_orig = &spline_orig->points[i];
+ MaskSplinePoint *cur_point_eval = &spline_eval->points[i];
- for (j = 0; j <= cur_point->tot_uw; j++) {
+ for (j = 0; j <= cur_point_eval->tot_uw; j++) {
float cur_len_sq, vec[2];
vec[0] = (*fp)[0] * scalex;
@@ -273,12 +288,12 @@ bool ED_mask_feather_find_nearest(const bContext *C,
uw = NULL;
}
else {
- uw = &cur_point->uw[j - 1];
+ uw = &cur_point_eval->uw[j - 1];
}
- point_masklay = masklay;
- point_spline = spline;
- point = cur_point;
+ point_masklay = masklay_orig;
+ point_spline = spline_orig;
+ point = cur_point_orig;
len = cur_len_sq;
}
@@ -1648,7 +1663,6 @@ static void delete_feather_points(MaskSplinePoint *point)
static int delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *masklay;
bool changed = false;
@@ -1743,8 +1757,7 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
- /* TODO: only update edited splines */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
@@ -1801,8 +1814,7 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op))
}
if (changed) {
- /* TODO: only update this spline */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
@@ -1867,8 +1879,7 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op)
}
if (changed) {
- /* TODO: only update this spline */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
@@ -2094,7 +2105,6 @@ void MASK_OT_hide_view_set(wmOperatorType *ot)
static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *masklay;
bool changed = false;
@@ -2121,8 +2131,7 @@ static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op))
}
if (changed) {
- /* TODO: only update edited splines */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask);
DEG_id_tag_update(&mask->id, 0);
@@ -2234,7 +2243,6 @@ void MASK_OT_layer_move(wmOperatorType *ot)
static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer;
@@ -2324,8 +2332,7 @@ static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
}
}
- /* TODO: only update edited splines */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
@@ -2391,7 +2398,6 @@ static bool paste_splines_poll(bContext *C)
static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer = BKE_mask_layer_active(mask);
@@ -2401,8 +2407,7 @@ static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op))
BKE_mask_clipboard_paste_to_layer(CTX_data_main(C), mask_layer);
- /* TODO: only update edited splines */
- BKE_mask_update_display(mask, CFRA);
+ DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index a592f39d24b..717ce9fd72e 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -43,6 +43,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "DEG_depsgraph.h"
+
#include "mask_intern.h" /* own include */
/* -------------------------------------------------------------------- */
@@ -223,6 +225,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
ED_mask_select_toggle_all(mask, action);
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -326,6 +329,7 @@ static int select_exec(bContext *C, wmOperator *op)
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -365,6 +369,7 @@ static int select_exec(bContext *C, wmOperator *op)
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -374,6 +379,7 @@ static int select_exec(bContext *C, wmOperator *op)
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -488,6 +494,7 @@ static int box_select_exec(bContext *C, wmOperator *op)
if (changed) {
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -592,6 +599,7 @@ static bool do_lasso_select_mask(bContext *C,
if (changed) {
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
}
@@ -719,6 +727,7 @@ static int circle_select_exec(bContext *C, wmOperator *op)
if (changed) {
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -783,6 +792,7 @@ static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
if (changed) {
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -840,6 +850,7 @@ static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op))
if (changed) {
ED_mask_select_flush_all(mask);
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
@@ -940,6 +951,7 @@ static int mask_select_more_less(bContext *C, bool more)
}
}
+ DEG_id_tag_update(&mask->id, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index fdbcc3449b2..d61c340f7a2 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -441,74 +441,6 @@ bool paintface_mouse_select(
return true;
}
-bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op)
-{
- Object *ob = vc->obact;
- Mesh *me;
-
- me = BKE_mesh_from_object(ob);
- if ((me == NULL) || (me->totpoly == 0)) {
- return false;
- }
-
- bool changed = false;
- if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
- changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
- }
-
- if (BLI_rcti_is_empty(rect)) {
- /* pass */
- }
- else {
- MPoly *mpoly;
- uint *rt, *buf, buf_len;
- int a, index;
-
- char *selar = MEM_callocN(me->totpoly + 1, "selar");
-
- ED_view3d_select_id_validate(vc);
- buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
-
- rt = buf;
-
- a = buf_len;
- while (a--) {
- if (*rt) {
- index = *rt;
- if (index <= me->totpoly) {
- selar[index] = 1;
- }
- }
- rt++;
- }
-
- mpoly = me->mpoly;
- for (a = 1; a <= me->totpoly; a++, mpoly++) {
- if ((mpoly->flag & ME_HIDE) == 0) {
- const bool is_select = mpoly->flag & ME_FACE_SEL;
- const bool is_inside = (selar[a] != 0);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
- changed = true;
- }
- }
- }
-
- MEM_freeN(buf);
- MEM_freeN(selar);
-
-#ifdef __APPLE__
- glReadBuffer(GL_BACK);
-#endif
- }
-
- if (changed) {
- paintface_flush_flags(vc->C, vc->obact, SELECT);
- }
- return changed;
-}
-
/* (similar to void paintface_flush_flags(Object *ob))
* copy the vertex flags, most importantly selection from the mesh to the final derived mesh,
* use in object mode when selecting vertices (while painting) */
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index bc60ff9274f..1d173d8e396 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -148,7 +148,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
BisectData *opdata;
opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data");
- gesture->userdata = opdata;
+ gesture->user_data.data = opdata;
opdata->backup_len = objects_len;
opdata->backup = MEM_callocN(sizeof(*opdata->backup) * objects_len, __func__);
@@ -193,7 +193,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata)
static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
- BisectData *opdata = gesture->userdata;
+ BisectData *opdata = gesture->user_data.data;
BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */
int ret;
@@ -276,7 +276,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op)
}
wmGesture *gesture = op->customdata;
- BisectData *opdata = (gesture != NULL) ? gesture->userdata : NULL;
+ BisectData *opdata = (gesture != NULL) ? gesture->user_data.data : NULL;
/* -------------------------------------------------------------------- */
/* Modal support */
diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
index 269ead7b23f..74700e59e99 100644
--- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
+++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c
@@ -295,7 +295,8 @@ static void gizmo_mesh_spin_init_draw_prepare(const bContext *C, wmGizmoGroup *g
static void gizmo_mesh_spin_init_invoke_prepare(const bContext *UNUSED(C),
wmGizmoGroup *gzgroup,
- wmGizmo *gz)
+ wmGizmo *gz,
+ const wmEvent *UNUSED(event))
{
/* Set the initial ortho axis. */
GizmoGroupData_SpinInit *ggd = gzgroup->customdata;
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index e45c15b3e53..976dbe01a22 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1156,19 +1156,20 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GPU_batch_bind(batch);
/* draw any snapped verts first */
rgba_uchar_to_float(fcol, kcd->colors.point_a);
GPU_batch_uniform_4fv(batch, "color", fcol);
GPU_matrix_bind(batch->interface);
GPU_point_size(11);
- GPU_batch_draw_range_ex(batch, 0, v - 1, false);
+ GPU_batch_draw_advanced(batch, 0, v - 1, 0, 0);
/* now draw the rest */
rgba_uchar_to_float(fcol, kcd->colors.curpoint_a);
GPU_batch_uniform_4fv(batch, "color", fcol);
GPU_point_size(7);
- GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false);
+ GPU_batch_draw_advanced(batch, vs + 1, kcd->totlinehit - (vs + 1), 0, 0);
GPU_batch_program_use_end(batch);
GPU_batch_discard(batch);
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index f8ec4334427..6fd0ee83b6c 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -63,6 +63,15 @@
/** \name Path Select Struct & Properties
* \{ */
+enum {
+ EDGE_MODE_SELECT = 0,
+ EDGE_MODE_TAG_SEAM = 1,
+ EDGE_MODE_TAG_SHARP = 2,
+ EDGE_MODE_TAG_CREASE = 3,
+ EDGE_MODE_TAG_BEVEL = 4,
+ EDGE_MODE_TAG_FREESTYLE = 5,
+};
+
struct PathSelectParams {
/** ensure the active element is the last selected item (handy for picking) */
bool track_active;
@@ -75,6 +84,23 @@ struct PathSelectParams {
static void path_select_properties(wmOperatorType *ot)
{
+ static const EnumPropertyItem edge_tag_items[] = {
+ {EDGE_MODE_SELECT, "SELECT", 0, "Select", ""},
+ {EDGE_MODE_TAG_SEAM, "SEAM", 0, "Tag Seam", ""},
+ {EDGE_MODE_TAG_SHARP, "SHARP", 0, "Tag Sharp", ""},
+ {EDGE_MODE_TAG_CREASE, "CREASE", 0, "Tag Crease", ""},
+ {EDGE_MODE_TAG_BEVEL, "BEVEL", 0, "Tag Bevel", ""},
+ {EDGE_MODE_TAG_FREESTYLE, "FREESTYLE", 0, "Tag Freestyle Edge Mark", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+
+ RNA_def_enum(ot->srna,
+ "edge_mode",
+ edge_tag_items,
+ EDGE_MODE_SELECT,
+ "Edge Tag",
+ "The edge flag to tag when selecting the shortest path");
+
RNA_def_boolean(ot->srna,
"use_face_step",
false,
@@ -93,9 +119,24 @@ static void path_select_properties(wmOperatorType *ot)
WM_operator_properties_checker_interval(ot, true);
}
-static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *op_params)
+static void path_select_params_from_op(wmOperator *op,
+ ToolSettings *ts,
+ struct PathSelectParams *op_params)
{
- op_params->edge_mode = EDGE_MODE_SELECT;
+ {
+ PropertyRNA *prop = RNA_struct_find_property(op->ptr, "edge_mode");
+ if (RNA_property_is_set(op->ptr, prop)) {
+ op_params->edge_mode = RNA_property_enum_get(op->ptr, prop);
+ if (op->flag & OP_IS_INVOKE) {
+ ts->edge_mode = op_params->edge_mode;
+ }
+ }
+ else {
+ op_params->edge_mode = ts->edge_mode;
+ RNA_property_enum_set(op->ptr, prop, op_params->edge_mode);
+ }
+ }
+
op_params->track_active = false;
op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step");
op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill");
@@ -103,6 +144,21 @@ static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *
WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params);
}
+static bool path_select_poll_property(const bContext *C,
+ wmOperator *UNUSED(op),
+ const PropertyRNA *prop)
+{
+ const char *prop_id = RNA_property_identifier(prop);
+ if (STREQ(prop_id, "edge_mode")) {
+ const Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ if ((ts->selectmode & SCE_SELECT_EDGE) == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
struct UserData {
BMesh *bm;
Mesh *me;
@@ -319,7 +375,7 @@ static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode)
/* mesh shortest path select, uses prev-selected edge */
/* since you want to create paths with multiple selects, it doesn't have extend option */
-static void mouse_mesh_shortest_path_edge(Scene *UNUSED(scene),
+static void mouse_mesh_shortest_path_edge(Scene *scene,
Object *obedit,
const struct PathSelectParams *op_params,
BMEdge *e_act,
@@ -421,6 +477,10 @@ static void mouse_mesh_shortest_path_edge(Scene *UNUSED(scene),
}
EDBM_update_generic(em, false, false);
+
+ if (op_params->edge_mode == EDGE_MODE_TAG_SEAM) {
+ ED_uvedit_live_unwrap(scene, &obedit, 1);
+ }
}
/** \} */
@@ -649,12 +709,14 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
return OPERATOR_FINISHED;
}
+ struct PathSelectParams op_params;
+ path_select_params_from_op(op, vc.scene->toolsettings, &op_params);
+
BMElem *ele_src, *ele_dst;
if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
!(ele_dst = edbm_elem_find_nearest(&vc, ele_src->head.htype))) {
/* special case, toggle edge tags even when we don't have a path */
- if (((em->selectmode & SCE_SELECT_EDGE) &&
- (vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) &&
+ if (((em->selectmode & SCE_SELECT_EDGE) && (op_params.edge_mode != EDGE_MODE_SELECT)) &&
/* check if we only have a destination edge */
((ele_src == NULL) && (ele_dst = edbm_elem_find_nearest(&vc, BM_EDGE)))) {
ele_src = ele_dst;
@@ -665,11 +727,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
}
}
- struct PathSelectParams op_params;
-
- path_select_params_from_op(op, &op_params);
op_params.track_active = track_active;
- op_params.edge_mode = vc.scene->toolsettings->edge_mode;
if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) {
return OPERATOR_PASS_THROUGH;
@@ -707,9 +765,8 @@ static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op)
}
struct PathSelectParams op_params;
- path_select_params_from_op(op, &op_params);
+ path_select_params_from_op(op, scene->toolsettings, &op_params);
op_params.track_active = true;
- op_params.edge_mode = scene->toolsettings->edge_mode;
if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) {
return OPERATOR_CANCELLED;
@@ -731,6 +788,7 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot)
ot->invoke = edbm_shortest_path_pick_invoke;
ot->exec = edbm_shortest_path_pick_exec;
ot->poll = ED_operator_editmesh_region_view3d;
+ ot->poll_property = path_select_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -832,7 +890,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op)
if (ele_src && ele_dst) {
struct PathSelectParams op_params;
- path_select_params_from_op(op, &op_params);
+ path_select_params_from_op(op, scene->toolsettings, &op_params);
edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst);
@@ -860,6 +918,7 @@ void MESH_OT_shortest_path_select(wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_shortest_path_select_exec;
ot->poll = ED_operator_editmesh;
+ ot->poll_property = path_select_poll_property;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 485d855e18e..6a91fcb8327 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -53,6 +53,7 @@
#include "ED_mesh.h"
#include "ED_screen.h"
#include "ED_transform.h"
+#include "ED_select_buffer_utils.h"
#include "ED_select_utils.h"
#include "ED_view3d.h"
@@ -199,8 +200,19 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag)
* \{ */
struct EDBMBaseOffset {
- uint face;
- uint edge;
+ /* For convenience only. */
+ union {
+ uint offset;
+ uint face_start;
+ };
+ union {
+ uint face;
+ uint edge_start;
+ };
+ union {
+ uint edge;
+ uint vert_start;
+ };
uint vert;
};
@@ -209,18 +221,21 @@ struct EDBMSelectID_Context {
/** Borrow from caller (not freed). */
struct Base **bases;
uint bases_len;
+ /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */
+ uint base_array_index_len;
};
static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt)
{
if (select_mode & SCE_SELECT_FACE) {
- if (dt < OB_SOLID) {
+ if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) {
return true;
}
if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) {
return true;
}
- if (XRAY_FLAG_ENABLED(v3d)) {
+ if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) {
+ /* Since we can't deduce face selection when edges aren't visible - show dots. */
return true;
}
}
@@ -234,7 +249,7 @@ static void edbm_select_pick_draw_bases(struct EDBMSelectID_Context *sel_id_ctx,
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id);
DRW_framebuffer_select_id_setup(vc->ar, true);
- uint offset = 0;
+ uint offset = 1;
for (uint base_index = 0; base_index < sel_id_ctx->bases_len; base_index++) {
Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph,
sel_id_ctx->bases[base_index]->object);
@@ -252,9 +267,12 @@ static void edbm_select_pick_draw_bases(struct EDBMSelectID_Context *sel_id_ctx,
&base_ofs->edge,
&base_ofs->face);
+ base_ofs->offset = offset;
offset = base_ofs->vert;
}
+ sel_id_ctx->base_array_index_len = offset;
+
DRW_framebuffer_select_id_release(vc->ar);
}
@@ -262,28 +280,26 @@ BMElem *EDBM_select_id_bm_elem_get(struct EDBMSelectID_Context *sel_id_ctx,
const uint sel_id,
uint *r_base_index)
{
- char elem_type;
+ char elem_type = 0;
uint elem_id;
- uint prev_offs = 0;
uint base_index = 0;
for (; base_index < sel_id_ctx->bases_len; base_index++) {
struct EDBMBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index];
if (base_ofs->face > sel_id) {
- elem_id = sel_id - (prev_offs + 1);
+ elem_id = sel_id - base_ofs->face_start;
elem_type = BM_FACE;
break;
}
if (base_ofs->edge > sel_id) {
- elem_id = sel_id - base_ofs->face;
+ elem_id = sel_id - base_ofs->edge_start;
elem_type = BM_EDGE;
break;
}
if (base_ofs->vert > sel_id) {
- elem_id = sel_id - base_ofs->edge;
+ elem_id = sel_id - base_ofs->vert_start;
elem_type = BM_VERT;
break;
}
- prev_offs = base_ofs->vert;
}
if (r_base_index) {
@@ -306,9 +322,32 @@ BMElem *EDBM_select_id_bm_elem_get(struct EDBMSelectID_Context *sel_id_ctx,
}
}
+uint EDBM_select_id_context_offset_for_object_elem(const struct EDBMSelectID_Context *sel_id_ctx,
+ int base_index,
+ char htype)
+{
+ struct EDBMBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index];
+ if (htype == BM_VERT) {
+ return base_ofs->vert_start - 1;
+ }
+ if (htype == BM_EDGE) {
+ return base_ofs->edge_start - 1;
+ }
+ if (htype == BM_FACE) {
+ return base_ofs->face_start - 1;
+ }
+ BLI_assert(0);
+ return 0;
+}
+
+uint EDBM_select_id_context_elem_len(const struct EDBMSelectID_Context *sel_id_ctx)
+{
+ return sel_id_ctx->base_array_index_len;
+}
+
struct EDBMSelectID_Context *EDBM_select_id_context_create(ViewContext *vc,
Base **bases,
- uint bases_len,
+ const uint bases_len,
short select_mode)
{
struct EDBMSelectID_Context *sel_id_ctx = MEM_mallocN(sizeof(*sel_id_ctx), __func__);
@@ -328,192 +367,6 @@ void EDBM_select_id_context_destroy(struct EDBMSelectID_Context *sel_id_ctx)
MEM_freeN(sel_id_ctx);
}
-/* set in view3d_draw_legacy.c ... for colorindices */
-unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0;
-
-/* facilities for box select and circle select */
-static BLI_bitmap *selbuf = NULL;
-
-static BLI_bitmap *edbm_backbuf_alloc(const int size)
-{
- return BLI_BITMAP_NEW(size, "selbuf");
-}
-
-/* reads rect, and builds selection array for quick lookup */
-/* returns if all is OK */
-bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
-{
- uint *buf, *dr, buf_len;
-
- if (vc->obedit == NULL || XRAY_FLAG_ENABLED(vc->v3d)) {
- return false;
- }
-
- ED_view3d_select_id_validate(vc);
- buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
- if ((buf == NULL) || (bm_vertoffs == 0)) {
- return false;
- }
-
- dr = buf;
-
- /* build selection lookup */
- selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
-
- while (buf_len--) {
- if (*dr > 0 && *dr <= bm_vertoffs) {
- BLI_BITMAP_ENABLE(selbuf, *dr);
- }
- dr++;
- }
- MEM_freeN(buf);
- return true;
-}
-
-bool EDBM_backbuf_check(unsigned int index)
-{
- /* odd logic, if selbuf is NULL we assume no zbuf-selection is enabled
- * and just ignore the depth buffer, this is error prone since its possible
- * code doesn't set the depth buffer by accident, but leave for now. - Campbell */
- if (selbuf == NULL) {
- return true;
- }
-
- if (index > 0 && index <= bm_vertoffs) {
- return BLI_BITMAP_TEST_BOOL(selbuf, index);
- }
-
- return false;
-}
-
-void EDBM_backbuf_free(void)
-{
- if (selbuf) {
- MEM_freeN(selbuf);
- }
- selbuf = NULL;
-}
-
-struct LassoMaskData {
- unsigned int *px;
- int width;
-};
-
-static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
-{
- struct LassoMaskData *data = user_data;
- unsigned int *px = &data->px[(y * data->width) + x];
- do {
- *px = true;
- px++;
- } while (++x != x_end);
-}
-
-/* mcords is a polygon mask
- * - grab backbuffer,
- * - draw with black in backbuffer,
- * - grab again and compare
- * returns 'OK'
- */
-bool EDBM_backbuf_border_mask_init(ViewContext *vc,
- const int mcords[][2],
- short tot,
- short xmin,
- short ymin,
- short xmax,
- short ymax)
-{
- uint *buf, *dr, *dr_mask, *dr_mask_arr, buf_len;
- struct LassoMaskData lasso_mask_data;
-
- /* method in use for face selecting too */
- if (vc->obedit == NULL) {
- if (!BKE_paint_select_elem_test(vc->obact)) {
- return false;
- }
- }
- else if (XRAY_FLAG_ENABLED(vc->v3d)) {
- return false;
- }
-
- ED_view3d_select_id_validate(vc);
- buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len);
- if ((buf == NULL) || (bm_vertoffs == 0)) {
- return false;
- }
-
- dr = buf;
-
- dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf_len, __func__);
- lasso_mask_data.px = dr_mask;
- lasso_mask_data.width = (xmax - xmin) + 1;
-
- BLI_bitmap_draw_2d_poly_v2i_n(
- xmin, ymin, xmax + 1, ymax + 1, mcords, tot, edbm_mask_lasso_px_cb, &lasso_mask_data);
-
- /* build selection lookup */
- selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
-
- while (buf_len--) {
- if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) {
- BLI_BITMAP_ENABLE(selbuf, *dr);
- }
- dr++;
- dr_mask++;
- }
- MEM_freeN(buf);
- MEM_freeN(dr_mask_arr);
-
- return true;
-}
-
-/* circle shaped sample area */
-bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
-{
- uint *buf, *dr;
- short xmin, ymin, xmax, ymax, xc, yc;
- int radsq;
-
- /* method in use for face selecting too */
- if (vc->obedit == NULL) {
- if (!BKE_paint_select_elem_test(vc->obact)) {
- return false;
- }
- }
- else if (XRAY_FLAG_ENABLED(vc->v3d)) {
- return false;
- }
-
- xmin = xs - rads;
- xmax = xs + rads;
- ymin = ys - rads;
- ymax = ys + rads;
-
- ED_view3d_select_id_validate(vc);
- buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL);
- if ((buf == NULL) || (bm_vertoffs == 0)) {
- return false;
- }
-
- dr = buf;
-
- /* build selection lookup */
- selbuf = edbm_backbuf_alloc(bm_vertoffs + 1);
- radsq = rads * rads;
- for (yc = -rads; yc <= rads; yc++) {
- for (xc = -rads; xc <= rads; xc++, dr++) {
- if (xc * xc + yc * yc < radsq) {
- if (*dr > 0 && *dr <= bm_vertoffs) {
- BLI_BITMAP_ENABLE(selbuf, *dr);
- }
- }
- }
- }
-
- MEM_freeN(buf);
- return true;
-}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -625,7 +478,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create(
vc, bases, bases_len, select_mode);
- index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
+ index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px);
if (index) {
eve = (BMVert *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index);
@@ -652,7 +505,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
}
else {
struct NearestVertUserData data = {{0}};
- const struct NearestVertUserData_Hit *hit;
+ const struct NearestVertUserData_Hit *hit = NULL;
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
BMesh *prev_select_bm = NULL;
@@ -697,6 +550,10 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc,
}
}
+ if (hit == NULL) {
+ return NULL;
+ }
+
prev_select.index = hit->index;
prev_select.elem = hit->vert;
prev_select.bm = prev_select_bm;
@@ -850,7 +707,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create(
vc, bases, bases_len, select_mode);
- index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px);
+ index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px);
if (index) {
eed = (BMEdge *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index);
@@ -899,7 +756,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
}
else {
struct NearestEdgeUserData data = {{0}};
- const struct NearestEdgeUserData_Hit *hit;
+ const struct NearestEdgeUserData_Hit *hit = NULL;
/* interpolate along the edge before doing a clipping plane test */
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB;
BMesh *prev_select_bm = NULL;
@@ -946,6 +803,10 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc,
}
}
+ if (hit == NULL) {
+ return NULL;
+ }
+
if (r_dist_center) {
*r_dist_center = hit->dist_center;
}
@@ -1059,7 +920,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create(
vc, bases, bases_len, select_mode);
- index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]);
+ index = ED_select_buffer_sample_point(vc->mval);
if (index) {
efa = (BMFace *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index);
@@ -1108,7 +969,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
}
else {
struct NearestFaceUserData data = {{0}};
- const struct NearestFaceUserData_Hit *hit;
+ const struct NearestFaceUserData_Hit *hit = NULL;
const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT;
BMesh *prev_select_bm = NULL;
@@ -1153,6 +1014,10 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc,
}
}
+ if (hit == NULL) {
+ return NULL;
+ }
+
if (r_dist_center) {
*r_dist_center = hit->dist;
}
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 331be744932..60c6994eb2e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -7688,6 +7688,7 @@ static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMesh *bm = em->bm;
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
@@ -8077,7 +8078,7 @@ void MESH_OT_point_normals(struct wmOperatorType *ot)
ot->exec = edbm_point_normals_exec;
ot->invoke = edbm_point_normals_invoke;
ot->modal = edbm_point_normals_modal;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
ot->ui = edbm_point_normals_ui;
ot->cancel = point_normals_free;
@@ -8243,6 +8244,7 @@ static int normals_split_merge(bContext *C, const bool do_merge)
BMEdge *e;
BMIter eiter;
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm) : NULL;
@@ -8288,7 +8290,7 @@ void MESH_OT_merge_normals(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_merge_normals_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8308,7 +8310,7 @@ void MESH_OT_split_normals(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_split_normals_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8346,6 +8348,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op)
BMLoop *l, *l_curr, *l_first;
BMIter fiter;
+ BKE_editmesh_ensure_autosmooth(em);
bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
BKE_editmesh_lnorspace_update(em);
@@ -8506,7 +8509,7 @@ void MESH_OT_average_normals(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_average_normals_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
ot->ui = edbm_average_normals_ui;
/* flags */
@@ -8569,6 +8572,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
const int mode = RNA_enum_get(op->ptr, "mode");
const bool absolute = RNA_boolean_get(op->ptr, "absolute");
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata;
@@ -8725,7 +8729,7 @@ void MESH_OT_normals_tools(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_normals_tools_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
ot->ui = edbm_normals_tools_ui;
/* flags */
@@ -8765,6 +8769,7 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp");
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, __func__);
@@ -8830,6 +8835,7 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op)
MEM_freeN(vnors);
EDBM_update_generic(em, true, false);
}
+ MEM_freeN(objects);
return OPERATOR_FINISHED;
}
@@ -8843,7 +8849,7 @@ void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_set_normals_from_faces_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -8860,6 +8866,7 @@ static int edbm_smoothen_normals_exec(bContext *C, wmOperator *op)
BMLoop *l;
BMIter fiter, liter;
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm);
@@ -8935,7 +8942,7 @@ void MESH_OT_smoothen_normals(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_smoothen_normals_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -9018,7 +9025,7 @@ void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot)
/* api callbacks */
ot->exec = edbm_mod_weighted_strength_exec;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index e29cfa6b6e0..41736fb9a14 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -61,6 +61,7 @@
#include "DEG_depsgraph_query.h"
#include "ED_mesh.h"
+#include "ED_select_buffer_utils.h"
#include "ED_object.h"
#include "ED_view3d.h"
@@ -1114,11 +1115,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px,
if (dist_px) {
/* sample rect to increase chances of selecting, so that when clicking
* on an edge in the backbuf, we can still select a face */
- *r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px);
+ *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totpoly + 1, &dist_px);
}
else {
/* sample only on the exact position */
- *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]);
+ *r_index = ED_select_buffer_sample_point(mval);
}
if ((*r_index) == 0 || (*r_index) > (unsigned int)me->totpoly) {
@@ -1295,11 +1296,11 @@ bool ED_mesh_pick_vert(
if (dist_px > 0) {
/* sample rect to increase chances of selecting, so that when clicking
* on an face in the backbuf, we can still select a vert */
- *r_index = ED_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px);
+ *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totvert + 1, &dist_px);
}
else {
/* sample only on the exact position */
- *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]);
+ *r_index = ED_select_buffer_sample_point(mval);
}
if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) {
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 293b3a57fdb..dc2a353bd86 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1962,7 +1962,7 @@ static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Objec
if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
/* We need 'for render' ON here, to enable computing bevel dipslist if needed.
* Also makes sense anyway, we would not want e.g. to loose hidden parts etc. */
- BKE_displist_make_curveTypes(depsgraph, scene, ob, true, false, NULL);
+ BKE_displist_make_curveTypes(depsgraph, scene, ob, true, false);
}
else if (ob->type == OB_MBALL) {
BKE_displist_make_mball(depsgraph, scene, ob);
@@ -1970,13 +1970,30 @@ static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Objec
}
}
-static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
+static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob)
{
- convert_ensure_curve_cache(depsgraph, scene, ob);
- BKE_mesh_from_nurbs(bmain, ob); /* also does users */
+ Object *object_eval = DEG_get_evaluated_object(depsgraph, ob);
+ Curve *curve = ob->data;
+ Mesh *mesh = BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object_eval, true);
+ BKE_object_free_modifiers(ob, 0);
+ /* Replace curve used by the object itself. */
+ ob->data = mesh;
+ ob->type = OB_MESH;
+ id_us_min(&curve->id);
+ id_us_plus(&mesh->id);
+ /* Change objects which are using same curve.
+ * A bit annoying, but:
+ * - It's possible to have multiple curve objects selected which are sharing the same curve
+ * datablock. We don't want mesh to be created for every of those objects.
+ * - This is how conversion worked for a long long time. */
+ LISTBASE_FOREACH (Object *, other_object, &bmain->objects) {
+ if (other_object->data == curve) {
+ other_object->type = OB_MESH;
- if (ob->type == OB_MESH) {
- BKE_object_free_modifiers(ob, 0);
+ id_us_min((ID *)other_object->data);
+ other_object->data = ob->data;
+ id_us_plus((ID *)other_object->data);
+ }
}
}
@@ -2052,7 +2069,8 @@ static int convert_exec(bContext *C, wmOperator *op)
FOREACH_SCENE_OBJECT_END;
}
- ListBase selected_editable_bases = CTX_data_collection_get(C, "selected_editable_bases");
+ ListBase selected_editable_bases;
+ CTX_data_selected_editable_bases(C, &selected_editable_bases);
/* Ensure we get all meshes calculated with a sufficient data-mask,
* needed since re-evaluating single modifiers causes bugs if they depend
@@ -2232,7 +2250,7 @@ static int convert_exec(bContext *C, wmOperator *op)
BKE_curve_curve_dimension_update(cu);
if (target == OB_MESH) {
- curvetomesh(bmain, depsgraph, scene, newob);
+ curvetomesh(bmain, depsgraph, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
@@ -2256,7 +2274,7 @@ static int convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
- curvetomesh(bmain, depsgraph, scene, newob);
+ curvetomesh(bmain, depsgraph, newob);
/* meshes doesn't use displist */
BKE_object_free_curve_cache(newob);
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index f87342a14ad..2f5a4b44412 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -707,7 +707,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re
/* create new mesh with edit mode changes and modifiers applied */
static Mesh *bake_mesh_new_from_object(Object *object)
{
- Mesh *me = BKE_object_to_mesh(object);
+ Mesh *me = BKE_object_to_mesh(NULL, object, false);
if (me->flag & ME_AUTOSMOOTH) {
BKE_mesh_split_faces(me, true);
@@ -946,7 +946,7 @@ static int bake(Render *re,
md = md_next;
}
- me_cage = BKE_object_to_mesh(ob_low_eval);
+ me_cage = BKE_object_to_mesh(NULL, ob_low_eval, false);
RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
}
@@ -965,7 +965,7 @@ static int bake(Render *re,
highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER);
- highpoly[i].me = BKE_object_to_mesh(highpoly[i].ob_eval);
+ highpoly[i].me = BKE_object_to_mesh(NULL, highpoly[i].ob_eval, false);
/* lowpoly to highpoly transformation matrix */
copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
@@ -1088,7 +1088,7 @@ static int bake(Render *re,
}
/* Evaluate modifiers again. */
- me_nores = BKE_object_to_mesh(ob_low_eval);
+ me_nores = BKE_object_to_mesh(NULL, ob_low_eval, false);
RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);
RE_bake_normal_world_to_tangent(pixel_array_low,
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index e555f0d940d..8d3a636671a 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -108,7 +108,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object *
BKE_displist_make_mball(depsgraph, scene_eval, ob_eval);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false, NULL);
+ BKE_displist_make_curveTypes(depsgraph, scene_eval, ob_eval, false, false);
}
}
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index e15d85a7953..6df012cdc80 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -697,7 +697,7 @@ bool ED_object_parent_set(ReportList *reports,
cu->flag |= CU_PATH | CU_FOLLOW;
cu_eval->flag |= CU_PATH | CU_FOLLOW;
/* force creation of path data */
- BKE_displist_make_curveTypes(depsgraph, scene, par, false, false, NULL);
+ BKE_displist_make_curveTypes(depsgraph, scene, par, false, false);
}
else {
cu->flag |= CU_FOLLOW;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 8836d913475..00f5dffb3cc 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -1335,6 +1335,11 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
BKE_object_batch_cache_dirty_tag(tob);
DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
}
+ /* special support for dupligroups */
+ else if (tob->instance_collection && tob->instance_collection->id.tag & LIB_TAG_DOIT) {
+ DEG_id_tag_update(&tob->id, ID_RECALC_TRANSFORM);
+ DEG_id_tag_update(&tob->instance_collection->id, ID_RECALC_COPY_ON_WRITE);
+ }
}
if (tot_change) {
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 342c6269419..20229b63258 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -114,7 +114,6 @@ typedef struct OGLRender {
GPUOffScreen *ofs;
int ofs_samples;
- bool ofs_full_samples;
int sizex, sizey;
int write_still;
@@ -356,9 +355,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
ImBuf *ibuf_view;
const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
- unsigned int draw_flags = V3D_OFSDRAW_NONE;
- draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
-
if (view_context) {
ibuf_view = ED_view3d_draw_offscreen_imbuf(depsgraph,
scene,
@@ -368,7 +364,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
sizex,
sizey,
IB_rectfloat,
- draw_flags,
alpha_mode,
oglrender->ofs_samples,
viewname,
@@ -381,7 +376,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
}
}
else {
- draw_flags |= V3D_OFSDRAW_SHOW_ANNOTATION;
ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
scene,
NULL,
@@ -390,7 +384,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
oglrender->sizex,
oglrender->sizey,
IB_rectfloat,
- draw_flags,
+ V3D_OFSDRAW_SHOW_ANNOTATION,
alpha_mode,
oglrender->ofs_samples,
viewname,
@@ -532,6 +526,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
const bool is_animation = RNA_boolean_get(op->ptr, "animation");
const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+ const int samples = U.ogl_multisamples;
char err_out[256] = "unknown";
if (G.background) {
@@ -576,7 +571,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
/* corrects render size with actual size, not every card supports non-power-of-two dimensions */
DRW_opengl_context_enable(); /* Offscreen creation needs to be done in DRW context. */
- ofs = GPU_offscreen_create(sizex, sizey, 0, true, true, err_out);
+ ofs = GPU_offscreen_create(sizex, sizey, samples, true, true, err_out);
DRW_opengl_context_disable();
if (!ofs) {
@@ -597,6 +592,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
oglrender->view_layer = CTX_data_view_layer(C);
oglrender->depsgraph = CTX_data_depsgraph(C);
oglrender->cfrao = scene->r.cfra;
+ oglrender->ofs_samples = samples;
oglrender->write_still = is_write_still && !is_animation;
oglrender->is_animation = is_animation;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 8819b7a541d..f7a1d7187f1 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -595,7 +595,7 @@ static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
id_us_min(&ma->id);
RNA_id_pointer_create(&ma->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
@@ -644,7 +644,7 @@ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
id_us_min(&tex->id);
RNA_id_pointer_create(&tex->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
@@ -695,7 +695,7 @@ static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
id_us_min(&wo->id);
RNA_id_pointer_create(&wo->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index c2f9beb5d78..83058f2bc95 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -1612,9 +1612,9 @@ static void ed_default_handlers(
keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0);
WM_event_add_keymap_handler_poll(handlers, keymap, event_in_markers_region);
- /* time-scrubbing */
- keymap = WM_keymap_ensure(wm->defaultconf, "Scrubbing", 0, 0);
- WM_event_add_keymap_handler_poll(handlers, keymap, ED_event_in_scrubbing_region);
+ /* time-scrub */
+ keymap = WM_keymap_ensure(wm->defaultconf, "Time Scrub", 0, 0);
+ WM_event_add_keymap_handler_poll(handlers, keymap, ED_time_scrub_event_in_region);
/* frame changing and timeline operators (for time spaces) */
keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0);
@@ -2292,7 +2292,7 @@ static void ed_panel_draw(const bContext *C,
}
}
- UI_panel_end(block, w, h);
+ UI_panel_end(block, w, h, open);
}
/**
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index c60469e092f..6a5df8a3776 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -69,15 +69,10 @@ const char *screen_context_dir[] = {
"scene",
"view_layer",
"visible_objects",
- "visible_bases",
"selectable_objects",
- "selectable_bases",
"selected_objects",
- "selected_bases",
"editable_objects",
- "editable_bases",
"selected_editable_objects",
- "selected_editable_bases",
"objects_in_mode",
"objects_in_mode_unique_data",
"visible_bones",
@@ -89,7 +84,6 @@ const char *screen_context_dir[] = {
"selected_pose_bones_from_active_object",
"active_bone",
"active_pose_bone",
- "active_base",
"active_object",
"object",
"edit_object",
@@ -179,52 +173,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
return 1;
}
- else if (CTX_data_equals(member, "visible_bases")) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_VISIBLE(v3d, base)) {
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selectable_bases")) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTABLE(v3d, base)) {
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selected_bases")) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTED(v3d, base)) {
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "selected_editable_bases")) {
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_SELECTED_EDITABLE(v3d, base)) {
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
- else if (CTX_data_equals(member, "editable_bases")) {
- /* Visible + Editable, but not necessarily selected */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (BASE_EDITABLE(v3d, base)) {
- CTX_data_list_add(result, &scene->id, &RNA_ObjectBase, base);
- }
- }
- CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
- return 1;
- }
else if (CTX_data_equals(member, "objects_in_mode")) {
if (obact && (obact->mode != OB_MODE_OBJECT)) {
FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, obact->type, obact->mode, ob_iter) {
@@ -455,13 +403,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
return 1;
}
}
- else if (CTX_data_equals(member, "active_base")) {
- if (view_layer->basact) {
- CTX_data_pointer_set(result, &scene->id, &RNA_ObjectBase, view_layer->basact);
- }
-
- return 1;
- }
else if (CTX_data_equals(member, "active_object")) {
if (obact) {
CTX_data_id_pointer_set(result, &obact->id);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 07a87982890..3a90532aa56 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -675,6 +675,12 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2])
bool do_draw = false;
for (ar = area_iter->regionbase.first; ar; ar = ar->next) {
+
+ /* call old area's deactivate if assigned */
+ if (ar == old_ar && area_iter->type->deactivate) {
+ area_iter->type->deactivate(area_iter);
+ }
+
if (ar == old_ar || ar == scr->active_region) {
do_draw = true;
}
diff --git a/source/blender/editors/screen/screen_user_menu.c b/source/blender/editors/screen/screen_user_menu.c
index 0ec989db12b..08b9d010f79 100644
--- a/source/blender/editors/screen/screen_user_menu.c
+++ b/source/blender/editors/screen/screen_user_menu.c
@@ -194,6 +194,10 @@ void ED_screen_user_menu_item_remove(ListBase *lb, bUserMenuItem *umi)
static void screen_user_menu_draw(const bContext *C, Menu *menu)
{
+ /* Enable when we have the ability to edit menus. */
+ const bool show_missing = false;
+ char label[512];
+
uint um_array_len;
bUserMenu **um_array = ED_screen_user_menus_find(C, &um_array_len);
bool is_empty = true;
@@ -206,15 +210,32 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
const char *ui_name = umi->ui_name[0] ? umi->ui_name : NULL;
if (umi->type == USER_MENU_TYPE_OPERATOR) {
bUserMenuItem_Op *umi_op = (bUserMenuItem_Op *)umi;
- IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
- uiItemFullO(
- menu->layout, umi_op->op_idname, ui_name, ICON_NONE, prop, umi_op->opcontext, 0, NULL);
- is_empty = false;
+ wmOperatorType *ot = WM_operatortype_find(umi_op->op_idname, false);
+ if (ot != NULL) {
+ IDProperty *prop = umi_op->prop ? IDP_CopyProperty(umi_op->prop) : NULL;
+ uiItemFullO_ptr(menu->layout, ot, ui_name, ICON_NONE, prop, umi_op->opcontext, 0, NULL);
+ is_empty = false;
+ }
+ else {
+ if (show_missing) {
+ SNPRINTF(label, "Missing: %s", umi_op->op_idname);
+ uiItemL(menu->layout, label, ICON_NONE);
+ }
+ }
}
else if (umi->type == USER_MENU_TYPE_MENU) {
bUserMenuItem_Menu *umi_mt = (bUserMenuItem_Menu *)umi;
- uiItemM(menu->layout, umi_mt->mt_idname, ui_name, ICON_NONE);
- is_empty = false;
+ MenuType *mt = WM_menutype_find(umi_mt->mt_idname, false);
+ if (mt != NULL) {
+ uiItemM_ptr(menu->layout, mt, ui_name, ICON_NONE);
+ is_empty = false;
+ }
+ else {
+ if (show_missing) {
+ SNPRINTF(label, "Missing: %s", umi_mt->mt_idname);
+ uiItemL(menu->layout, label, ICON_NONE);
+ }
+ }
}
else if (umi->type == USER_MENU_TYPE_PROP) {
bUserMenuItem_Prop *umi_pr = (bUserMenuItem_Prop *)umi;
@@ -252,9 +273,10 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
}
}
if (!ok) {
- char label[512];
- SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
- uiItemL(menu->layout, label, ICON_NONE);
+ if (show_missing) {
+ SNPRINTF(label, "Missing: %s.%s", umi_pr->context_data_path, umi_pr->prop_id);
+ uiItemL(menu->layout, label, ICON_NONE);
+ }
}
}
else if (umi->type == USER_MENU_TYPE_SEP) {
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d7553d18d3b..303c3fac363 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -6188,7 +6188,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
w,
h,
IB_rect,
- V3D_OFSDRAW_NONE,
R_ALPHAPREMUL,
0,
NULL,
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 84b4a130183..c8ad1b5781d 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -71,6 +71,7 @@
#include "BLI_sys_types.h"
#include "ED_mesh.h" /* for face mask functions */
+#include "ED_select_buffer_utils.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -390,7 +391,7 @@ static int imapaint_pick_face(ViewContext *vc,
/* sample only on the exact position */
ED_view3d_select_id_validate(vc);
- *r_index = ED_view3d_select_id_sample(vc, mval[0], mval[1]);
+ *r_index = ED_select_buffer_sample_point(mval);
if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
return 0;
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index c904bf2005b..b6a6c897606 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -695,7 +695,7 @@ static void gradientVertInit__mapFunc(void *userData,
static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
- WPGradient_vertStoreBase *vert_cache = gesture->userdata;
+ WPGradient_vertStoreBase *vert_cache = gesture->user_data.data;
int ret = WM_gesture_straightline_modal(C, op, event);
if (ret & OPERATOR_RUNNING_MODAL) {
@@ -751,15 +751,15 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
WPGradient_userData data = {NULL};
if (is_interactive) {
- if (gesture->userdata == NULL) {
- gesture->userdata = MEM_mallocN(sizeof(WPGradient_vertStoreBase) +
- (sizeof(WPGradient_vertStore) * me->totvert),
- __func__);
- gesture->userdata_free = false;
+ if (gesture->user_data.data == NULL) {
+ gesture->user_data.data = MEM_mallocN(sizeof(WPGradient_vertStoreBase) +
+ (sizeof(WPGradient_vertStore) * me->totvert),
+ __func__);
+ gesture->user_data.use_free = false;
data.is_init = true;
wpaint_prev_create(
- &((WPGradient_vertStoreBase *)gesture->userdata)->wpp, me->dvert, me->totvert);
+ &((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, me->dvert, me->totvert);
/* on init only, convert face -> vert sel */
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
@@ -767,7 +767,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
}
}
- vert_cache = gesture->userdata;
+ vert_cache = gesture->user_data.data;
}
else {
if (ED_wpaint_ensure_data(C, op->reports, 0, NULL) == false) {
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 692681cecb7..381173999c4 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -136,7 +136,7 @@ static int sound_open_exec(bContext *C, wmOperator *op)
id_us_min(&sound->id);
RNA_id_pointer_create(&sound->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
diff --git a/source/blender/editors/space_action/action_data.c b/source/blender/editors/space_action/action_data.c
index d3e5c011579..bc7f8a0f79d 100644
--- a/source/blender/editors/space_action/action_data.c
+++ b/source/blender/editors/space_action/action_data.c
@@ -155,7 +155,7 @@ static void actedit_change_action(bContext *C, bAction *act)
RNA_id_pointer_create((ID *)act, &idptr);
/* set the new pointer, and force a refresh */
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
@@ -261,7 +261,7 @@ static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
* NOTE: we can't use actedit_change_action, as this function is also called from the NLA
*/
RNA_id_pointer_create(&action->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
@@ -619,7 +619,7 @@ void ED_animedit_unlink_action(
prop = RNA_struct_find_property(&ptr, "action");
/* clear... */
- RNA_property_pointer_set(NULL, &ptr, prop, PointerRNA_NULL);
+ RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL, NULL);
RNA_property_update(C, &ptr, prop);
}
}
diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c
index 972f19bb643..3c879b03126 100644
--- a/source/blender/editors/space_action/space_action.c
+++ b/source/blender/editors/space_action/space_action.c
@@ -237,7 +237,7 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
/* scrubbing region */
- ED_scrubbing_draw(ar, scene, saction->flag & SACTION_DRAWTIME, true);
+ ED_time_scrub_draw(ar, scene, saction->flag & SACTION_DRAWTIME, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@@ -281,7 +281,7 @@ static void action_channel_region_draw(const bContext *C, ARegion *ar)
}
/* channel filter next to scrubbing area */
- ED_channel_search_draw(C, ar, ac.ads);
+ ED_time_scrub_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c
index c985d61a8b8..2496b16ffae 100644
--- a/source/blender/editors/space_clip/clip_buttons.c
+++ b/source/blender/editors/space_clip/clip_buttons.c
@@ -808,12 +808,13 @@ void uiTemplateMovieclipInformation(uiLayout *layout,
user = userptr->data;
col = uiLayoutColumn(layout, false);
+ uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_RIGHT);
ibuf = BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, MOVIECLIP_CACHE_SKIP);
/* Display frame dimensions, channels number and byffer type. */
BKE_movieclip_get_size(clip, user, &width, &height);
- ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("Size %d x %d"), width, height);
+ ofs += BLI_snprintf(str + ofs, sizeof(str) - ofs, IFACE_("%d x %d"), width, height);
if (ibuf) {
if (ibuf->rect_float) {
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 081515ca4bc..7683823a79f 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -35,7 +35,7 @@ struct bContext;
struct wmOperatorType;
/* channel heights */
-#define CHANNEL_FIRST (-UI_SCRUBBING_MARGIN_Y - CHANNEL_HEIGHT_HALF - CHANNEL_SKIP)
+#define CHANNEL_FIRST (-UI_TIME_SCRUB_MARGIN_Y - CHANNEL_HEIGHT_HALF - CHANNEL_SKIP)
#define CHANNEL_HEIGHT (0.8f * U.widget_unit)
#define CHANNEL_HEIGHT_HALF (0.4f * U.widget_unit)
#define CHANNEL_SKIP (0.1f * U.widget_unit)
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index e5698ede59a..710a46fdd51 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -245,7 +245,7 @@ static int open_exec(bContext *C, wmOperator *op)
id_us_min(&clip->id);
RNA_id_pointer_create(&clip->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
else if (sc) {
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 13d190e6861..4df435270ce 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -926,7 +926,8 @@ static void clip_main_region_draw(const bContext *C, ARegion *ar)
ScrArea *sa = CTX_wm_area(C);
int mask_width, mask_height;
ED_mask_get_size(sa, &mask_width, &mask_height);
- ED_mask_draw_region(mask,
+ ED_mask_draw_region(CTX_data_depsgraph(C),
+ mask,
ar,
sc->mask_info.draw_flag,
sc->mask_info.draw_type,
@@ -1006,8 +1007,8 @@ static void clip_preview_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
- keymap = WM_keymap_ensure(wm->defaultconf, "Clip Scrubbing", SPACE_CLIP, RGN_TYPE_PREVIEW);
- WM_event_add_keymap_handler_poll(&ar->handlers, keymap, ED_event_in_scrubbing_region);
+ keymap = WM_keymap_ensure(wm->defaultconf, "Clip Time Scrub", SPACE_CLIP, RGN_TYPE_PREVIEW);
+ WM_event_add_keymap_handler_poll(&ar->handlers, keymap, ED_time_scrub_event_in_region);
keymap = WM_keymap_ensure(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
@@ -1047,7 +1048,7 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
/* time-scrubbing */
- ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
+ ED_time_scrub_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@@ -1061,7 +1062,7 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
0,
15 * UI_DPI_FAC,
15 * UI_DPI_FAC,
- UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_DPI_FAC * ar->sizey - UI_TIME_SCRUB_MARGIN_Y);
UI_view2d_draw_scale_y__values(ar, v2d, &rect, TH_TEXT);
}
}
@@ -1101,7 +1102,7 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
/* time-scrubbing */
- ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
+ ED_time_scrub_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@@ -1371,7 +1372,7 @@ void ED_spacetype_clip(void)
/* regions: properties */
art = MEM_callocN(sizeof(ARegionType), "spacetype clip region properties");
art->regionid = RGN_TYPE_UI;
- art->prefsizex = UI_COMPACT_PANEL_WIDTH;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
art->init = clip_properties_region_init;
art->draw = clip_properties_region_draw;
@@ -1382,7 +1383,7 @@ void ED_spacetype_clip(void)
/* regions: tools */
art = MEM_callocN(sizeof(ARegionType), "spacetype clip region tools");
art->regionid = RGN_TYPE_TOOLS;
- art->prefsizex = UI_COMPACT_PANEL_WIDTH;
+ art->prefsizex = UI_SIDEBAR_PANEL_WIDTH;
art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
art->listener = clip_props_region_listener;
art->init = clip_tools_region_init;
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index b51baafbcf5..0425d6da3d8 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -1466,6 +1466,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op)
}
BLI_gset_free(point_tracks, NULL);
+ DEG_id_tag_update(&clip->id, 0);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
@@ -1625,6 +1626,7 @@ static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op))
}
}
+ DEG_id_tag_update(&clip->id, 0);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip);
return OPERATOR_FINISHED;
@@ -1806,6 +1808,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
}
}
+ DEG_id_tag_update(&clip->id, 0);
BKE_tracking_dopesheet_tag_update(tracking);
WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, clip);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 8329218eea9..b68efdc0ea0 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -55,6 +55,7 @@
#include "DEG_depsgraph_build.h"
#include "UI_view2d.h"
+#include "UI_interface.h"
#include "ED_anim_api.h"
#include "ED_keyframing.h"
@@ -282,10 +283,18 @@ static int graphkeys_viewall(bContext *C,
do_sel_only,
include_handles);
+ /* Give some more space at the borders. */
BLI_rctf_scale(&cur_new, 1.1f);
- UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
+ /* Take regions into account, that could block the view. */
+ float pad_top = UI_TIME_SCRUB_MARGIN_Y;
+ float pad_bottom = 0;
+ if (!BLI_listbase_is_empty(ED_context_get_markers(C))) {
+ pad_bottom = UI_MARKER_MARGIN_Y;
+ }
+ BLI_rctf_pad_y(&cur_new, ac.ar->sizey * UI_DPI_FAC, pad_bottom, pad_top);
+ UI_view2d_smooth_view(C, ac.ar, &cur_new, smooth_viewtx);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 4e131c653f8..6c5ebf77bf4 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -314,7 +314,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
/* time-scrubbing */
- ED_scrubbing_draw(ar, scene, display_seconds, false);
+ ED_time_scrub_draw(ar, scene, display_seconds, false);
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
@@ -329,7 +329,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
0,
15 * UI_DPI_FAC,
15 * UI_DPI_FAC,
- UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_DPI_FAC * ar->sizey - UI_TIME_SCRUB_MARGIN_Y);
UI_view2d_draw_scale_y__values(ar, v2d, &rect, TH_SCROLL_TEXT);
}
}
@@ -376,7 +376,7 @@ static void graph_channel_region_draw(const bContext *C, ARegion *ar)
}
/* channel filter next to scrubbing area */
- ED_channel_search_draw(C, ar, ac.ads);
+ ED_time_scrub_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 68af854e367..26512cb232d 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -42,6 +42,7 @@
#include "RE_pipeline.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -62,81 +63,6 @@
#define B_NOP -1
#define MAX_IMAGE_INFO_LEN 128
-/* proto */
-
-static void image_info(
- Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
-{
- size_t ofs = 0;
-
- str[0] = 0;
- if (ima == NULL) {
- return;
- }
-
- if (ibuf == NULL) {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs);
- }
- else {
- if (ima->source == IMA_SRC_MOVIE) {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
- if (BKE_image_has_anim(ima)) {
- ofs += BLI_snprintf(
- str + ofs,
- len - ofs,
- IFACE_(" %d frs"),
- IMB_anim_get_duration(((ImageAnim *)ima->anims.first)->anim, IMB_TC_RECORD_RUN));
- }
- }
- else {
- ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
- }
-
- ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
-
- if (ibuf->rect_float) {
- if (ibuf->channels != 4) {
- ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
- }
- else if (ibuf->planes == R_IMF_PLANES_RGBA) {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
- }
- else {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
- }
- }
- else {
- if (ibuf->planes == R_IMF_PLANES_RGBA) {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
- }
- else {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
- }
- }
- if (ibuf->zbuf || ibuf->zbuf_float) {
- ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
- }
-
- if (ima->source == IMA_SRC_SEQUENCE) {
- const char *file = BLI_last_slash(ibuf->name);
- if (file == NULL) {
- file = ibuf->name;
- }
- else {
- file++;
- }
- ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file);
- }
- }
-
- /* the frame number, even if we cant */
- if (ima->source == IMA_SRC_SEQUENCE) {
- /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
- const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
- ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr);
- }
-}
-
/* gets active viewer user */
struct ImageUser *ntree_get_active_iuser(bNodeTree *ntree)
{
@@ -822,6 +748,22 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
RNA_property_update(C, &cb->ptr, cb->prop);
}
+static bool image_has_alpha(Image *ima, ImageUser *iuser)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if (ibuf == NULL) {
+ return false;
+ }
+
+ int imtype = BKE_image_ftype_to_imtype(ibuf->ftype, &ibuf->foptions);
+ char valid_channels = BKE_imtype_valid_channels(imtype, false);
+ bool has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
+ return has_alpha;
+}
+
void uiTemplateImage(uiLayout *layout,
bContext *C,
PointerRNA *ptr,
@@ -830,24 +772,11 @@ void uiTemplateImage(uiLayout *layout,
bool compact,
bool multiview)
{
- PropertyRNA *prop;
- PointerRNA imaptr;
- RNAUpdateCb *cb;
- Image *ima;
- ImageUser *iuser;
- Scene *scene = CTX_data_scene(C);
- SpaceImage *space_image = CTX_wm_space_image(C);
- uiLayout *row, *split, *col;
- uiBlock *block;
- char str[MAX_IMAGE_INFO_LEN];
-
- void *lock;
-
if (!ptr->data) {
return;
}
- prop = RNA_struct_find_property(ptr, propname);
+ PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
if (!prop) {
printf(
"%s: property not found: %s.%s\n", __func__, RNA_struct_identifier(ptr->type), propname);
@@ -862,22 +791,19 @@ void uiTemplateImage(uiLayout *layout,
return;
}
- block = uiLayoutGetBlock(layout);
+ uiBlock *block = uiLayoutGetBlock(layout);
- imaptr = RNA_property_pointer_get(ptr, prop);
- ima = imaptr.data;
- iuser = userptr->data;
+ PointerRNA imaptr = RNA_property_pointer_get(ptr, prop);
+ Image *ima = imaptr.data;
+ ImageUser *iuser = userptr->data;
+ Scene *scene = CTX_data_scene(C);
BKE_image_user_frame_calc(iuser, (int)scene->r.cfra);
- cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
- cb->ptr = *ptr;
- cb->prop = prop;
- cb->iuser = iuser;
-
uiLayoutSetContextPointer(layout, "edit_image", &imaptr);
uiLayoutSetContextPointer(layout, "edit_image_user", userptr);
+ SpaceImage *space_image = CTX_wm_space_image(C);
if (!compact && (space_image == NULL || iuser != &space_image->iuser)) {
uiTemplateID(layout,
C,
@@ -888,164 +814,178 @@ void uiTemplateImage(uiLayout *layout,
NULL,
UI_TEMPLATE_ID_FILTER_ALL,
false);
+
+ if (ima != NULL) {
+ uiItemS(layout);
+ }
}
- if (ima) {
- UI_block_funcN_set(block, rna_update_cb, MEM_dupallocN(cb), NULL);
+ if (ima == NULL) {
+ return;
+ }
- if (ima->source == IMA_SRC_VIEWER) {
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
- BKE_image_release_ibuf(ima, ibuf, lock);
+ if (ima->source == IMA_SRC_VIEWER) {
+ /* Viewer images. */
+ uiTemplateImageInfo(layout, C, ima, iuser);
- uiItemL(layout, ima->id.name + 2, ICON_NONE);
- uiItemL(layout, str, ICON_NONE);
+ if (ima->type == IMA_TYPE_COMPOSITE) {
+ }
+ else if (ima->type == IMA_TYPE_R_RESULT) {
+ /* browse layer/passes */
+ RenderResult *rr;
+ const float dpi_fac = UI_DPI_FAC;
+ const int menus_width = 230 * dpi_fac;
+
+ /* use BKE_image_acquire_renderresult so we get the correct slot in the menu */
+ rr = BKE_image_acquire_renderresult(scene, ima);
+ uiblock_layer_pass_buttons(layout, ima, rr, iuser, menus_width, &ima->render_slot);
+ BKE_image_release_renderresult(scene, ima);
+ }
- if (ima->type == IMA_TYPE_COMPOSITE) {
- }
- else if (ima->type == IMA_TYPE_R_RESULT) {
- /* browse layer/passes */
- RenderResult *rr;
- const float dpi_fac = UI_DPI_FAC;
- const int menus_width = 230 * dpi_fac;
-
- /* use BKE_image_acquire_renderresult so we get the correct slot in the menu */
- rr = BKE_image_acquire_renderresult(scene, ima);
- uiblock_layer_pass_buttons(layout, ima, rr, iuser, menus_width, &ima->render_slot);
- BKE_image_release_renderresult(scene, ima);
- }
+ return;
+ }
+
+ /* Set custom callback for property updates. */
+ RNAUpdateCb *cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb");
+ cb->ptr = *ptr;
+ cb->prop = prop;
+ cb->iuser = iuser;
+ UI_block_funcN_set(block, rna_update_cb, cb, NULL);
+
+ /* Disable editing if image was modified, to avoid losing changes. */
+ const bool is_dirty = BKE_image_is_dirty(ima);
+ if (is_dirty) {
+ uiLayout *row = uiLayoutRow(layout, true);
+ uiItemO(row, IFACE_("Save"), ICON_NONE, "image.save");
+ uiItemO(row, IFACE_("Discard"), ICON_NONE, "image.reload");
+ uiItemS(layout);
+ }
+
+ layout = uiLayoutColumn(layout, false);
+ uiLayoutSetEnabled(layout, !is_dirty);
+ uiLayoutSetPropDecorate(layout, false);
+
+ /* Image source */
+ {
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetPropSep(col, true);
+ uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE);
+ }
+
+ /* Filepath */
+ const bool is_packed = BKE_image_has_packedfile(ima);
+ const bool no_filepath = is_packed && !BKE_image_has_filepath(ima);
+
+ if ((ima->source != IMA_SRC_GENERATED) && !no_filepath) {
+ uiItemS(layout);
+
+ uiLayout *row = uiLayoutRow(layout, true);
+ if (is_packed) {
+ uiItemO(row, "", ICON_PACKAGE, "image.unpack");
}
else {
- /* Disable editing if image was modified, to avoid losing changes. */
- const bool is_dirty = BKE_image_is_dirty(ima);
- if (is_dirty) {
- row = uiLayoutRow(layout, true);
- uiItemO(row, IFACE_("Save"), ICON_NONE, "image.save");
- uiItemO(row, IFACE_("Discard Changes"), ICON_NONE, "image.reload");
- uiItemS(layout);
- }
+ uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
+ }
- layout = uiLayoutColumn(layout, false);
- uiLayoutSetEnabled(layout, !is_dirty);
+ row = uiLayoutRow(row, true);
+ uiLayoutSetEnabled(row, is_packed == false);
+ uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
+ uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
+ }
- /* Image source */
- uiItemR(layout, &imaptr, "source", 0, NULL, ICON_NONE);
+ /* Image layers and Info */
+ if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
+ uiItemS(layout);
- /* Filepath */
- const bool is_packed = BKE_image_has_packedfile(ima);
- const bool no_filepath = is_packed && !BKE_image_has_filepath(ima);
+ const float dpi_fac = UI_DPI_FAC;
+ uiblock_layer_pass_buttons(layout, ima, ima->rr, iuser, 230 * dpi_fac, NULL);
+ }
+ else if (ima->source == IMA_SRC_GENERATED) {
+ uiItemS(layout);
- if ((ima->source != IMA_SRC_GENERATED) && !no_filepath) {
- row = uiLayoutRow(layout, true);
- if (is_packed) {
- uiItemO(row, "", ICON_PACKAGE, "image.unpack");
- }
- else {
- uiItemO(row, "", ICON_UGLYPACKAGE, "image.pack");
- }
+ /* Generated */
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetPropSep(col, true);
- row = uiLayoutRow(row, true);
- uiLayoutSetEnabled(row, is_packed == false);
- uiItemR(row, &imaptr, "filepath", 0, "", ICON_NONE);
- uiItemO(row, "", ICON_FILE_REFRESH, "image.reload");
- }
+ uiLayout *sub = uiLayoutColumn(col, true);
+ uiItemR(sub, &imaptr, "generated_width", 0, "X", ICON_NONE);
+ uiItemR(sub, &imaptr, "generated_height", 0, "Y", ICON_NONE);
- /* Image layers and Info */
- if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
- const float dpi_fac = UI_DPI_FAC;
- uiblock_layer_pass_buttons(layout, ima, ima->rr, iuser, 230 * dpi_fac, NULL);
- }
- else if (ima->source != IMA_SRC_GENERATED) {
- if (compact == 0) {
- uiTemplateImageInfo(layout, C, ima, iuser);
- }
- }
+ uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
- uiItemS(layout);
+ uiItemS(col);
- col = uiLayoutColumn(layout, false);
- uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
- uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
+ uiItemR(col, &imaptr, "generated_type", UI_ITEM_R_EXPAND, IFACE_("Type"), ICON_NONE);
+ if (ima->gen_type == IMA_GENTYPE_BLANK) {
+ uiItemR(col, &imaptr, "generated_color", 0, NULL, ICON_NONE);
+ }
+ }
+ else if (compact == 0) {
+ uiTemplateImageInfo(layout, C, ima, iuser);
+ }
- uiItemS(layout);
+ if (BKE_image_is_animated(ima)) {
+ /* Animation */
+ uiItemS(layout);
- if (ima->source != IMA_SRC_GENERATED) {
- if (compact == 0) { /* background image view doesn't need these */
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- bool has_alpha = true;
-
- if (ibuf) {
- int imtype = BKE_image_ftype_to_imtype(ibuf->ftype, &ibuf->foptions);
- char valid_channels = BKE_imtype_valid_channels(imtype, false);
-
- has_alpha = (valid_channels & IMA_CHAN_FLAG_ALPHA) != 0;
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
-
- if (multiview) {
- if ((scene->r.scemode & R_MULTIVIEW) != 0) {
- uiItemR(layout, &imaptr, "use_multiview", 0, NULL, ICON_NONE);
-
- if (RNA_boolean_get(&imaptr, "use_multiview")) {
- uiTemplateImageViews(layout, &imaptr);
- }
- }
- }
-
- if (has_alpha) {
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &imaptr, "use_alpha", 0, NULL, ICON_NONE);
- row = uiLayoutRow(col, false);
- uiLayoutSetActive(row, RNA_boolean_get(&imaptr, "use_alpha"));
- uiItemR(row, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
- }
-
- if (ima->source == IMA_SRC_MOVIE) {
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
- }
- }
- }
+ uiLayout *col = uiLayoutColumn(layout, true);
+ uiLayoutSetPropSep(col, true);
+
+ uiLayout *sub = uiLayoutColumn(col, true);
+ uiLayout *row = uiLayoutRow(sub, true);
+ uiItemR(row, userptr, "frame_duration", 0, IFACE_("Frames"), ICON_NONE);
+ uiItemO(row, "", ICON_FILE_REFRESH, "IMAGE_OT_match_movie_length");
+
+ uiItemR(sub, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
+ uiItemR(sub, userptr, "frame_offset", 0, NULL, ICON_NONE);
- if (BKE_image_is_animated(ima)) {
- uiItemS(layout);
+ uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
+ uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
- split = uiLayoutSplit(layout, 0.0f, false);
+ if (ima->source == IMA_SRC_MOVIE && compact == 0) {
+ uiItemR(col, &imaptr, "use_deinterlace", 0, IFACE_("Deinterlace"), ICON_NONE);
+ }
+ }
- col = uiLayoutColumn(split, false);
+ /* Multiview */
+ if (multiview && compact == 0) {
+ if ((scene->r.scemode & R_MULTIVIEW) != 0) {
+ uiItemS(layout);
- BLI_snprintf(str, sizeof(str), IFACE_("(%d) Frames"), iuser->framenr);
- uiItemR(col, userptr, "frame_duration", 0, str, ICON_NONE);
- uiItemR(col, userptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
- uiItemR(col, userptr, "frame_offset", 0, NULL, ICON_NONE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetPropSep(col, true);
+ uiItemR(col, &imaptr, "use_multiview", 0, NULL, ICON_NONE);
- col = uiLayoutColumn(split, false);
- uiItemO(col, NULL, ICON_NONE, "IMAGE_OT_match_movie_length");
- uiItemR(col, userptr, "use_auto_refresh", 0, NULL, ICON_NONE);
- uiItemR(col, userptr, "use_cyclic", 0, NULL, ICON_NONE);
+ if (RNA_boolean_get(&imaptr, "use_multiview")) {
+ uiTemplateImageViews(layout, &imaptr);
}
- else if (ima->source == IMA_SRC_GENERATED) {
- split = uiLayoutSplit(layout, 0.0f, false);
+ }
+ }
- col = uiLayoutColumn(split, true);
- uiItemR(col, &imaptr, "generated_width", 0, "X", ICON_NONE);
- uiItemR(col, &imaptr, "generated_height", 0, "Y", ICON_NONE);
+ /* Colorspace and alpha */
+ {
+ uiItemS(layout);
- uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
+ uiLayout *col = uiLayoutColumn(layout, false);
+ uiLayoutSetPropSep(col, true);
+ uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
- uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+ if (compact == 0) {
+ if (ima->source != IMA_SRC_GENERATED) {
+ if (image_has_alpha(ima, iuser)) {
+ uiLayout *sub = uiLayoutColumn(col, false);
+ uiItemR(sub, &imaptr, "alpha_mode", 0, IFACE_("Alpha"), ICON_NONE);
- if (ima->gen_type == IMA_GENTYPE_BLANK) {
- uiItemR(layout, &imaptr, "generated_color", 0, NULL, ICON_NONE);
+ bool is_data = IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name);
+ uiLayoutSetActive(sub, !is_data);
}
}
- }
- UI_block_funcN_set(block, NULL, NULL, NULL);
+ uiItemR(col, &imaptr, "use_view_as_render", 0, NULL, ICON_NONE);
+ }
}
- MEM_freeN(cb);
+ UI_block_funcN_set(block, NULL, NULL, NULL);
}
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, bool color_management)
@@ -1215,25 +1155,24 @@ void uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA
{
ImageFormatData *imf = imfptr->data;
- if (ptr == NULL) {
- return;
+ if (ptr != NULL) {
+ uiItemR(layout, ptr, "use_multiview", 0, NULL, ICON_NONE);
+ if (!RNA_boolean_get(ptr, "use_multiview")) {
+ return;
+ }
}
- uiItemR(layout, ptr, "use_multiview", 0, NULL, ICON_NONE);
-
- if (RNA_boolean_get(ptr, "use_multiview")) {
- if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
- PropertyRNA *prop;
- PointerRNA stereo3d_format_ptr;
+ if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
+ PropertyRNA *prop;
+ PointerRNA stereo3d_format_ptr;
- prop = RNA_struct_find_property(imfptr, "stereo_3d_format");
- stereo3d_format_ptr = RNA_property_pointer_get(imfptr, prop);
+ prop = RNA_struct_find_property(imfptr, "stereo_3d_format");
+ stereo3d_format_ptr = RNA_property_pointer_get(imfptr, prop);
- uiTemplateViewsFormat(layout, imfptr, &stereo3d_format_ptr);
- }
- else {
- uiTemplateViewsFormat(layout, imfptr, NULL);
- }
+ uiTemplateViewsFormat(layout, imfptr, &stereo3d_format_ptr);
+ }
+ else {
+ uiTemplateViewsFormat(layout, imfptr, NULL);
}
}
@@ -1258,21 +1197,87 @@ void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser
void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
{
- Scene *scene = CTX_data_scene(C);
- ImBuf *ibuf;
- char str[MAX_IMAGE_INFO_LEN];
+ if (ima == NULL || iuser == NULL) {
+ return;
+ }
+
+ /* Acquire image buffer. */
void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- if (!ima || !iuser) {
- return;
+ uiLayout *col = uiLayoutColumn(layout, true);
+ uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_RIGHT);
+
+ if (ibuf == NULL) {
+ uiItemL(col, IFACE_("Can't Load Image"), ICON_NONE);
}
+ else {
+ char str[MAX_IMAGE_INFO_LEN] = {0};
+ const int len = MAX_IMAGE_INFO_LEN;
+ int ofs = 0;
- ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d x %d, "), ibuf->x, ibuf->y);
+
+ if (ibuf->rect_float) {
+ if (ibuf->channels != 4) {
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
+ }
+ else if (ibuf->planes == R_IMF_PLANES_RGBA) {
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
+ }
+ else {
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
+ }
+ }
+ else {
+ if (ibuf->planes == R_IMF_PLANES_RGBA) {
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
+ }
+ else {
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
+ }
+ }
+ if (ibuf->zbuf || ibuf->zbuf_float) {
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
+ }
+
+ uiItemL(col, str, ICON_NONE);
+ }
+
+ /* Frame number, even if we can't load the image. */
+ if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
+ /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
+ Scene *scene = CTX_data_scene(C);
+ const int framenr = BKE_image_user_frame_get(iuser, CFRA, NULL);
+ char str[MAX_IMAGE_INFO_LEN];
+ int duration = 0;
+
+ if (ima->source == IMA_SRC_MOVIE && BKE_image_has_anim(ima)) {
+ struct anim *anim = ((ImageAnim *)ima->anims.first)->anim;
+ if (anim) {
+ duration = IMB_anim_get_duration(anim, IMB_TC_RECORD_RUN);
+ }
+ }
+
+ if (duration > 0) {
+ /* Movie duration */
+ BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d / %d"), framenr, duration);
+ }
+ else if (ima->source == IMA_SRC_SEQUENCE && ibuf) {
+ /* Image sequence frame number + filename */
+ const char *filename = BLI_last_slash(ibuf->name);
+ filename = (filename == NULL) ? ibuf->name : filename + 1;
+ BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d: %s"), framenr, filename);
+ }
+ else {
+ /* Frame number */
+ BLI_snprintf(str, MAX_IMAGE_INFO_LEN, IFACE_("Frame %d"), framenr);
+ }
+
+ uiItemL(col, str, ICON_NONE);
+ }
- BKE_image_user_frame_calc(iuser, (int)scene->r.cfra);
- image_info(scene, iuser, ima, ibuf, str, MAX_IMAGE_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
- uiItemL(layout, str, ICON_NONE);
}
#undef MAX_IMAGE_INFO_LEN
@@ -1304,6 +1309,7 @@ void image_buttons_register(ARegionType *art)
strcpy(pt->label, N_("Metadata"));
strcpy(pt->category, "Image");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->order = 10;
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;
pt->flag |= PNL_DEFAULT_CLOSED;
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 07c2d216a93..8121c577706 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1320,7 +1320,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
PointerRNA imaptr;
RNA_id_pointer_create(&ima->id, &imaptr);
- RNA_property_pointer_set(NULL, &iod->pprop.ptr, iod->pprop.prop, imaptr);
+ RNA_property_pointer_set(&iod->pprop.ptr, iod->pprop.prop, imaptr, NULL);
RNA_property_update(C, &iod->pprop.ptr, iod->pprop.prop);
}
@@ -1869,8 +1869,7 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS
Scene *scene = CTX_data_scene(C);
ImageSaveOptions opts;
PropertyRNA *prop;
- const bool save_as_render = ((ima->source == IMA_SRC_VIEWER) ||
- (ima->flag & IMA_VIEW_AS_RENDER));
+ const bool save_as_render = (ima->source == IMA_SRC_VIEWER);
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return image_save_as_exec(C, op);
@@ -2474,7 +2473,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
PointerRNA imaptr;
RNA_id_pointer_create(&ima->id, &imaptr);
- RNA_property_pointer_set(NULL, &data->pprop.ptr, data->pprop.prop, imaptr);
+ RNA_property_pointer_set(&data->pprop.ptr, data->pprop.prop, imaptr, NULL);
RNA_property_update(C, &data->pprop.ptr, data->pprop.prop);
}
else if (sima) {
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index a8be93ad213..73baf1540f7 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -658,7 +658,8 @@ static void image_main_region_draw(const bContext *C, ARegion *ar)
BLI_thread_unlock(LOCK_DRAW_IMAGE);
}
- ED_mask_draw_region(mask,
+ ED_mask_draw_region(depsgraph,
+ mask,
ar,
sima->mask_info.draw_flag,
sima->mask_info.draw_type,
diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c
index 4b7dfe5d653..3bdd2804efc 100644
--- a/source/blender/editors/space_nla/space_nla.c
+++ b/source/blender/editors/space_nla/space_nla.c
@@ -205,7 +205,7 @@ static void nla_channel_region_draw(const bContext *C, ARegion *ar)
}
/* channel filter next to scrubbing area */
- ED_channel_search_draw(C, ar, ac.ads);
+ ED_time_scrub_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -290,7 +290,7 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
- ED_scrubbing_draw(ar, scene, snla->flag & SNLA_DRAWTIME, true);
+ ED_time_scrub_draw(ar, scene, snla->flag & SNLA_DRAWTIME, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index bf6ec961a5d..e39e024e44a 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -713,6 +713,11 @@ static void node_buts_image_user(uiLayout *layout,
PointerRNA colorspace_settings_ptr = RNA_pointer_get(imaptr, "colorspace_settings");
uiItemL(split, IFACE_("Color Space"), ICON_NONE);
uiItemR(split, &colorspace_settings_ptr, "name", 0, "", ICON_NONE);
+
+ /* Avoid losing changes image is painted. */
+ if (BKE_image_is_dirty(imaptr->data)) {
+ uiLayoutSetEnabled(split, false);
+ }
}
static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index e677c649fb4..01a30f677a3 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -521,7 +521,7 @@ static int new_node_tree_exec(bContext *C, wmOperator *op)
id_us_min(&ntree->id);
RNA_id_pointer_create(&ntree->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
else if (snode) {
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index a8331c26ce6..aab328249fe 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -495,17 +495,7 @@ static int node_mouse_select(bContext *C,
}
}
- /* In case we do two-steps selection, we do not want to select the node if some valid socket
- * is below the mouse, as that would prevent draging from sockets (NODE_OT_link)
- * to be properly triggered. See T64660. */
- if (wait_to_deselect_others) {
- if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN) ||
- node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) {
- ret_value = OPERATOR_CANCELLED;
- }
- }
-
- if (sock == NULL) {
+ if (!sock) {
/* find the closest visible node */
node = node_under_mouse_select(snode->edittree, (int)cursor[0], (int)cursor[1]);
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 6a7795393c9..aed7af3911f 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2802,7 +2802,11 @@ static void outliner_draw_tree_element(bContext *C,
BKE_view_layer_base_find(view_layer, ob);
const bool is_selected = (base != NULL) && ((base->flag & BASE_SELECTED) != 0);
- if (ob == obact || is_selected) {
+ if (ob == obact) {
+ active = OL_DRAWSEL_ACTIVE;
+ }
+
+ if (is_selected) {
if (ob == obact) {
/* active selected object */
UI_GetThemeColor3ubv(TH_ACTIVE_OBJECT, text_color);
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 90180c4ea47..c32b2b051f8 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -88,6 +88,11 @@
static int outliner_highlight_update(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
+ /* stop highlighting if out of area */
+ if (!ED_screen_area_active(C)) {
+ return OPERATOR_PASS_THROUGH;
+ }
+
/* Drag and drop does own highlighting. */
wmWindowManager *wm = CTX_wm_manager(C);
if (wm->drags.first) {
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index c6fcf1d8cf7..bee615108f9 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -450,32 +450,6 @@ static eOLDrawState tree_element_active_material(bContext *C,
return OL_DRAWSEL_NONE;
}
-static eOLDrawState tree_element_active_light(bContext *UNUSED(C),
- Scene *UNUSED(scene),
- ViewLayer *view_layer,
- SpaceOutliner *soops,
- TreeElement *te,
- const eOLSetState set)
-{
- Object *ob;
-
- /* we search for the object parent */
- ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == NULL || ob != OBACT(view_layer)) {
- /* just paranoia */
- return OL_DRAWSEL_NONE;
- }
-
- if (set != OL_SETSEL_NONE) {
- // XXX extern_set_butspace(F5KEY, 0);
- }
- else {
- return OL_DRAWSEL_NORMAL;
- }
-
- return OL_DRAWSEL_NONE;
-}
-
static eOLDrawState tree_element_active_camera(bContext *UNUSED(C),
Scene *scene,
ViewLayer *UNUSED(sl),
@@ -1041,8 +1015,6 @@ eOLDrawState tree_element_active(bContext *C,
return tree_element_active_material(C, scene, view_layer, soops, te, set);
case ID_WO:
return tree_element_active_world(C, scene, view_layer, soops, te, set);
- case ID_LA:
- return tree_element_active_light(C, scene, view_layer, soops, te, set);
case ID_TXT:
return tree_element_active_text(C, scene, view_layer, soops, te, set);
case ID_CA:
@@ -1160,7 +1132,7 @@ static void do_outliner_item_activate_tree_element(bContext *C,
WM_window_set_active_scene(CTX_data_main(C), C, CTX_wm_window(C), (Scene *)tselem->id);
}
}
- else if (te->idcode == ID_GR) {
+ else if ((te->idcode == ID_GR) && (soops->outlinevis != SO_VIEW_LAYER)) {
Collection *gr = (Collection *)tselem->id;
if (extend) {
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 80424f021e2..6da2e913003 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1808,7 +1808,7 @@ static void outliner_collections_children_sort(ListBase *lb)
}
for (te = lb->first; te; te = te->next) {
- outliner_sort(&te->subtree);
+ outliner_collections_children_sort(&te->subtree);
}
}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 4c591a61f67..091efc56c09 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -303,6 +303,7 @@ static SpaceLink *outliner_new(const ScrArea *UNUSED(area), const Scene *UNUSED(
soutliner->spacetype = SPACE_OUTLINER;
soutliner->filter_id_type = ID_GR;
soutliner->show_restrict_flags = SO_RESTRICT_ENABLE | SO_RESTRICT_HIDE;
+ soutliner->outlinevis = SO_VIEW_LAYER;
/* header */
ar = MEM_callocN(sizeof(ARegion), "header for outliner");
@@ -384,6 +385,14 @@ static void outliner_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id,
}
}
+static void outliner_deactivate(struct ScrArea *sa)
+{
+ /* Remove hover highlights */
+ SpaceOutliner *soops = sa->spacedata.first;
+ outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED, false);
+ ED_region_tag_redraw(BKE_area_find_region_type(sa, RGN_TYPE_WINDOW));
+}
+
/* only called once, from space_api/spacetypes.c */
void ED_spacetype_outliner(void)
{
@@ -401,6 +410,7 @@ void ED_spacetype_outliner(void)
st->keymap = outliner_keymap;
st->dropboxes = outliner_dropboxes;
st->id_remap = outliner_id_remap;
+ st->deactivate = outliner_deactivate;
/* regions: main window */
art = MEM_callocN(sizeof(ARegionType), "spacetype outliner region");
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index b5bb79fb430..e8f18eeebc7 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -149,7 +149,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
int proximity = INT_MAX;
if (!ed || !ed->seqbasep) {
- return 1;
+ return 2;
}
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
@@ -161,9 +161,9 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type)
}
if (tgt) {
- return tgt->machine;
+ return tgt->machine + 1;
}
- return 1;
+ return 2;
}
static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, int flag, int type)
@@ -173,7 +173,7 @@ static void sequencer_generic_invoke_xy__internal(bContext *C, wmOperator *op, i
int cfra = (int)CFRA;
/* effect strips don't need a channel initialized from the mouse */
- if (!(flag & SEQPROP_NOCHAN)) {
+ if (!(flag & SEQPROP_NOCHAN) && RNA_struct_property_is_set(op->ptr, "channel") == 0) {
RNA_int_set(op->ptr, "channel", sequencer_generic_invoke_xy_guess_channel(C, type));
}
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 805ec26950a..a59cc36f28e 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -1121,8 +1121,7 @@ static void sequencer_display_size(Scene *scene, float r_viewrect[2])
r_viewrect[0] = (float)scene->r.xsch;
r_viewrect[1] = (float)scene->r.ysch;
- /* Aspect ratio seems to have no effect on output image*/
- /* r_viewrect[0] *= scene->r.xasp / scene->r.yasp; */
+ r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
}
static void sequencer_draw_gpencil(const bContext *C)
@@ -1822,7 +1821,7 @@ typedef struct CacheDrawData {
/* Called as a callback */
static bool draw_cache_view_cb(
- void *userdata, struct Sequence *seq, int cfra, int cache_type, float UNUSED(cost))
+ void *userdata, struct Sequence *seq, int nfra, int cache_type, float UNUSED(cost))
{
CacheDrawData *drawdata = userdata;
const bContext *C = drawdata->C;
@@ -1902,6 +1901,7 @@ static bool draw_cache_view_cb(
}
}
+ int cfra = seq->start + nfra;
immUniformColor4f(color[0], color[1], color[2], color[3]);
immRectf(pos, cfra, stripe_bot, cfra + 1, stripe_top);
@@ -2087,7 +2087,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
UI_view2d_view_restore(C);
/* scrubbing region */
- ED_scrubbing_draw(ar, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
+ ED_time_scrub_draw(ar, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@@ -2101,7 +2101,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
0,
15 * UI_DPI_FAC,
15 * UI_DPI_FAC,
- UI_DPI_FAC * ar->sizey - UI_SCRUBBING_MARGIN_Y);
+ UI_DPI_FAC * ar->sizey - UI_TIME_SCRUB_MARGIN_Y);
UI_view2d_draw_scale_y__block(ar, v2d, &rect, TH_SCROLL_TEXT);
}
}
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index a3030153e6c..a998ae7a7b3 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -2680,7 +2680,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
while (seq) {
next = seq->next;
if (seq != seqm && (seq->flag & SELECT)) {
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_dependent(scene, seq);
channel_max = max_ii(seq->machine, channel_max);
BLI_remlink(ed->seqbasep, seq);
BLI_addtail(&seqm->seqbase, seq);
@@ -2755,7 +2755,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
}
for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) {
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_dependent(scene, seq);
}
BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase);
@@ -3518,8 +3518,8 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
BKE_sound_add_scene_sound_defaults(scene, seq_other);
}
- BKE_sequence_invalidate_cache(scene, seq_act);
- BKE_sequence_invalidate_cache(scene, seq_other);
+ BKE_sequence_invalidate_cache_raw(scene, seq_act);
+ BKE_sequence_invalidate_cache_raw(scene, seq_other);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c
index e00d33853a3..f262c6518aa 100644
--- a/source/blender/editors/space_sequencer/sequencer_modifier.c
+++ b/source/blender/editors/space_sequencer/sequencer_modifier.c
@@ -64,7 +64,7 @@ static int strip_modifier_add_exec(bContext *C, wmOperator *op)
BKE_sequence_modifier_new(seq, NULL, type);
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -115,7 +115,7 @@ static int strip_modifier_remove_exec(bContext *C, wmOperator *op)
BLI_remlink(&seq->modifiers, smd);
BKE_sequence_modifier_free(smd);
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -175,7 +175,7 @@ static int strip_modifier_move_exec(bContext *C, wmOperator *op)
}
}
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -249,7 +249,7 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op)
}
SEQ_END;
- BKE_sequence_invalidate_cache(scene, seq);
+ BKE_sequence_invalidate_cache_preprocessed(scene, seq);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index e16029395bd..593dd86477a 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -108,6 +108,8 @@ static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fx, &fy);
+ fx /= scene->r.xasp / scene->r.yasp;
+
fx += (float)scene->r.xsch / 2.0f;
fy += (float)scene->r.ysch / 2.0f;
fx *= (float)ibuf->x / (float)scene->r.xsch;
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 7a02b1850ae..6ab44ded046 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -729,6 +729,7 @@ static void sequencer_buttons_region_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_ensure(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0);
WM_event_add_keymap_handler_v2d_mask(&ar->handlers, keymap);
+ UI_panel_category_active_set_default(ar, "Strip");
ED_region_panels_init(wm, ar);
}
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index a9dd2a59d1e..2593571d9a3 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -247,7 +247,7 @@ static int text_new_exec(bContext *C, wmOperator *UNUSED(op))
if (prop) {
RNA_id_pointer_create(&text->id, &idptr);
- RNA_property_pointer_set(NULL, &ptr, prop, idptr);
+ RNA_property_pointer_set(&ptr, prop, idptr, NULL);
RNA_property_update(C, &ptr, prop);
}
else if (st) {
@@ -326,7 +326,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
if (pprop->prop) {
RNA_id_pointer_create(&text->id, &idptr);
- RNA_property_pointer_set(NULL, &pprop->ptr, pprop->prop, idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr, NULL);
RNA_property_update(C, &pprop->ptr, pprop->prop);
}
else if (st) {
diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c
index a67e6c27acb..04ef2ed8118 100644
--- a/source/blender/editors/space_userpref/userpref_ops.c
+++ b/source/blender/editors/space_userpref/userpref_ops.c
@@ -48,7 +48,7 @@ static int reset_default_theme_exec(bContext *C, wmOperator *UNUSED(op))
UI_theme_init_default();
UI_style_init_default();
WM_event_add_notifier(C, NC_WINDOW, NULL);
-
+ U.runtime.is_dirty = true;
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index afc3b80fe3e..2ce67bfbe4c 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -105,7 +105,8 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
ARegion *ar,
float viewmat[4][4],
float winmat[4][4],
- const rcti *rect)
+ const rcti *rect,
+ bool offscreen)
{
RegionView3D *rv3d = ar->regiondata;
@@ -138,7 +139,7 @@ void ED_view3d_update_viewmat(Depsgraph *depsgraph,
/* calculate GLSL view dependent values */
/* store window coordinates scaling/offset */
- if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ if (!offscreen && rv3d->persp == RV3D_CAMOB && v3d->camera) {
rctf cameraborder;
ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &cameraborder, false);
rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
@@ -184,7 +185,22 @@ static void view3d_main_region_setup_view(Depsgraph *depsgraph,
{
RegionView3D *rv3d = ar->regiondata;
- ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect);
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, rect, false);
+
+ /* set for opengl */
+ GPU_matrix_projection_set(rv3d->winmat);
+ GPU_matrix_set(rv3d->viewmat);
+}
+
+static void view3d_main_region_setup_offscreen(Depsgraph *depsgraph,
+ Scene *scene,
+ View3D *v3d,
+ ARegion *ar,
+ float viewmat[4][4],
+ float winmat[4][4])
+{
+ RegionView3D *rv3d = ar->regiondata;
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, viewmat, winmat, NULL, true);
/* set for opengl */
GPU_matrix_projection_set(rv3d->winmat);
@@ -1480,14 +1496,14 @@ static void view3d_stereo3d_setup_offscreen(Depsgraph *depsgraph,
const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ view3d_main_region_setup_offscreen(depsgraph, scene, v3d, ar, viewmat, winmat);
}
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
float viewmat[4][4];
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ view3d_main_region_setup_offscreen(depsgraph, scene, v3d, ar, viewmat, winmat);
}
}
@@ -1545,7 +1561,7 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph,
view3d_stereo3d_setup_offscreen(depsgraph, scene, v3d, ar, winmat, viewname);
}
else {
- view3d_main_region_setup_view(depsgraph, scene, v3d, ar, viewmat, winmat, NULL);
+ view3d_main_region_setup_offscreen(depsgraph, scene, v3d, ar, viewmat, winmat);
}
/* main drawing call */
@@ -1579,7 +1595,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
int sizex,
int sizey,
uint flag,
- uint draw_flags,
int alpha_mode,
int samples,
const char *viewname,
@@ -1589,7 +1604,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
{
RegionView3D *rv3d = ar->regiondata;
const bool draw_sky = (alpha_mode == R_ADDSKY);
- const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE);
/* view state */
bool is_ortho = false;
@@ -1611,7 +1625,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
if (own_ofs) {
/* bind */
- ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
+ ofs = GPU_offscreen_create(sizex, sizey, samples, true, false, err_out);
if (ofs == NULL) {
DRW_opengl_context_disable();
return NULL;
@@ -1667,120 +1681,28 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
}
}
- if ((samples && use_full_sample) == 0) {
- const bool do_color_management = (ibuf->rect_float == NULL);
- /* Single-pass render, common case */
- ED_view3d_draw_offscreen(depsgraph,
- scene,
- drawtype,
- v3d,
- ar,
- sizex,
- sizey,
- NULL,
- winmat,
- draw_sky,
- !is_ortho,
- viewname,
- do_color_management,
- ofs,
- NULL);
-
- if (ibuf->rect_float) {
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
- }
- else if (ibuf->rect) {
- GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
- }
- }
- else {
- /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling.
- * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */
- static float jit_ofs[32][2];
- float winmat_jitter[4][4];
- float *rect_temp = (ibuf->rect_float) ?
- ibuf->rect_float :
- MEM_mallocN(sizex * sizey * sizeof(float[4]), "rect_temp");
- float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float[4]), "accum_buffer");
- GPUViewport *viewport = GPU_viewport_create_from_offscreen(ofs);
-
- BLI_jitter_init(jit_ofs, samples);
-
- /* first sample buffer, also initializes 'rv3d->persmat' */
- ED_view3d_draw_offscreen(depsgraph,
- scene,
- drawtype,
- v3d,
- ar,
- sizex,
- sizey,
- NULL,
- winmat,
- draw_sky,
- !is_ortho,
- viewname,
- false,
- ofs,
- viewport);
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer);
-
- /* skip the first sample */
- for (int j = 1; j < samples; j++) {
- copy_m4_m4(winmat_jitter, winmat);
- window_translate_m4(winmat_jitter,
- rv3d->persmat,
- (jit_ofs[j][0] * 2.0f) / sizex,
- (jit_ofs[j][1] * 2.0f) / sizey);
-
- ED_view3d_draw_offscreen(depsgraph,
- scene,
- drawtype,
- v3d,
- ar,
- sizex,
- sizey,
- NULL,
- winmat_jitter,
- draw_sky,
- !is_ortho,
- viewname,
- false,
- ofs,
- viewport);
- GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp);
-
- uint i = sizex * sizey * 4;
- while (i--) {
- accum_buffer[i] += rect_temp[i];
- }
- }
-
- {
- /* don't free data owned by 'ofs' */
- GPU_viewport_clear_from_offscreen(viewport);
- GPU_viewport_free(viewport);
- }
+ const bool do_color_management = (ibuf->rect_float == NULL);
+ ED_view3d_draw_offscreen(depsgraph,
+ scene,
+ drawtype,
+ v3d,
+ ar,
+ sizex,
+ sizey,
+ NULL,
+ winmat,
+ draw_sky,
+ !is_ortho,
+ viewname,
+ do_color_management,
+ ofs,
+ NULL);
- if (ibuf->rect_float == NULL) {
- MEM_freeN(rect_temp);
- }
-
- if (ibuf->rect_float) {
- float *rect_float = ibuf->rect_float;
- uint i = sizex * sizey * 4;
- while (i--) {
- rect_float[i] = accum_buffer[i] / samples;
- }
- }
- else {
- uchar *rect_ub = (uchar *)ibuf->rect;
- uint i = sizex * sizey * 4;
- while (i--) {
- rect_ub[i] = (uchar)(255.0f * accum_buffer[i] / samples);
- }
- }
-
- MEM_freeN(accum_buffer);
+ if (ibuf->rect_float) {
+ GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
+ }
+ else if (ibuf->rect) {
+ GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
}
/* unbind */
@@ -1889,7 +1811,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
width,
height,
flag,
- draw_flags,
alpha_mode,
samples,
viewname,
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index e0dbe1f6543..755852a2e18 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -152,13 +152,11 @@ void ED_view3d_clipping_enable(void)
/* *********************** backdraw for selection *************** */
-static void validate_object_select_id(struct Depsgraph *depsgraph,
- Scene *scene,
- ARegion *ar,
- View3D *v3d,
- Object *obact,
- Object *obedit,
- short select_mode)
+/**
+ * \note Only use in object mode.
+ */
+static void validate_object_select_id(
+ struct Depsgraph *depsgraph, Scene *scene, ARegion *ar, View3D *v3d, Object *obact)
{
RegionView3D *rv3d = ar->regiondata;
Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
@@ -178,9 +176,6 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
else if ((obact_eval && (obact_eval->mode & OB_MODE_PARTICLE_EDIT)) && !XRAY_ENABLED(v3d)) {
/* do nothing */
}
- else if ((obedit && (obedit->mode & OB_MODE_EDIT)) && !XRAY_FLAG_ENABLED(v3d)) {
- /* do nothing */
- }
else {
v3d->flag &= ~V3D_INVALID_BACKBUF;
return;
@@ -190,34 +185,18 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
return;
}
-#if 0
- if (test) {
- if (qtest()) {
- addafterqueue(ar->win, BACKBUFDRAW, 1);
- return;
- }
- }
-#endif
-
-#if 0 /* v3d->zbuf deprecated */
- if (v3d->shading.type > OB_WIRE) {
- v3d->zbuf = true;
- }
-#endif
-
- G.f |= G_FLAG_BACKBUFSEL;
-
if (obact_eval && ((obact_eval->base_flag & BASE_VISIBLE) != 0)) {
+ uint dummy_vert_ofs, dummy_edge_ofs, dummy_face_ofs;
DRW_framebuffer_select_id_setup(ar, true);
DRW_draw_select_id_object(scene_eval,
rv3d,
obact_eval,
- select_mode,
+ scene->toolsettings->selectmode,
false,
- 0,
- &bm_vertoffs,
- &bm_wireoffs,
- &bm_solidoffs);
+ 1,
+ &dummy_vert_ofs,
+ &dummy_edge_ofs,
+ &dummy_face_ofs);
DRW_framebuffer_select_id_release(ar);
}
@@ -225,8 +204,6 @@ static void validate_object_select_id(struct Depsgraph *depsgraph,
/* TODO: Create a flag in `DRW_manager` because the drawing is no longer
* made on the backbuffer in this case. */
v3d->flag &= ~V3D_INVALID_BACKBUF;
-
- G.f &= ~G_FLAG_BACKBUFSEL;
}
/* TODO: Creating, attaching texture, and destroying a framebuffer is quite slow.
@@ -251,21 +228,15 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void
GPU_framebuffer_free(tmp_fb);
}
-void ED_view3d_select_id_validate_with_select_mode(ViewContext *vc, short select_mode)
+void ED_view3d_select_id_validate(ViewContext *vc)
{
/* TODO: Create a flag in `DRW_manager` because the drawing is no longer
* made on the backbuffer in this case. */
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
- validate_object_select_id(
- vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact, vc->obedit, select_mode);
+ validate_object_select_id(vc->depsgraph, vc->scene, vc->ar, vc->v3d, vc->obact);
}
}
-void ED_view3d_select_id_validate(ViewContext *vc)
-{
- ED_view3d_select_id_validate_with_select_mode(vc, -1);
-}
-
void ED_view3d_backbuf_depth_validate(ViewContext *vc)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
@@ -281,7 +252,7 @@ void ED_view3d_backbuf_depth_validate(ViewContext *vc)
}
}
-uint *ED_view3d_select_id_read_rect(ViewContext *UNUSED(vc), const rcti *clip, uint *r_buf_len)
+uint *ED_view3d_select_id_read_rect(const rcti *clip, uint *r_buf_len)
{
uint width = BLI_rcti_size_x(clip);
uint height = BLI_rcti_size_y(clip);
@@ -306,25 +277,8 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
return (int)min_ff(ceilf(dist), (float)max_ii(ar->winx, ar->winx));
}
-/* samples a single pixel (copied from vpaint) */
-uint ED_view3d_select_id_sample(ViewContext *vc, int x, int y)
-{
- if (x >= vc->ar->winx || y >= vc->ar->winy) {
- return 0;
- }
-
- uint buf_len;
- uint *buf = ED_view3d_select_id_read(vc, x, y, x, y, &buf_len);
- BLI_assert(0 != buf_len);
- uint ret = buf[0];
- MEM_freeN(buf);
-
- return ret;
-}
-
/* reads full rect, converts indices */
-uint *ED_view3d_select_id_read(
- ViewContext *vc, int xmin, int ymin, int xmax, int ymax, uint *r_buf_len)
+uint *ED_view3d_select_id_read(int xmin, int ymin, int xmax, int ymax, uint *r_buf_len)
{
if (UNLIKELY((xmin > xmax) || (ymin > ymax))) {
return NULL;
@@ -338,7 +292,7 @@ uint *ED_view3d_select_id_read(
};
uint buf_len;
- uint *buf = ED_view3d_select_id_read_rect(vc, &rect, &buf_len);
+ uint *buf = ED_view3d_select_id_read_rect(&rect, &buf_len);
if (r_buf_len) {
*r_buf_len = buf_len;
@@ -347,85 +301,6 @@ uint *ED_view3d_select_id_read(
return buf;
}
-/* smart function to sample a rect spiralling outside, nice for backbuf selection */
-uint ED_view3d_select_id_read_nearest(struct ViewContext *UNUSED(vc),
- const int mval[2],
- const uint id_min,
- const uint id_max,
- uint *r_dist)
-{
- /* Create region around mouse cursor. This must be square and have an odd
- * width, the spiraling algorithm does not work with arbitrary rectangles. */
- rcti rect;
- BLI_rcti_init_pt_radius(&rect, mval, *r_dist);
- rect.xmax += 1;
- rect.ymax += 1;
-
- int width = BLI_rcti_size_x(&rect);
- int height = width;
- BLI_assert(width == height);
-
- /* Read from selection framebuffer. */
- uint *buf = MEM_mallocN(width * height * sizeof(*buf), __func__);
- DRW_framebuffer_select_id_read(&rect, buf);
-
- /* Spiral, starting from center of buffer. */
- int spiral_offset = height * (int)(width / 2) + (height / 2);
- int spiral_direction = 0;
-
- uint index = 0;
-
- for (int nr = 1; nr <= height; nr++) {
- for (int a = 0; a < 2; a++) {
- for (int b = 0; b < nr; b++) {
- /* Find hit within the specified range. */
- uint hit_id = buf[spiral_offset];
-
- if (hit_id && hit_id >= id_min && hit_id < id_max) {
- /* Get x/y from spiral offset. */
- int hit_x = spiral_offset % width;
- int hit_y = spiral_offset / width;
-
- int center_x = width / 2;
- int center_y = height / 2;
-
- /* Manhatten distance in keeping with other screen-based selection. */
- *r_dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
-
- /* Indices start at 1 here. */
- index = (hit_id - id_min) + 1;
- goto exit;
- }
-
- /* Next spiral step. */
- if (spiral_direction == 0) {
- spiral_offset += 1; /* right */
- }
- else if (spiral_direction == 1) {
- spiral_offset -= width; /* down */
- }
- else if (spiral_direction == 2) {
- spiral_offset -= 1; /* left */
- }
- else {
- spiral_offset += width; /* up */
- }
-
- /* Stop if we are outside the buffer. */
- if (spiral_offset < 0 || spiral_offset >= width * height) {
- goto exit;
- }
- }
-
- spiral_direction = (spiral_direction + 1) % 4;
- }
- }
-
-exit:
- MEM_freeN(buf);
- return index;
-}
-
/* ************************************************************* */
static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser)
diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
index 5af6fd8b04b..d39be3d8e20 100644
--- a/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
+++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate.c
@@ -131,7 +131,7 @@ static bool WIDGETGROUP_navigate_poll(const bContext *C, wmGizmoGroupType *UNUSE
return true;
}
-static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
+static void WIDGETGROUP_navigate_setup(const bContext *C, wmGizmoGroup *gzgroup)
{
struct NavigateWidgetGroup *navgroup = MEM_callocN(sizeof(struct NavigateWidgetGroup), __func__);
@@ -227,6 +227,9 @@ static void WIDGETGROUP_navigate_setup(const bContext *UNUSED(C), wmGizmoGroup *
}
/* When dragging an axis, use this instead. */
+ wmWindowManager *wm = CTX_wm_manager(C);
+ gz->keymap = WM_keymap_ensure(
+ wm->defaultconf, "Generic Gizmo Click Drag", SPACE_EMPTY, RGN_TYPE_WINDOW);
gz->drag_part = 0;
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 419ec87eec8..b3b4910c525 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -41,6 +41,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_array.h"
+#include "BLI_bitmap.h"
#include "BLI_math.h"
#include "BLI_lasso_2d.h"
#include "BLI_rect.h"
@@ -88,6 +89,7 @@
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_screen.h"
+#include "ED_select_buffer_utils.h"
#include "ED_select_utils.h"
#include "ED_sculpt.h"
#include "ED_mball.h"
@@ -179,20 +181,96 @@ static bool object_deselect_all_except(ViewLayer *view_layer, Base *b)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Internal Edit-Mesh Select Buffer Wrapper
+ *
+ * Avoid duplicate code when using edit-mode selection,
+ * actual logic is handled outside of this function.
+ *
+ * \note Currently this #EDBMSelectID_Context which is mesh specific
+ * however the logic could also be used for non-meshes too.
+ *
+ * \{ */
+
+struct EditSelectBuf_Cache {
+ Base **bases;
+ uint bases_len;
+ struct EDBMSelectID_Context *sel_id_ctx;
+ BLI_bitmap *select_bitmap;
+};
+
+static void editselect_buf_cache_init(struct EditSelectBuf_Cache *esel, ViewContext *vc)
+{
+ if (vc->obedit) {
+ esel->bases = BKE_view_layer_array_from_bases_in_edit_mode(
+ vc->view_layer, vc->v3d, &esel->bases_len);
+ }
+ else {
+ /* Use for paint modes, currently only a single object at a time. */
+ if (vc->obact) {
+ esel->bases = MEM_mallocN(sizeof(esel->bases), __func__);
+ esel->bases[0] = BKE_view_layer_base_find(vc->view_layer, vc->obact);
+ esel->bases_len = 1;
+ }
+ else {
+ esel->bases = NULL;
+ esel->bases_len = 0;
+ }
+ }
+ esel->sel_id_ctx = EDBM_select_id_context_create(
+ vc, esel->bases, esel->bases_len, vc->scene->toolsettings->selectmode);
+ for (int i = 0; i < esel->bases_len; i++) {
+ esel->bases[i]->object->runtime.select_id = i;
+ }
+}
+
+static void editselect_buf_cache_free(struct EditSelectBuf_Cache *esel)
+{
+ if (esel->sel_id_ctx) {
+ EDBM_select_id_context_destroy(esel->sel_id_ctx);
+ }
+ MEM_SAFE_FREE(esel->select_bitmap);
+ MEM_SAFE_FREE(esel->bases);
+}
+
+static void editselect_buf_cache_free_voidp(void *esel_voidp)
+{
+ editselect_buf_cache_free(esel_voidp);
+ MEM_freeN(esel_voidp);
+}
+
+static void editselect_buf_cache_init_with_generic_userdata(wmGenericUserData *wm_userdata,
+ ViewContext *vc)
+{
+ struct EditSelectBuf_Cache *esel = MEM_callocN(sizeof(*esel), __func__);
+ wm_userdata->data = esel;
+ wm_userdata->free_fn = editselect_buf_cache_free_voidp;
+ wm_userdata->use_free = true;
+ editselect_buf_cache_init(esel, vc);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Internal Edit-Mesh Utilities
* \{ */
-static bool edbm_backbuf_check_and_select_verts(BMEditMesh *em, const eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel,
+ Object *ob,
+ BMEditMesh *em,
+ const eSelectOp sel_op)
{
BMVert *eve;
BMIter iter;
- uint index = bm_wireoffs;
bool changed = false;
+ const BLI_bitmap *select_bitmap = esel->select_bitmap;
+ uint index = EDBM_select_id_context_offset_for_object_elem(
+ esel->sel_id_ctx, ob->runtime.select_id, BM_VERT);
+
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
const bool is_select = BM_elem_flag_test(eve, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_vert_select_set(em->bm, eve, sel_op_result);
@@ -204,17 +282,23 @@ static bool edbm_backbuf_check_and_select_verts(BMEditMesh *em, const eSelectOp
return changed;
}
-static bool edbm_backbuf_check_and_select_edges(BMEditMesh *em, const eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel,
+ Object *ob,
+ BMEditMesh *em,
+ const eSelectOp sel_op)
{
BMEdge *eed;
BMIter iter;
- uint index = bm_solidoffs;
bool changed = false;
+ const BLI_bitmap *select_bitmap = esel->select_bitmap;
+ uint index = EDBM_select_id_context_offset_for_object_elem(
+ esel->sel_id_ctx, ob->runtime.select_id, BM_EDGE);
+
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_edge_select_set(em->bm, eed, sel_op_result);
@@ -226,17 +310,23 @@ static bool edbm_backbuf_check_and_select_edges(BMEditMesh *em, const eSelectOp
return changed;
}
-static bool edbm_backbuf_check_and_select_faces(BMEditMesh *em, const eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel,
+ Object *ob,
+ BMEditMesh *em,
+ const eSelectOp sel_op)
{
BMFace *efa;
BMIter iter;
- uint index = 1;
bool changed = false;
+ const BLI_bitmap *select_bitmap = esel->select_bitmap;
+ uint index = EDBM_select_id_context_offset_for_object_elem(
+ esel->sel_id_ctx, ob->runtime.select_id, BM_FACE);
+
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
const bool is_select = BM_elem_flag_test(efa, BM_ELEM_SELECT);
- const bool is_inside = EDBM_backbuf_check(index);
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_face_select_set(em->bm, efa, sel_op_result);
@@ -249,17 +339,21 @@ static bool edbm_backbuf_check_and_select_faces(BMEditMesh *em, const eSelectOp
}
/* object mode, edbm_ prefix is confusing here, rename? */
-static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me,
+ struct EditSelectBuf_Cache *esel,
+ const eSelectOp sel_op)
{
MVert *mv = me->mvert;
uint index;
bool changed = false;
+ const BLI_bitmap *select_bitmap = esel->select_bitmap;
+
if (mv) {
- for (index = 1; index <= me->totvert; index++, mv++) {
+ for (index = 0; index < me->totvert; index++, mv++) {
if (!(mv->flag & ME_HIDE)) {
const bool is_select = mv->flag & SELECT;
- const bool is_inside = EDBM_backbuf_check(index);
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(mv->flag, sel_op_result, SELECT);
@@ -272,17 +366,21 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, const eSelectOp
}
/* object mode, edbm_ prefix is confusing here, rename? */
-static bool edbm_backbuf_check_and_select_tfaces(Mesh *me, const eSelectOp sel_op)
+static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me,
+ struct EditSelectBuf_Cache *esel,
+ const eSelectOp sel_op)
{
MPoly *mpoly = me->mpoly;
uint index;
bool changed = false;
+ const BLI_bitmap *select_bitmap = esel->select_bitmap;
+
if (mpoly) {
- for (index = 1; index <= me->totpoly; index++, mpoly++) {
+ for (index = 0; index < me->totpoly; index++, mpoly++) {
if (!(mpoly->flag & ME_HIDE)) {
const bool is_select = mpoly->flag & ME_FACE_SEL;
- const bool is_inside = EDBM_backbuf_check(index);
+ const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
@@ -621,14 +719,26 @@ static void do_lasso_select_mesh__doSelectVert(void *userData,
data->is_changed = true;
}
}
-static void do_lasso_select_mesh__doSelectEdge_pass0(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
-{
- LassoSelectUserData *data = userData;
+struct LassoSelectUserData_ForMeshEdge {
+ LassoSelectUserData *data;
+ struct EditSelectBuf_Cache *esel;
+ uint backbuf_offset;
+};
+static void do_lasso_select_mesh__doSelectEdge_pass0(void *user_data,
+ BMEdge *eed,
+ const float screen_co_a[2],
+ const float screen_co_b[2],
+ int index)
+{
+ struct LassoSelectUserData_ForMeshEdge *data_for_edge = user_data;
+ LassoSelectUserData *data = data_for_edge->data;
+ const bool is_visible = (data_for_edge->esel ?
+ BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap,
+ data_for_edge->backbuf_offset + index) :
+ true);
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
const bool is_inside =
- (EDBM_backbuf_check(bm_solidoffs + index) &&
- edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
+ (is_visible && edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) &&
BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_a), IS_CLIPPED) &&
BLI_lasso_is_point_inside(data->mcords, data->moves, UNPACK2(screen_co_b), IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
@@ -638,15 +748,24 @@ static void do_lasso_select_mesh__doSelectEdge_pass0(
data->is_changed = true;
}
}
-static void do_lasso_select_mesh__doSelectEdge_pass1(
- void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
+static void do_lasso_select_mesh__doSelectEdge_pass1(void *user_data,
+ BMEdge *eed,
+ const float screen_co_a[2],
+ const float screen_co_b[2],
+ int index)
{
- LassoSelectUserData *data = userData;
+ struct LassoSelectUserData_ForMeshEdge *data_for_edge = user_data;
+ LassoSelectUserData *data = data_for_edge->data;
+ const bool is_visible = (data_for_edge->esel ?
+ BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap,
+ data_for_edge->backbuf_offset + index) :
+ true);
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside =
- (EDBM_backbuf_check(bm_solidoffs + index) &&
- BLI_lasso_is_edge_inside(
- data->mcords, data->moves, UNPACK2(screen_co_a), UNPACK2(screen_co_b), IS_CLIPPED));
+ const bool is_inside = (is_visible && BLI_lasso_is_edge_inside(data->mcords,
+ data->moves,
+ UNPACK2(screen_co_a),
+ UNPACK2(screen_co_b),
+ IS_CLIPPED));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
@@ -672,6 +791,7 @@ static void do_lasso_select_mesh__doSelectFace(void *userData,
}
static bool do_lasso_select_mesh(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const int mcords[][2],
short moves,
const eSelectOp sel_op)
@@ -679,7 +799,6 @@ static bool do_lasso_select_mesh(ViewContext *vc,
LassoSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
rcti rect;
- int bbsel;
/* set editmesh */
vc->em = BKE_editmesh_from_object(vc->obedit);
@@ -699,12 +818,22 @@ static bool do_lasso_select_mesh(ViewContext *vc,
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
GPU_matrix_set(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_mask_init(
- vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+
+ const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
+
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ if (use_zbuf) {
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
+ }
+ }
if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
+ if (use_zbuf) {
+ data.is_changed |= edbm_backbuf_check_and_select_verts(esel, vc->obedit, vc->em, sel_op);
}
else {
mesh_foreachScreenVert(
@@ -712,18 +841,26 @@ static bool do_lasso_select_mesh(ViewContext *vc,
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
- /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+ /* Does both use_zbuf and non-use_zbuf versions (need screen cos for both) */
+ struct LassoSelectUserData_ForMeshEdge data_for_edge = {
+ .data = &data,
+ .esel = use_zbuf ? esel : NULL,
+ .backbuf_offset = use_zbuf ?
+ EDBM_select_id_context_offset_for_object_elem(
+ esel->sel_id_ctx, vc->obedit->runtime.select_id, BM_EDGE) :
+ 0,
+ };
mesh_foreachScreenEdge(
- vc, do_lasso_select_mesh__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ vc, do_lasso_select_mesh__doSelectEdge_pass0, &data_for_edge, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == false) {
mesh_foreachScreenEdge(
- vc, do_lasso_select_mesh__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ vc, do_lasso_select_mesh__doSelectEdge_pass1, &data_for_edge, V3D_PROJ_TEST_CLIP_NEAR);
}
}
if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
+ if (use_zbuf) {
+ data.is_changed |= edbm_backbuf_check_and_select_faces(esel, vc->obedit, vc->em, sel_op);
}
else {
mesh_foreachScreenFace(
@@ -731,8 +868,6 @@ static bool do_lasso_select_mesh(ViewContext *vc,
}
}
- EDBM_backbuf_free();
-
if (data.is_changed) {
EDBM_selectmode_flush(vc->em);
}
@@ -973,6 +1108,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData,
}
}
static bool do_lasso_select_paintvert(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const int mcords[][2],
short moves,
const eSelectOp sel_op)
@@ -994,14 +1130,20 @@ static bool do_lasso_select_paintvert(ViewContext *vc,
BLI_lasso_boundbox(&rect, mcords, moves);
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
if (use_zbuf) {
- bm_vertoffs = me->totvert + 1; /* max index array */
-
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
- changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
+ }
+ }
- EDBM_backbuf_free();
+ if (use_zbuf) {
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op);
+ }
}
else {
LassoSelectUserData data;
@@ -1023,9 +1165,11 @@ static bool do_lasso_select_paintvert(ViewContext *vc,
paintvert_flush_flags(ob);
paintvert_tag_select_update(vc->C, ob);
}
+
return changed;
}
static bool do_lasso_select_paintface(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const int mcords[][2],
short moves,
const eSelectOp sel_op)
@@ -1038,19 +1182,25 @@ static bool do_lasso_select_paintface(ViewContext *vc,
return false;
}
- bm_vertoffs = me->totpoly + 1; /* max index array */
-
- BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
-
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
/* flush selection at the end */
changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
}
- changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
- EDBM_backbuf_free();
+ BLI_lasso_boundbox(&rect, mcords, moves);
+
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ if (esel == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_poly(buffer_len, mcords, moves, &rect);
+ }
+
+ if (esel->select_bitmap) {
+ changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op);
+ }
if (changed) {
paintface_flush_flags(vc->C, ob, SELECT);
@@ -1098,12 +1248,15 @@ static bool view3d_lasso_select(
Object *ob = CTX_data_active_object(C);
bool changed_multi = false;
+ wmGenericUserData wm_userdata_buf = {0};
+ wmGenericUserData *wm_userdata = &wm_userdata_buf;
+
if (vc->obedit == NULL) { /* Object Mode */
if (BKE_paint_select_face_test(ob)) {
- changed_multi |= do_lasso_select_paintface(vc, mcords, moves, sel_op);
+ changed_multi |= do_lasso_select_paintface(vc, wm_userdata, mcords, moves, sel_op);
}
else if (BKE_paint_select_vert_test(ob)) {
- changed_multi |= do_lasso_select_paintvert(vc, mcords, moves, sel_op);
+ changed_multi |= do_lasso_select_paintvert(vc, wm_userdata, mcords, moves, sel_op);
}
else if (ob &&
(ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
@@ -1120,14 +1273,13 @@ static bool view3d_lasso_select(
}
}
else { /* Edit Mode */
-
FOREACH_OBJECT_IN_MODE_BEGIN (vc->view_layer, vc->v3d, ob->type, ob->mode, ob_iter) {
ED_view3d_viewcontext_init_object(vc, ob_iter);
bool changed = false;
switch (vc->obedit->type) {
case OB_MESH:
- changed = do_lasso_select_mesh(vc, mcords, moves, sel_op);
+ changed = do_lasso_select_mesh(vc, wm_userdata, mcords, moves, sel_op);
break;
case OB_CURVE:
case OB_SURF:
@@ -1155,6 +1307,9 @@ static bool view3d_lasso_select(
}
FOREACH_OBJECT_IN_MODE_END;
}
+
+ WM_generic_user_data_free(wm_userdata);
+
return changed_multi;
}
@@ -2336,9 +2491,13 @@ static void do_paintvert_box_select__doSelectVert(void *userData,
data->is_changed = true;
}
}
-static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSelectOp sel_op)
+static bool do_paintvert_box_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
+ const rcti *rect,
+ const eSelectOp sel_op)
{
const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
+
Mesh *me;
me = vc->obact->data;
@@ -2355,48 +2514,16 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe
/* pass */
}
else if (use_zbuf) {
- MVert *mvert;
- uint *rt, *buf, buf_len;
- int a, index;
- char *selar;
-
- selar = MEM_callocN(me->totvert + 1, "selar");
-
- ED_view3d_select_id_validate(vc);
- buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len);
-
- rt = buf;
-
- a = buf_len;
- while (a--) {
- if (*rt) {
- index = *rt;
- if (index <= me->totvert) {
- selar[index] = 1;
- }
- }
- rt++;
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
}
-
- mvert = me->mvert;
- for (a = 1; a <= me->totvert; a++, mvert++) {
- if ((mvert->flag & ME_HIDE) == 0) {
- const bool is_select = mvert->flag & SELECT;
- const bool is_inside = (selar[a] != 0);
- const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
- if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mvert->flag, sel_op_result, SELECT);
- changed = true;
- }
- }
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op);
}
-
- MEM_freeN(buf);
- MEM_freeN(selar);
-
-#ifdef __APPLE__
- glReadBuffer(GL_BACK);
-#endif
}
else {
BoxSelectUserData data;
@@ -2420,6 +2547,46 @@ static bool do_paintvert_box_select(ViewContext *vc, const rcti *rect, const eSe
return changed;
}
+static bool do_paintface_box_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
+ const rcti *rect,
+ int sel_op)
+{
+ Object *ob = vc->obact;
+ Mesh *me;
+
+ me = BKE_mesh_from_object(ob);
+ if ((me == NULL) || (me->totpoly == 0)) {
+ return false;
+ }
+
+ bool changed = false;
+ if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
+ changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false);
+ }
+
+ if (BLI_rcti_is_empty(rect)) {
+ /* pass */
+ }
+ else {
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
+ }
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op);
+ }
+ }
+
+ if (changed) {
+ paintface_flush_flags(vc->C, vc->obact, SELECT);
+ }
+ return changed;
+}
+
static void do_nurbs_box_select__doSelect(void *userData,
Nurb *UNUSED(nu),
BPoint *bp,
@@ -2520,12 +2687,22 @@ static void do_mesh_box_select__doSelectVert(void *userData,
data->is_changed = true;
}
}
+struct BoxSelectUserData_ForMeshEdge {
+ BoxSelectUserData *data;
+ struct EditSelectBuf_Cache *esel;
+ uint backbuf_offset;
+};
static void do_mesh_box_select__doSelectEdge_pass0(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
- BoxSelectUserData *data = userData;
+ struct BoxSelectUserData_ForMeshEdge *data_for_edge = userData;
+ BoxSelectUserData *data = data_for_edge->data;
+ const bool is_visible = (data_for_edge->esel ?
+ BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap,
+ data_for_edge->backbuf_offset + index) :
+ true);
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (EDBM_backbuf_check(bm_solidoffs + index) &&
+ const bool is_inside = (is_visible &&
edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
@@ -2537,10 +2714,14 @@ static void do_mesh_box_select__doSelectEdge_pass0(
static void do_mesh_box_select__doSelectEdge_pass1(
void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index)
{
- BoxSelectUserData *data = userData;
+ struct BoxSelectUserData_ForMeshEdge *data_for_edge = userData;
+ BoxSelectUserData *data = data_for_edge->data;
+ const bool is_visible = (data_for_edge->esel ?
+ BLI_BITMAP_TEST_BOOL(data_for_edge->esel->select_bitmap,
+ data_for_edge->backbuf_offset + index) :
+ true);
const bool is_select = BM_elem_flag_test(eed, BM_ELEM_SELECT);
- const bool is_inside = (EDBM_backbuf_check(bm_solidoffs + index) &&
- edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
+ const bool is_inside = (is_visible && edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b));
const int sel_op_result = ED_select_op_action_deselected(data->sel_op, is_select, is_inside);
if (sel_op_result != -1) {
BM_edge_select_set(data->vc->em->bm, eed, sel_op_result);
@@ -2561,11 +2742,13 @@ static void do_mesh_box_select__doSelectFace(void *userData,
data->is_changed = true;
}
}
-static bool do_mesh_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_op)
+static bool do_mesh_box_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
+ const rcti *rect,
+ const eSelectOp sel_op)
{
BoxSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
- int bbsel;
view3d_userdata_boxselect_init(&data, vc, rect, sel_op);
@@ -2580,11 +2763,22 @@ static bool do_mesh_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
GPU_matrix_set(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_init(vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+
+ const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
+
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ if (use_zbuf) {
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_rect(buffer_len, rect);
+ }
+ }
if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_verts(vc->em, sel_op);
+ if (use_zbuf) {
+ data.is_changed |= edbm_backbuf_check_and_select_verts(esel, vc->obedit, vc->em, sel_op);
}
else {
mesh_foreachScreenVert(
@@ -2592,18 +2786,26 @@ static bool do_mesh_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
- /* Does both bbsel and non-bbsel versions (need screen cos for both) */
+ /* Does both use_zbuf and non-use_zbuf versions (need screen cos for both) */
+ struct BoxSelectUserData_ForMeshEdge cb_data = {
+ .data = &data,
+ .esel = use_zbuf ? esel : NULL,
+ .backbuf_offset = use_zbuf ?
+ EDBM_select_id_context_offset_for_object_elem(
+ esel->sel_id_ctx, vc->obedit->runtime.select_id, BM_EDGE) :
+ 0,
+ };
mesh_foreachScreenEdge(
- vc, do_mesh_box_select__doSelectEdge_pass0, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ vc, do_mesh_box_select__doSelectEdge_pass0, &cb_data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == false) {
mesh_foreachScreenEdge(
- vc, do_mesh_box_select__doSelectEdge_pass1, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ vc, do_mesh_box_select__doSelectEdge_pass1, &cb_data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- data.is_changed |= edbm_backbuf_check_and_select_faces(vc->em, sel_op);
+ if (use_zbuf) {
+ data.is_changed |= edbm_backbuf_check_and_select_faces(esel, vc->obedit, vc->em, sel_op);
}
else {
mesh_foreachScreenFace(
@@ -2611,8 +2813,6 @@ static bool do_mesh_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel_
}
}
- EDBM_backbuf_free();
-
if (data.is_changed) {
EDBM_selectmode_flush(vc->em);
}
@@ -2930,6 +3130,9 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
rcti rect;
bool changed_multi = false;
+ wmGenericUserData wm_userdata_buf = {0};
+ wmGenericUserData *wm_userdata = &wm_userdata_buf;
+
view3d_operator_needs_opengl(C);
BKE_object_update_select_id(CTX_data_main(C));
@@ -2940,7 +3143,6 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
WM_operator_properties_border_to_rcti(op, &rect);
if (vc.obedit) {
-
FOREACH_OBJECT_IN_MODE_BEGIN (
vc.view_layer, vc.v3d, vc.obedit->type, vc.obedit->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
@@ -2949,7 +3151,7 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
switch (vc.obedit->type) {
case OB_MESH:
vc.em = BKE_editmesh_from_object(vc.obedit);
- changed = do_mesh_box_select(&vc, &rect, sel_op);
+ changed = do_mesh_box_select(&vc, wm_userdata, &rect, sel_op);
if (changed) {
DEG_id_tag_update(vc.obedit->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
@@ -2999,10 +3201,10 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
C, &vc, &rect, sel_op == SEL_OP_ADD ? true : false);
}
else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
- changed_multi = do_paintface_box_select(&vc, &rect, sel_op);
+ changed_multi = do_paintface_box_select(&vc, wm_userdata, &rect, sel_op);
}
else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
- changed_multi = do_paintvert_box_select(&vc, &rect, sel_op);
+ changed_multi = do_paintvert_box_select(&vc, wm_userdata, &rect, sel_op);
}
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
changed_multi = PE_box_select(C, &rect, sel_op);
@@ -3015,6 +3217,8 @@ static int view3d_box_select_exec(bContext *C, wmOperator *op)
}
}
+ WM_generic_user_data_free(wm_userdata);
+
if (changed_multi) {
return OPERATOR_FINISHED;
}
@@ -3120,10 +3324,13 @@ static void mesh_circle_doSelectFace(void *userData,
}
}
-static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval[2], float rad)
+static bool mesh_circle_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
+ eSelectOp sel_op,
+ const int mval[2],
+ float rad)
{
ToolSettings *ts = vc->scene->toolsettings;
- int bbsel;
CircleSelectUserData data;
vc->em = BKE_editmesh_from_object(vc->obedit);
@@ -3136,14 +3343,30 @@ static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval
}
const bool select = (sel_op != SEL_OP_SUB);
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
+ const bool use_zbuf = !XRAY_FLAG_ENABLED(vc->v3d);
+
+ if (use_zbuf) {
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ }
+ }
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+
+ if (use_zbuf) {
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
+ }
+
if (ts->selectmode & SCE_SELECT_VERTEX) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_verts(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ if (use_zbuf) {
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_verts(
+ esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
}
else {
mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -3151,8 +3374,11 @@ static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval
}
if (ts->selectmode & SCE_SELECT_EDGE) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_edges(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ if (use_zbuf) {
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_edges(
+ esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
}
else {
mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
@@ -3160,17 +3386,25 @@ static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval
}
if (ts->selectmode & SCE_SELECT_FACE) {
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_faces(vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ if (use_zbuf) {
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_faces(
+ esel, vc->obedit, vc->em, select ? SEL_OP_ADD : SEL_OP_SUB);
+ }
}
else {
mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
- changed |= data.is_changed;
+ if (use_zbuf) {
+ if (esel->select_bitmap != NULL) {
+ MEM_freeN(esel->select_bitmap);
+ esel->select_bitmap = NULL;
+ }
+ }
- EDBM_backbuf_free();
+ changed |= data.is_changed;
if (changed) {
EDBM_selectmode_flush(vc->em);
@@ -3179,6 +3413,7 @@ static bool mesh_circle_select(ViewContext *vc, eSelectOp sel_op, const int mval
}
static bool paint_facesel_circle_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const eSelectOp sel_op,
const int mval[2],
float rad)
@@ -3186,7 +3421,6 @@ static bool paint_facesel_circle_select(ViewContext *vc,
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
Object *ob = vc->obact;
Mesh *me = ob->data;
- bool bbsel;
bool changed = false;
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
@@ -3194,13 +3428,21 @@ static bool paint_facesel_circle_select(ViewContext *vc,
changed |= paintface_deselect_all_visible(vc->C, ob, SEL_DESELECT, false);
}
- bm_vertoffs = me->totpoly + 1; /* max index array */
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ }
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_tfaces(me, sel_op);
- EDBM_backbuf_free();
+ {
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op);
+ MEM_freeN(esel->select_bitmap);
+ esel->select_bitmap = NULL;
+ }
}
+
if (changed) {
paintface_flush_flags(vc->C, ob, SELECT);
}
@@ -3220,6 +3462,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData,
}
}
static bool paint_vertsel_circle_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const eSelectOp sel_op,
const int mval[2],
float rad)
@@ -3228,7 +3471,6 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
const bool use_zbuf = !XRAY_ENABLED(vc->v3d);
Object *ob = vc->obact;
Mesh *me = ob->data;
- bool bbsel;
/* CircleSelectUserData data = {NULL}; */ /* UNUSED */
bool changed = false;
@@ -3240,12 +3482,19 @@ static bool paint_vertsel_circle_select(ViewContext *vc,
const bool select = (sel_op != SEL_OP_SUB);
if (use_zbuf) {
- bm_vertoffs = me->totvert + 1; /* max index array */
+ if (wm_userdata->data == NULL) {
+ editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc);
+ }
+ }
- bbsel = EDBM_backbuf_circle_init(vc, mval[0], mval[1], (short)(rad + 1.0f));
- if (bbsel) {
- changed |= edbm_backbuf_check_and_select_verts_obmode(me, sel_op);
- EDBM_backbuf_free();
+ if (use_zbuf) {
+ struct EditSelectBuf_Cache *esel = wm_userdata->data;
+ const uint buffer_len = EDBM_select_id_context_elem_len(esel->sel_id_ctx);
+ esel->select_bitmap = ED_select_buffer_bitmap_from_circle(buffer_len, mval, (int)(rad + 1.0f));
+ if (esel->select_bitmap != NULL) {
+ changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op);
+ MEM_freeN(esel->select_bitmap);
+ esel->select_bitmap = NULL;
}
}
else {
@@ -3593,27 +3842,40 @@ static bool mball_circle_select(ViewContext *vc,
/** Callbacks for circle selection in Editmode */
static bool obedit_circle_select(ViewContext *vc,
+ wmGenericUserData *wm_userdata,
const eSelectOp sel_op,
const int mval[2],
float rad)
{
+ bool changed = false;
BLI_assert(ELEM(sel_op, SEL_OP_SET, SEL_OP_ADD, SEL_OP_SUB));
switch (vc->obedit->type) {
case OB_MESH:
- return mesh_circle_select(vc, sel_op, mval, rad);
+ changed = mesh_circle_select(vc, wm_userdata, sel_op, mval, rad);
+ break;
case OB_CURVE:
case OB_SURF:
- return nurbscurve_circle_select(vc, sel_op, mval, rad);
+ changed = nurbscurve_circle_select(vc, sel_op, mval, rad);
+ break;
case OB_LATTICE:
- return lattice_circle_select(vc, sel_op, mval, rad);
+ changed = lattice_circle_select(vc, sel_op, mval, rad);
+ break;
case OB_ARMATURE:
- return armature_circle_select(vc, sel_op, mval, rad);
+ changed = armature_circle_select(vc, sel_op, mval, rad);
+ break;
case OB_MBALL:
- return mball_circle_select(vc, sel_op, mval, rad);
+ changed = mball_circle_select(vc, sel_op, mval, rad);
+ break;
default:
BLI_assert(0);
- return false;
+ break;
}
+
+ if (changed) {
+ DEG_id_tag_update(vc->obact->data, ID_RECALC_SELECT);
+ WM_main_add_notifier(NC_GEOM | ND_SELECT, vc->obact->data);
+ }
+ return changed;
}
static bool object_circle_select(ViewContext *vc,
@@ -3662,8 +3924,13 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
const int radius = RNA_int_get(op->ptr, "radius");
const int mval[2] = {RNA_int_get(op->ptr, "x"), RNA_int_get(op->ptr, "y")};
+ /* Allow each selection type to allocate their own data thats used between executions. */
+ wmGesture *gesture = op->customdata; /* NULL when non-modal. */
+ wmGenericUserData wm_userdata_buf = {0};
+ wmGenericUserData *wm_userdata = gesture ? &gesture->user_data : &wm_userdata_buf;
+
const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"),
- WM_gesture_is_modal_first(op->customdata));
+ WM_gesture_is_modal_first(gesture));
ED_view3d_viewcontext_init(C, &vc);
@@ -3672,7 +3939,9 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
if (obedit || BKE_paint_select_elem_test(obact) || (obact && (obact->mode & OB_MODE_POSE))) {
view3d_operator_needs_opengl(C);
- BKE_object_update_select_id(CTX_data_main(C));
+ if (obedit == NULL) {
+ BKE_object_update_select_id(CTX_data_main(C));
+ }
FOREACH_OBJECT_IN_MODE_BEGIN (vc.view_layer, vc.v3d, obact->type, obact->mode, ob_iter) {
ED_view3d_viewcontext_init_object(&vc, ob_iter);
@@ -3681,16 +3950,13 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
obedit = vc.obedit;
if (obedit) {
- if (obedit_circle_select(&vc, sel_op, mval, (float)radius)) {
- DEG_id_tag_update(obact->data, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
- }
+ obedit_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius);
}
else if (BKE_paint_select_face_test(obact)) {
- paint_facesel_circle_select(&vc, sel_op, mval, (float)radius);
+ paint_facesel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius);
}
else if (BKE_paint_select_vert_test(obact)) {
- paint_vertsel_circle_select(&vc, sel_op, mval, (float)radius);
+ paint_vertsel_circle_select(&vc, wm_userdata, sel_op, mval, (float)radius);
}
else if (obact->mode & OB_MODE_POSE) {
pose_circle_select(&vc, sel_op, mval, (float)radius);
@@ -3717,6 +3983,11 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
}
}
+ /* Otherwise this is freed by the gesture. */
+ if (wm_userdata == &wm_userdata_buf) {
+ WM_generic_user_data_free(wm_userdata);
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 2454358b687..5865efa0ffa 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -428,7 +428,7 @@ void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *ar)
* can use them without redrawing first */
Depsgraph *depsgraph = CTX_data_depsgraph(C);
Scene *scene = CTX_data_scene(C);
- ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, NULL, NULL, NULL);
+ ED_view3d_update_viewmat(depsgraph, scene, v3d, ar, NULL, NULL, NULL, false);
}
}
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 09f198ff14c..c3acd604ee1 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -4835,6 +4835,7 @@ static void initNormalRotation(TransInfo *t)
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
+ BKE_editmesh_ensure_autosmooth(em);
BKE_editmesh_lnorspace_update(em);
storeCustomLNorValue(tc, bm);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 758551be0b5..6a9c6856a03 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1177,12 +1177,7 @@ static void recalcData_sequencer(TransInfo *t)
Sequence *seq = tdsq->seq;
if (seq != seq_prev) {
- if (BKE_sequence_tx_fullupdate_test(seq)) {
- BKE_sequence_invalidate_cache(t->scene, seq);
- }
- else {
- BKE_sequence_invalidate_cache(t->scene, seq);
- }
+ BKE_sequence_invalidate_cache_composite(t->scene, seq);
}
seq_prev = seq;
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index e43379dc358..68885a72092 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -1661,7 +1661,12 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
else if (tref && STREQ(tref->idname, "builtin.scale")) {
ggd->twtype |= V3D_GIZMO_SHOW_OBJECT_SCALE;
}
+ else if (tref && STREQ(tref->idname, "builtin.transform")) {
+ ggd->twtype = V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE |
+ V3D_GIZMO_SHOW_OBJECT_SCALE;
+ }
else {
+ /* This is also correct logic for 'builtin.transform', no special check needed. */
/* Setup all gizmos, they can be toggled via 'ToolSettings.gizmo_flag' */
ggd->twtype = V3D_GIZMO_SHOW_OBJECT_TRANSLATE | V3D_GIZMO_SHOW_OBJECT_ROTATE |
V3D_GIZMO_SHOW_OBJECT_SCALE;
@@ -1852,7 +1857,10 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
}
}
-static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C, wmGizmoGroup *gzgroup, wmGizmo *gz)
+static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
+ wmGizmoGroup *gzgroup,
+ wmGizmo *gz,
+ const wmEvent *UNUSED(event))
{
GizmoGroup *ggd = gzgroup->customdata;
@@ -1971,12 +1979,12 @@ static bool WIDGETGROUP_gizmo_poll_tool(const struct bContext *C, struct wmGizmo
return true;
}
-/* Expose as multiple gizmos so tools use one, persistant context another.
+/* Expose as multiple gizmos so tools use one, persistent context another.
* Needed because they use different options which isn't so simple to dynamically update. */
void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Gizmo";
+ gzgt->name = "3D View: Transform Gizmo";
gzgt->idname = "VIEW3D_GGT_xform_gizmo";
gzgt->flag = WM_GIZMOGROUPTYPE_3D;
@@ -1990,12 +1998,26 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
gzgt->message_subscribe = WIDGETGROUP_gizmo_message_subscribe;
gzgt->draw_prepare = WIDGETGROUP_gizmo_draw_prepare;
gzgt->invoke_prepare = WIDGETGROUP_gizmo_invoke_prepare;
+
+ static const EnumPropertyItem rna_enum_gizmo_items[] = {
+ {V3D_GIZMO_SHOW_OBJECT_TRANSLATE, "TRANSLATE", 0, "Move", ""},
+ {V3D_GIZMO_SHOW_OBJECT_ROTATE, "ROTATE", 0, "Rotate", ""},
+ {V3D_GIZMO_SHOW_OBJECT_SCALE, "SCALE", 0, "Scale", ""},
+ {0, "NONE", 0, "None", ""},
+ {0, NULL, 0, NULL, NULL},
+ };
+ RNA_def_enum(gzgt->srna,
+ "drag_action",
+ rna_enum_gizmo_items,
+ V3D_GIZMO_SHOW_OBJECT_TRANSLATE,
+ "Drag Action",
+ "");
}
/** Only poll, flag & gzmap_params differ. */
void VIEW3D_GGT_xform_gizmo_context(wmGizmoGroupType *gzgt)
{
- gzgt->name = "Transform Gizmo Context";
+ gzgt->name = "3D View: Transform Gizmo Context";
gzgt->idname = "VIEW3D_GGT_xform_gizmo_context";
gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_PERSISTENT;
diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
index 47a584561f9..24ef92b3153 100644
--- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c
@@ -385,7 +385,8 @@ static void gizmo_mesh_extrude_draw_prepare(const bContext *C, wmGizmoGroup *gzg
static void gizmo_mesh_extrude_invoke_prepare(const bContext *UNUSED(C),
wmGizmoGroup *gzgroup,
- wmGizmo *gz)
+ wmGizmo *gz,
+ const wmEvent *UNUSED(event))
{
GizmoExtrudeGroup *ggd = gzgroup->customdata;
if (ELEM(gz, ggd->adjust[0], ggd->adjust[1])) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 8606cd19c96..f028f2dc506 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -1170,7 +1170,7 @@ static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot)
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
- ot->poll = ED_operator_editmesh_auto_smooth;
+ ot->poll = ED_operator_editmesh;
RNA_def_float_rotation(
ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
@@ -1210,6 +1210,60 @@ static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
+static int transform_from_gizmo_invoke(bContext *C,
+ wmOperator *UNUSED(op),
+ const wmEvent *UNUSED(event))
+{
+ bToolRef *tref = WM_toolsystem_ref_from_context(C);
+ if (tref) {
+ ARegion *ar = CTX_wm_region(C);
+ wmGizmoMap *gzmap = ar->gizmo_map;
+ wmGizmoGroup *gzgroup = gzmap ? WM_gizmomap_group_find(gzmap, "VIEW3D_GGT_xform_gizmo") : NULL;
+ if (gzgroup != NULL) {
+ PointerRNA gzg_ptr;
+ WM_toolsystem_ref_properties_ensure_from_gizmo_group(tref, gzgroup->type, &gzg_ptr);
+ const int drag_action = RNA_enum_get(&gzg_ptr, "drag_action");
+ const char *op_id = NULL;
+ switch (drag_action) {
+ case V3D_GIZMO_SHOW_OBJECT_TRANSLATE:
+ op_id = "TRANSFORM_OT_translate";
+ break;
+ case V3D_GIZMO_SHOW_OBJECT_ROTATE:
+ op_id = "TRANSFORM_OT_rotate";
+ break;
+ case V3D_GIZMO_SHOW_OBJECT_SCALE:
+ op_id = "TRANSFORM_OT_resize";
+ break;
+ default:
+ break;
+ }
+ if (op_id) {
+ wmOperatorType *ot = WM_operatortype_find(op_id, true);
+ PointerRNA op_ptr;
+ WM_operator_properties_create_ptr(&op_ptr, ot);
+ RNA_boolean_set(&op_ptr, "release_confirm", true);
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
+ WM_operator_properties_free(&op_ptr);
+ return OPERATOR_FINISHED;
+ }
+ }
+ }
+ return OPERATOR_PASS_THROUGH;
+}
+
+/* Use with 'TRANSFORM_GGT_gizmo'. */
+static void TRANSFORM_OT_from_gizmo(struct wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Transform From Gizmo";
+ ot->description = "Transform selected items by mode type";
+ ot->idname = "TRANSFORM_OT_from_gizmo";
+ ot->flag = 0;
+
+ /* api callbacks */
+ ot->invoke = transform_from_gizmo_invoke;
+}
+
void transform_operatortypes(void)
{
TransformModeItem *tmode;
@@ -1223,6 +1277,8 @@ void transform_operatortypes(void)
WM_operatortype_append(TRANSFORM_OT_select_orientation);
WM_operatortype_append(TRANSFORM_OT_create_orientation);
WM_operatortype_append(TRANSFORM_OT_delete_orientation);
+
+ WM_operatortype_append(TRANSFORM_OT_from_gizmo);
}
void ED_keymap_transform(wmKeyConfig *keyconf)
diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c
index 49b5cada04a..ccbe12b4a93 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -569,7 +569,7 @@ static const EnumPropertyItem *rna_undo_itemf(bContext *C, int *totitem)
item_tmp.identifier = us->name;
item_tmp.name = IFACE_(us->name);
if (us == wm->undo_stack->step_active) {
- item_tmp.icon = ICON_HIDE_OFF;
+ item_tmp.icon = ICON_LAYER_ACTIVE;
}
else {
item_tmp.icon = ICON_NONE;
diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt
index 0564cb07897..c09237d825d 100644
--- a/source/blender/editors/util/CMakeLists.txt
+++ b/source/blender/editors/util/CMakeLists.txt
@@ -41,6 +41,7 @@ set(SRC
ed_util.c
gizmo_utils.c
numinput.c
+ select_buffer_utils.c
select_utils.c
# general includes
@@ -79,6 +80,7 @@ set(SRC
../include/ED_screen.h
../include/ED_screen_types.h
../include/ED_sculpt.h
+ ../include/ED_select_buffer_utils.h
../include/ED_select_utils.h
../include/ED_sequencer.h
../include/ED_sound.h
diff --git a/source/blender/editors/util/select_buffer_utils.c b/source/blender/editors/util/select_buffer_utils.c
new file mode 100644
index 00000000000..130f6819e34
--- /dev/null
+++ b/source/blender/editors/util/select_buffer_utils.c
@@ -0,0 +1,303 @@
+/*
+ * 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) 2008 Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup edutil
+ *
+ * Generic utilities for handling buffer selection where selection ID's are drawn onto
+ * an off screen buffer.
+ *
+ * All coordinates are relative to the current region.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_bitmap.h"
+#include "BLI_bitmap_draw_2d.h"
+#include "BLI_rect.h"
+#include "BLI_utildefines.h"
+
+#include "ED_select_buffer_utils.h"
+
+/* Only for #ED_view3d_select_id_read,
+ * note that this file shouldn't have 3D view specific logic in it, we could have a more general
+ * way to read from selection buffers that doesn't depend on the view3d API. */
+#include "ED_view3d.h"
+
+/* -------------------------------------------------------------------- */
+/** \name Select Bitmap from ID's
+ *
+ * Given a buffer of select ID's, fill in a booleans (true/false) per index.
+ * #BLI_bitmap is used for memory effeciency.
+ *
+ * \{ */
+
+/**
+ * \param bitmap_len: Number of indices in the selection id buffer.
+ * \param rect: The rectangle to sample indices from (min/max inclusive).
+ * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure.
+ */
+uint *ED_select_buffer_bitmap_from_rect(const uint bitmap_len, const rcti *rect)
+{
+ uint buf_len;
+ const uint *buf = ED_view3d_select_id_read(
+ rect->xmin, rect->ymin, rect->xmax, rect->ymax, &buf_len);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ const uint *buf_iter = buf;
+
+ BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__);
+
+ while (buf_len--) {
+ const uint index = *buf_iter - 1;
+ if (index < bitmap_len) {
+ BLI_BITMAP_ENABLE(bitmap_buf, index);
+ }
+ buf_iter++;
+ }
+ MEM_freeN((void *)buf);
+ return bitmap_buf;
+}
+
+/**
+ * \param bitmap_len: Number of indices in the selection id buffer.
+ * \param center: Circle center.
+ * \param radius: Circle radius.
+ * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure.
+ */
+uint *ED_select_buffer_bitmap_from_circle(const uint bitmap_len,
+ const int center[2],
+ const int radius)
+{
+ if (bitmap_len == 0) {
+ return NULL;
+ }
+
+ const int xmin = center[0] - radius;
+ const int xmax = center[0] + radius;
+ const int ymin = center[1] - radius;
+ const int ymax = center[1] + radius;
+
+ const uint *buf = ED_view3d_select_id_read(xmin, ymin, xmax, ymax, NULL);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ const uint *buf_iter = buf;
+
+ BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__);
+ const int radius_sq = radius * radius;
+ for (int yc = -radius; yc <= radius; yc++) {
+ for (int xc = -radius; xc <= radius; xc++, buf_iter++) {
+ if (xc * xc + yc * yc < radius_sq) {
+ /* Intentionally wrap to max value if this is zero. */
+ const uint index = *buf_iter - 1;
+ if (index < bitmap_len) {
+ BLI_BITMAP_ENABLE(bitmap_buf, index);
+ }
+ }
+ }
+ }
+ MEM_freeN((void *)buf);
+ return bitmap_buf;
+}
+
+struct PolyMaskData {
+ BLI_bitmap *px;
+ int width;
+};
+
+static void ed_select_buffer_mask_px_cb(int x, int x_end, int y, void *user_data)
+{
+ struct PolyMaskData *data = user_data;
+ BLI_bitmap *px = data->px;
+ int i = (y * data->width) + x;
+ do {
+ BLI_BITMAP_ENABLE(px, i);
+ i++;
+ } while (++x != x_end);
+}
+
+/**
+ * \param bitmap_len: Number of indices in the selection id buffer.
+ * \param center: Circle center.
+ * \param radius: Circle radius.
+ * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure.
+ */
+uint *ED_select_buffer_bitmap_from_poly(const uint bitmap_len,
+ const int poly[][2],
+ const int poly_len,
+ const rcti *rect)
+
+{
+ if (bitmap_len == 0) {
+ return NULL;
+ }
+
+ struct PolyMaskData poly_mask_data;
+ uint buf_len;
+ const uint *buf = ED_view3d_select_id_read(
+ rect->xmin, rect->ymin, rect->xmax, rect->ymax, &buf_len);
+ if (buf == NULL) {
+ return NULL;
+ }
+
+ BLI_bitmap *buf_mask = BLI_BITMAP_NEW(buf_len, __func__);
+ poly_mask_data.px = buf_mask;
+ poly_mask_data.width = (rect->xmax - rect->xmin) + 1;
+
+ BLI_bitmap_draw_2d_poly_v2i_n(rect->xmin,
+ rect->ymin,
+ rect->xmax + 1,
+ rect->ymax + 1,
+ poly,
+ poly_len,
+ ed_select_buffer_mask_px_cb,
+ &poly_mask_data);
+
+ /* Build selection lookup. */
+ const uint *buf_iter = buf;
+ BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__);
+ int i = 0;
+ while (buf_len--) {
+ const uint index = *buf_iter - 1;
+ if (index < bitmap_len && BLI_BITMAP_TEST(buf_mask, i)) {
+ BLI_BITMAP_ENABLE(bitmap_buf, index);
+ }
+ buf_iter++;
+ i++;
+ }
+ MEM_freeN((void *)buf);
+ MEM_freeN(buf_mask);
+
+ return bitmap_buf;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Find Single Select ID's
+ *
+ * Given a buffer of select ID's, find the a single select id.
+ *
+ * \{ */
+
+/**
+ * Samples a single pixel.
+ */
+uint ED_select_buffer_sample_point(const int center[2])
+{
+ uint buf_len;
+ uint *buf = ED_view3d_select_id_read(center[0], center[1], center[0], center[1], &buf_len);
+ BLI_assert(0 != buf_len);
+ uint ret = buf[0];
+ MEM_freeN(buf);
+ return ret;
+}
+
+/**
+ * Find the selection id closest to \a center.
+ * \param dist[in,out]: Use to initalize the distance,
+ * when found, this value is set to the distance of the selection thats returned.
+ */
+uint ED_select_buffer_find_nearest_to_point(const int center[2],
+ const uint id_min,
+ const uint id_max,
+ uint *dist)
+{
+ /* Smart function to sample a rect spiralling outside, nice for selection ID. */
+
+ /* Create region around center (typically the mouse cursor).
+ * This must be square and have an odd width,
+ * the spiraling algorithm does not work with arbitrary rectangles. */
+ rcti rect;
+ BLI_rcti_init_pt_radius(&rect, center, *dist);
+ rect.xmax += 1;
+ rect.ymax += 1;
+
+ int width = BLI_rcti_size_x(&rect);
+ int height = width;
+ BLI_assert(width == height);
+
+ /* Read from selection framebuffer. */
+
+ uint buf_len;
+ const uint *buf = ED_view3d_select_id_read_rect(&rect, &buf_len);
+ BLI_assert(width * height == buf_len);
+
+ /* Spiral, starting from center of buffer. */
+ int spiral_offset = height * (int)(width / 2) + (height / 2);
+ int spiral_direction = 0;
+
+ uint index = 0;
+
+ for (int nr = 1; nr <= height; nr++) {
+ for (int a = 0; a < 2; a++) {
+ for (int b = 0; b < nr; b++) {
+ /* Find hit within the specified range. */
+ uint hit_id = buf[spiral_offset];
+
+ if (hit_id && hit_id >= id_min && hit_id < id_max) {
+ /* Get x/y from spiral offset. */
+ int hit_x = spiral_offset % width;
+ int hit_y = spiral_offset / width;
+
+ int center_x = width / 2;
+ int center_y = height / 2;
+
+ /* Manhatten distance in keeping with other screen-based selection. */
+ *dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
+
+ /* Indices start at 1 here. */
+ index = (hit_id - id_min) + 1;
+ goto exit;
+ }
+
+ /* Next spiral step. */
+ if (spiral_direction == 0) {
+ spiral_offset += 1; /* right */
+ }
+ else if (spiral_direction == 1) {
+ spiral_offset -= width; /* down */
+ }
+ else if (spiral_direction == 2) {
+ spiral_offset -= 1; /* left */
+ }
+ else {
+ spiral_offset += width; /* up */
+ }
+
+ /* Stop if we are outside the buffer. */
+ if (spiral_offset < 0 || spiral_offset >= buf_len) {
+ goto exit;
+ }
+ }
+
+ spiral_direction = (spiral_direction + 1) % 4;
+ }
+ }
+
+exit:
+ MEM_freeN((void *)buf);
+ return index;
+}
+
+/** \} */
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 3a5aead3d44..7f9b90f4496 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -246,6 +246,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
bool prev_ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1));
GPU_matrix_bind(geom->interface);
+ GPU_batch_bind(geom);
/* TODO(fclem): If drawcall count becomes a problem in the future
* we can use multi draw indirect drawcalls for this.
@@ -254,7 +255,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
bool ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1));
if (ma_match != prev_ma_match) {
if (ma_match == false) {
- GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false);
+ GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0);
}
else {
draw_start = idx;
@@ -264,7 +265,7 @@ static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
prev_ma_match = ma_match;
}
if (prev_ma_match == true) {
- GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false);
+ GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0);
}
GPU_batch_program_use_end(geom);