diff options
Diffstat (limited to 'source/blender/editors')
232 files changed, 6410 insertions, 5402 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 53401e0c05a..0a464e6709a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4386,9 +4386,7 @@ void ANIM_channel_draw( } /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* step 1) draw backdrop ........................................... */ if (acf->draw_backdrop) { @@ -4437,7 +4435,7 @@ void ANIM_channel_draw( } /* turn off blending, since not needed anymore... */ - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* icon is drawn as widget now... */ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) { diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index b2f687b49af..73df0518f06 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -98,9 +98,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) /* only draw this if preview range is set */ if (PRVRANGEON) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -121,7 +119,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -133,9 +131,7 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width) void ANIM_draw_framerange(Scene *scene, View2D *v2d) { /* draw darkened area outside of active timeline frame range */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -151,7 +147,7 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d) immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* thin lines where the actual frames are */ immUniformThemeColorShade(TH_BACK, -60); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 8280b58c21a..ddd389a5348 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1555,7 +1555,7 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), next = nlt->next; } - /* if we're in NLA-tweakmode, don't show this track if it was disabled + /* If we're in NLA-tweak-mode, don't show this track if it was disabled * (due to tweaking) for now: * - active track should still get shown though (even though it has disabled flag set) */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index bcdbf4c74f0..3bfa3b9d5be 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -499,16 +499,14 @@ static void draw_marker( marker_color_get(marker, text_color, line_color); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); draw_marker_line(line_color, xpos, UI_DPI_FAC * 20, region_height); int icon_id = marker_get_icon_id(marker, flag); UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, UI_DPI_FAC * 18, icon_id); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); float name_y = UI_DPI_FAC * 18; /* Give an offset to the marker name when selected, @@ -529,13 +527,11 @@ static void draw_markers_background(rctf *rect) immUniformColor4ubv(shade); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index 4c10c66dfa6..2a37302872a 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -69,9 +69,9 @@ typedef struct MPathTarget { /* ........ */ /* update scene for current frame */ -static void motionpaths_calc_update_scene(Main *bmain, struct Depsgraph *depsgraph) +static void motionpaths_calc_update_scene(struct Depsgraph *depsgraph) { - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } Depsgraph *animviz_depsgraph_build(Main *bmain, @@ -91,11 +91,11 @@ Depsgraph *animviz_depsgraph_build(Main *bmain, } /* Build graph from all requested IDs. */ - DEG_graph_build_from_ids(depsgraph, bmain, scene, view_layer, ids, num_ids); + DEG_graph_build_from_ids(depsgraph, ids, num_ids); MEM_freeN(ids); /* Update once so we can access pointers of evaluated animation data. */ - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); return depsgraph; } @@ -471,7 +471,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, } else { /* Update relevant data for new frame. */ - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); } /* perform baking for targets */ @@ -484,7 +484,7 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, * We always have to restore the current frame though. */ CFRA = cfra; if (range != ANIMVIZ_CALC_RANGE_CURRENT_FRAME && restore) { - motionpaths_calc_update_scene(bmain, depsgraph); + motionpaths_calc_update_scene(depsgraph); } if (is_active_depsgraph) { diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index c69f3ce3e3a..4d6d7fa3ad5 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -692,7 +692,7 @@ static void draw_keylist(View2D *v2d, const float smaller_sz = 0.35f * icon_sz; const float ipo_sz = 0.1f * icon_sz; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ @@ -848,7 +848,7 @@ static void draw_keylist(View2D *v2d, } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* *************************** Channel Drawing Funcs *************************** */ diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index edc36326c57..0615e21c4a5 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -66,13 +66,11 @@ static void draw_background(const rcti *rect) immUniformThemeColor(TH_TIME_SCRUB_BACKGROUND); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index a737916e9a2..2efb7315b89 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -304,6 +304,10 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + /* Inverse transform for all selected armatures in this object, + * See #object_join_exec for detailed comment on why the safe version is used. */ + invert_m4_m4_safe_ortho(oimat, ob_active->obmat); + /* Get edit-bones of active armature to add edit-bones to */ ED_armature_to_edit(arm); @@ -334,7 +338,6 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op) // BASACT->flag &= ~OB_MODE_POSE; /* Find the difference matrix */ - invert_m4_m4(oimat, ob_active->obmat); mul_m4_m4m4(mat, oimat, ob_iter->obmat); /* Copy bones and posechannels from the object to the edit armature */ @@ -435,6 +438,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 75ffd31854a..ceacd3333d5 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -37,6 +37,7 @@ #include "BKE_bvhutils.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" +#include "BKE_mesh_wrapper.h" #include "BKE_modifier.h" #include "ED_armature.h" @@ -1761,6 +1762,9 @@ void ED_mesh_deform_bind_callback(MeshDeformModifierData *mmd, memset(&mdb, 0, sizeof(MeshDeformBind)); + /* No need to support other kinds of mesh data as binding is a one-off action. */ + BKE_mesh_wrapper_ensure_mdata(cagemesh); + /* get mesh and cage mesh */ mdb.vertexcos = MEM_callocN(sizeof(float[3]) * totvert, "MeshDeformCos"); mdb.totvert = totvert; diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c index a6cf8552ca4..b09015096a6 100644 --- a/source/blender/editors/armature/pose_transform.c +++ b/source/blender/editors/armature/pose_transform.c @@ -23,6 +23,7 @@ #include "DNA_anim_types.h" #include "DNA_armature_types.h" +#include "DNA_constraint_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -338,6 +339,46 @@ static void applyarmature_process_selected_recursive(bArmature *arm, } } +/* Reset bone constraint so that it is correct after the pose has been applied. */ +static void applyarmature_reset_bone_constraint(const bConstraint *constraint) +{ + /* TODO(Sybren): This function needs too much knowledge of the internals of specific constraints. + * When it is extended with one or two more constraints, move the functionality into a + * bConstraintTypeInfo callback function. */ + switch (constraint->type) { + case CONSTRAINT_TYPE_STRETCHTO: { + bStretchToConstraint *stretch_to = (bStretchToConstraint *)constraint->data; + stretch_to->orglength = 0.0f; /* Force recalculation on next evaluation. */ + break; + } + default: + /* Most constraints don't need resetting. */ + break; + } +} + +/* Reset bone constraints of the given pose channel so that they are correct after the pose has + * been applied. */ +static void applyarmature_reset_bone_constraints(const bPoseChannel *pchan) +{ + LISTBASE_FOREACH (bConstraint *, constraint, &pchan->constraints) { + applyarmature_reset_bone_constraint(constraint); + } +} + +/* Reset all (or only selected) bone constraints so that they are correct after the pose has been + * applied. */ +static void applyarmature_reset_constraints(bPose *pose, const bool use_selected) +{ + for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + BLI_assert(pchan->bone != NULL); + if (use_selected && (pchan->bone->flag & BONE_SELECTED) == 0) { + continue; + } + applyarmature_reset_bone_constraints(pchan); + } +} + /* set the current pose as the restpose */ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) { @@ -416,6 +457,9 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) /* fix parenting of objects which are bone-parented */ applyarmature_fix_boneparents(C, scene, ob); + /* For the affected bones, reset specific constraints that are now known to be invalid. */ + applyarmature_reset_constraints(pose, use_selected); + /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index d113e0693a4..fb102574a85 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2172,12 +2172,22 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const short flag) return ok; } +static void calc_duplicate_actnurb(const ListBase *editnurb, const ListBase *newnurb, Curve *cu) +{ + cu->actnu = BLI_listbase_count(editnurb) + BLI_listbase_count(newnurb); +} + static bool calc_duplicate_actvert( const ListBase *editnurb, const ListBase *newnurb, Curve *cu, int start, int end, int vert) { + if (cu->actvert == -1) { + calc_duplicate_actnurb(editnurb, newnurb, cu); + return true; + } + if ((start <= cu->actvert) && (end > cu->actvert)) { + calc_duplicate_actnurb(editnurb, newnurb, cu); cu->actvert = vert; - cu->actnu = BLI_listbase_count(editnurb) + BLI_listbase_count(newnurb); return true; } return false; @@ -2427,26 +2437,31 @@ static void adduplicateflagNurb( } if (cu->actnu == i) { - for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { - starta = b * nu->pntsu + a; - if (calc_duplicate_actvert(editnurb, - newnurb, - cu, - cu->actvert, - starta, - cu->actvert % nu->pntsu + newu + - b * newnu->pntsu)) { - /* actvert in cyclicu selection */ - break; - } - if (calc_duplicate_actvert(editnurb, - newnurb, - cu, - starta, - starta + newu, - cu->actvert - starta + b * newnu->pntsu)) { - /* actvert in 'current' iteration selection */ - break; + if (cu->actvert == -1) { + calc_duplicate_actnurb(editnurb, newnurb, cu); + } + else { + for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { + starta = b * nu->pntsu + a; + if (calc_duplicate_actvert(editnurb, + newnurb, + cu, + cu->actvert, + starta, + cu->actvert % nu->pntsu + newu + + b * newnu->pntsu)) { + /* actvert in cyclicu selection */ + break; + } + if (calc_duplicate_actvert(editnurb, + newnurb, + cu, + starta, + starta + newu, + cu->actvert - starta + b * newnu->pntsu)) { + /* actvert in 'current' iteration selection */ + break; + } } } } @@ -2474,16 +2489,21 @@ static void adduplicateflagNurb( /* general case if not handled by cyclicu or cyclicv */ if (cu->actnu == i) { - for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { - starta = b * nu->pntsu + a; - if (calc_duplicate_actvert(editnurb, - newnurb, - cu, - starta, - starta + newu, - cu->actvert - (a / nu->pntsu * nu->pntsu + diffa + - (starta % nu->pntsu)))) { - break; + if (cu->actvert == -1) { + calc_duplicate_actnurb(editnurb, newnurb, cu); + } + else { + for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { + starta = b * nu->pntsu + a; + if (calc_duplicate_actvert(editnurb, + newnurb, + cu, + starta, + starta + newu, + cu->actvert - (a / nu->pntsu * nu->pntsu + diffa + + (starta % nu->pntsu)))) { + break; + } } } } @@ -2510,15 +2530,20 @@ static void adduplicateflagNurb( /* check for actvert in the unused cyclicuv selection */ if (cu->actnu == i) { - for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { - starta = b * nu->pntsu; - if (calc_duplicate_actvert(editnurb, - newnurb, - cu, - starta, - starta + newu, - cu->actvert - (diffa + (starta % nu->pntsu)))) { - break; + if (cu->actvert == -1) { + calc_duplicate_actnurb(editnurb, newnurb, cu); + } + else { + for (b = 0, diffa = 0; b < newv; b++, diffa += nu->pntsu - newu) { + starta = b * nu->pntsu; + if (calc_duplicate_actvert(editnurb, + newnurb, + cu, + starta, + starta + newu, + cu->actvert - (diffa + (starta % nu->pntsu)))) { + break; + } } } } @@ -6923,8 +6948,9 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) BLI_listbase_clear(&tempbase); - /* trasnform all selected curves inverse in obact */ - invert_m4_m4(imat, ob_active->obmat); + /* Inverse transform for all selected curves in this object, + * See #object_join_exec for detailed comment on why the safe version is used. */ + invert_m4_m4_safe_ortho(imat, ob_active->obmat); CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) { if (ob_iter->type == ob_active->type) { @@ -6988,6 +7014,7 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c index 748bf040fbb..889041daacf 100644 --- a/source/blender/editors/curve/editcurve_paint.c +++ b/source/blender/editors/curve/editcurve_paint.c @@ -419,8 +419,8 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - GPU_depth_test(false); - GPU_blend(true); + GPU_depth_test(GPU_DEPTH_NONE); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); GPU_line_width(3.0f); @@ -441,8 +441,8 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), immEnd(); /* Reset defaults */ - GPU_depth_test(true); - GPU_blend(false); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -666,7 +666,7 @@ static void curve_draw_exec_precalc(wmOperator *op) selem_prev = selem; } scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f; - float error_threshold = (cps->error_threshold * U.pixelsize) * scale_px; + float error_threshold = (cps->error_threshold * U.dpi_fac) * scale_px; RNA_property_float_set(op->ptr, prop, error_threshold); } @@ -685,7 +685,7 @@ static void curve_draw_exec_precalc(wmOperator *op) } if (len_squared_v2v2(selem_first->mval, selem_last->mval) <= - square_f(STROKE_CYCLIC_DIST_PX * U.pixelsize)) { + square_f(STROKE_CYCLIC_DIST_PX * U.dpi_fac)) { use_cyclic = true; } } diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 0dcb8de37f1..b8cc704eb23 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -744,6 +744,7 @@ set_property(GLOBAL PROPERTY ICON_GEOM_NAMES ops.pose.relax ops.sculpt.border_hide ops.sculpt.border_mask + ops.sculpt.cloth_filter ops.sculpt.lasso_mask ops.sculpt.mesh_filter ops.sequencer.blade diff --git a/source/blender/editors/gizmo_library/gizmo_draw_utils.c b/source/blender/editors/gizmo_library/gizmo_draw_utils.c index 033673a99a8..2896aa25930 100644 --- a/source/blender/editors/gizmo_library/gizmo_draw_utils.c +++ b/source/blender/editors/gizmo_library/gizmo_draw_utils.c @@ -84,13 +84,13 @@ void wm_gizmo_geometryinfo_draw(const GizmoGeomInfo *info, * since it causes issues leaving the GL state modified. */ #if 0 GPU_face_culling(GPU_CULL_BACK); - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); #endif GPU_batch_draw(batch); #if 0 - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_face_culling(GPU_CULL_NONE); #endif diff --git a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c index 341f43d0662..d4d9f9bf424 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/arrow3d_gizmo.c @@ -195,9 +195,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool GPU_matrix_push(); GPU_matrix_mul(matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); arrow_draw_geom(arrow, select, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); @@ -207,9 +207,9 @@ static void arrow_draw_intern(ArrowGizmo3D *arrow, const bool select, const bool GPU_matrix_push(); GPU_matrix_mul(inter->init_matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); arrow_draw_geom(arrow, select, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } diff --git a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c index c5231b3cd96..13f3903f0b2 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/button2d_gizmo.c @@ -195,7 +195,7 @@ static void button2d_draw_intern(const bContext *C, } else { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (draw_options & ED_GIZMO_BUTTON_SHOW_BACKDROP) { const float fill_alpha = RNA_float_get(gz->ptr, "backdrop_fill_alpha"); @@ -226,10 +226,10 @@ static void button2d_draw_intern(const bContext *C, float color_contrast[4]; copy_v3_fl(color_contrast, rgb_to_grayscale(color) < 0.2f ? 1 : 0); color_contrast[3] = color[3]; - GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color_contrast)); + GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color_contrast)); } else { - GPU_batch_uniform_4f(button->shape_batch[i], "color", UNPACK4(color)); + GPU_shader_uniform_4f(button->shape_batch[i]->shader, "color", UNPACK4(color)); } GPU_batch_draw(button->shape_batch[i]); @@ -265,7 +265,7 @@ static void button2d_draw_intern(const bContext *C, UI_icon_draw_alpha(pos[0], pos[1], button->icon, alpha); GPU_polygon_smooth(true); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (need_to_pop) { @@ -283,9 +283,9 @@ static void gizmo_button2d_draw(const bContext *C, wmGizmo *gz) { const bool is_highlight = (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); button2d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_button2d_test_select(bContext *C, wmGizmo *gz, const int mval[2]) diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index 406d66dfd8f..be5f488d759 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -626,14 +626,14 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, /* Handy for quick testing draw (if it's outside bounds). */ if (false) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; immRectf(pos, -s, -s, s, s); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (select) { @@ -722,7 +722,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, float color[4], black[3] = {0, 0, 0}; gizmo_color_get(gz, highlight, color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); float outline_line_width = gz->line_width + 3.0f; cage2d_draw_circle_wire(&r, margin, black, transform_flag, draw_options, outline_line_width); @@ -732,7 +732,7 @@ static void gizmo_cage2d_draw_intern(wmGizmo *gz, cage2d_draw_circle_handles(&r, margin, color, transform_flag, true); cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { BLI_assert(0); diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c index 0bc65fe10a5..644a4247d84 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage3d_gizmo.c @@ -303,14 +303,14 @@ static void gizmo_cage3d_draw_intern( /* Handy for quick testing draw (if it's outside bounds). */ if (false) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformColor4fv((const float[4]){1, 1, 1, 0.5f}); float s = 0.5f; immRectf(pos, -s, -s, s, s); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (select) { @@ -382,7 +382,7 @@ static void gizmo_cage3d_draw_intern( float color[4], black[3] = {0, 0, 0}; gizmo_color_get(gz, highlight, color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); cage3d_draw_circle_wire( size_real, margin, black, transform_flag, draw_options, gz->line_width + 3.0f); @@ -395,7 +395,7 @@ static void gizmo_cage3d_draw_intern( cage3d_draw_circle_handles(rv3d, matrix_final, size_real, margin, color, true, 40); GPU_polygon_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { BLI_assert(0); diff --git a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c index 5d7c3a9e717..e1860d5d0fd 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c @@ -482,9 +482,9 @@ static void gizmo_dial_draw(const bContext *C, wmGizmo *gz) clip_plane[3] += DIAL_CLIP_BIAS; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); dial_draw_intern(C, gz, false, is_highlight, clip_plane); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_dial_modal(bContext *C, diff --git a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c index db57a33f543..ad7036f4460 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/move3d_gizmo.c @@ -207,9 +207,9 @@ static void move3d_draw_intern(const bContext *C, GPU_matrix_mul(matrix_align); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move_geom_draw(gz, color, select, draw_options); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); if (gz->interaction_data) { @@ -220,9 +220,9 @@ static void move3d_draw_intern(const bContext *C, GPU_matrix_mul(matrix_align); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move_geom_draw(gz, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } } @@ -240,9 +240,9 @@ static void gizmo_move_draw(const bContext *C, wmGizmo *gz) (void)is_modal; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); move3d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_move_modal(bContext *C, diff --git a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c index 48b2e3348c9..177687b6afd 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/primitive3d_gizmo.c @@ -96,9 +96,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz, GPU_matrix_push(); GPU_matrix_mul(matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); @@ -112,9 +112,9 @@ static void gizmo_primitive_draw_intern(wmGizmo *gz, GPU_matrix_push(); GPU_matrix_mul(inter->init_matrix_final); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); gizmo_primitive_draw_geom(color_inner, color_outer, draw_style); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } diff --git a/source/blender/editors/gpencil/annotate_draw.c b/source/blender/editors/gpencil/annotate_draw.c index df479325027..b6cbbe7712b 100644 --- a/source/blender/editors/gpencil/annotate_draw.c +++ b/source/blender/editors/gpencil/annotate_draw.c @@ -556,7 +556,7 @@ static void annotation_draw_strokes(const bGPDframe *gpf, const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); if (no_xray) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ @@ -574,7 +574,7 @@ static void annotation_draw_strokes(const bGPDframe *gpf, } if (no_xray) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_polygon_offset(0.0f, 0.0f); } @@ -734,9 +734,7 @@ static void annotation_draw_data( GPU_line_smooth(true); /* turn on alpha-blending */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Do not write to depth (avoid self-occlusion). */ bool prev_depth_mask = GPU_depth_mask_get(); @@ -746,8 +744,8 @@ static void annotation_draw_data( annotation_draw_data_layers(gpd, offsx, offsy, winx, winy, cfra, dflag); /* turn off alpha blending, then smooth lines */ - GPU_blend(false); // alpha blending - GPU_line_smooth(false); // smooth lines + GPU_blend(GPU_BLEND_NONE); // alpha blending + GPU_line_smooth(false); // smooth lines GPU_depth_mask(prev_depth_mask); } diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 30e4fe0b531..8237e6cfd62 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -1700,9 +1700,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); @@ -1730,7 +1728,7 @@ static void annotation_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_pt immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } @@ -1768,7 +1766,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr) uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(1.25f); const float color[3] = {1.0f, 0.39f, 0.39f}; @@ -1793,7 +1791,7 @@ static void annotation_draw_stabilizer(bContext *C, int x, int y, void *p_ptr) immEnd(); /* Returns back all GPU settings */ - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 9d11c1c2a25..93767127cc7 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -348,7 +348,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw) const int no_xray = (tgpw->dflag & GP_DRAWDATA_NO_XRAY); if (no_xray) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ @@ -393,7 +393,7 @@ static void gpencil_draw_strokes(tGPDdraw *tgpw) } } if (no_xray) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_polygon_offset(0.0f, 0.0f); } diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 348fb614977..6c003b85edd 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -2819,7 +2819,10 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) sub_v3_v3v3(offset_global, ob_active->loc, ob_iter->obmat[3]); copy_m3_m4(bmat, ob_active->obmat); - invert_m3_m3(imat, bmat); + + /* Inverse transform for all selected curves in this object, + * See #object_join_exec for detailed comment on why the safe version is used. */ + invert_m3_m3_safe_ortho(imat, bmat); mul_m3_v3(imat, offset_global); mul_v3_m3v3(offset_local, imat, offset_global); @@ -2830,7 +2833,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) /* recalculate all stroke points */ BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat); - invert_m4_m4(inverse_diff_mat, diff_mat); + invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat); Material *ma_src = NULL; LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_new->frames) { @@ -2910,6 +2913,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); /* because we removed object(s) */ WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 99e98df3397..1bbba6c4b8a 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -3645,7 +3645,6 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); Scene *scene = CTX_data_scene(C); - Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ARegion *region = CTX_wm_region(C); int oldframe = (int)DEG_get_ctime(depsgraph); @@ -3669,7 +3668,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) if ((mode == GP_REPROJECT_SURFACE) && (cfra_prv != gpf_->framenum)) { cfra_prv = gpf_->framenum; CFRA = gpf_->framenum; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } ED_gpencil_stroke_reproject(depsgraph, &gsc, sctx, gpl, gpf_, gps, mode, keep_original); @@ -3679,7 +3678,7 @@ static int gpencil_strokes_reproject_exec(bContext *C, wmOperator *op) /* return frame state and DB to original state */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); if (sctx != NULL) { ED_transform_snap_object_context_destroy(sctx); diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 2855f2cc0d7..247cc218c2f 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -237,6 +237,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) bGPdata *gpd = tgpf->gpd; Brush *brush = tgpf->brush; BrushGpencilSettings *brush_settings = brush->gpencil_settings; + ToolSettings *ts = tgpf->scene->toolsettings; tGPDdraw tgpw; tgpw.rv3d = tgpf->rv3d; @@ -251,7 +252,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) tgpw.disable_fill = 1; tgpw.dflag |= (GP_DRAWFILLS_ONLY3D | GP_DRAWFILLS_NOSTATUS); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd); BLI_assert(gpl_active != NULL); @@ -309,7 +310,14 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) /* if active layer and no keyframe, create a new one */ if (gpl == tgpf->gpl) { if ((gpl->actframe == NULL) || (gpl->actframe->framenum != tgpf->active_cfra)) { - BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, GP_GETFRAME_ADD_NEW); + short add_frame_mode; + if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) { + add_frame_mode = GP_GETFRAME_ADD_COPY; + } + else { + add_frame_mode = GP_GETFRAME_ADD_NEW; + } + BKE_gpencil_layer_frame_get(gpl, tgpf->active_cfra, add_frame_mode); } } @@ -363,7 +371,7 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw strokes in offscreen buffer */ @@ -446,8 +454,9 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) GPU_matrix_push(); GPU_matrix_identity_set(); + GPU_depth_mask(true); GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); + GPU_clear_depth(1.0f); ED_view3d_update_viewmat( tgpf->depsgraph, tgpf->scene, tgpf->v3d, tgpf->region, NULL, winmat, NULL, true); @@ -459,6 +468,8 @@ static bool gpencil_render_offscreen(tGPDfill *tgpf) const float ink[4] = {1.0f, 0.0f, 0.0f, 1.0f}; gpencil_draw_datablock(tgpf, ink); + GPU_depth_mask(false); + GPU_matrix_pop_projection(); GPU_matrix_pop(); diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c index 53dbc1620d0..4aae0b97e05 100644 --- a/source/blender/editors/gpencil/gpencil_merge.c +++ b/source/blender/editors/gpencil/gpencil_merge.c @@ -584,42 +584,14 @@ static int gpencil_stroke_merge_material_exec(bContext *C, wmOperator *op) const float val_threshold = RNA_float_get(op->ptr, "val_threshold"); /* Review materials. */ - GHash *mat_table = BLI_ghash_int_new(__func__); - short *totcol = BKE_object_material_len_p(ob); if (totcol == 0) { return OPERATOR_CANCELLED; } - bool changed = BKE_gpencil_merge_materials_table_get( - ob, hue_threshold, sat_threshold, val_threshold, mat_table); - - int removed = BLI_ghash_len(mat_table); - - /* Update stroke material index. */ - if (changed) { - CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) { - LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { - continue; - } - - if (BLI_ghash_haskey(mat_table, POINTER_FROM_INT(gps->mat_nr))) { - int *idx = BLI_ghash_lookup(mat_table, POINTER_FROM_INT(gps->mat_nr)); - gps->mat_nr = POINTER_AS_INT(idx); - } - } - } - } - CTX_DATA_END; - } - - /* Free hash memory. */ - BLI_ghash_free(mat_table, NULL, NULL); + int removed; + bool changed = BKE_gpencil_merge_materials( + ob, hue_threshold, sat_threshold, val_threshold, &removed); /* notifiers */ if (changed) { diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c index a6088e31ff8..f4e40c2670f 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.c @@ -246,7 +246,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Move scene to new frame. */ CFRA = i; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* Loop all objects in the list. */ LISTBASE_FOREACH (GpBakeOb *, elem, &list) { @@ -287,7 +287,7 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Return scene frame state and DB to original state. */ CFRA = oldframe; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); /* Remove unused materials. */ int actcol = ob_gpencil->actcol; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 680e7b37d31..3f62c3ec8c0 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -2268,9 +2268,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, p->radius, 40); @@ -2298,7 +2296,7 @@ static void gpencil_draw_eraser(bContext *UNUSED(C), int x, int y, void *p_ptr) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index 75f08c37cba..a4c8fc770e2 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -109,7 +109,7 @@ /* ************************************************ */ /* Core/Shared Utilities */ -const static EnumPropertyItem gpencil_primitive_type[] = { +static const EnumPropertyItem gpencil_primitive_type[] = { {GP_STROKE_BOX, "BOX", 0, "Box", ""}, {GP_STROKE_LINE, "LINE", 0, "Line", ""}, {GP_STROKE_POLYLINE, "POLYLINE", 0, "Polyline", ""}, diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c index dcba8f16ee9..82d5eedf576 100644 --- a/source/blender/editors/gpencil/gpencil_select.c +++ b/source/blender/editors/gpencil/gpencil_select.c @@ -1114,6 +1114,8 @@ static int gpencil_generic_select_exec( gps->flag &= ~GP_STROKE_SELECT; } CTX_DATA_END; + + changed = true; } /* select/deselect points */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 5aae10a5db5..8b77709bacb 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1760,9 +1760,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 100, 100, 20); imm_draw_circle_fill_2d(shdr_pos, x, y, radius, 40); @@ -1790,7 +1788,7 @@ void ED_gpencil_brush_draw_eraser(Brush *brush, int x, int y) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } @@ -1944,7 +1942,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Inner Ring: Color from UI panel */ immUniformColor4f(color[0], color[1], color[2], 0.8f); @@ -1963,13 +1961,13 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat immUniformColor4f(darkcolor[0], darkcolor[1], darkcolor[2], 0.8f); imm_draw_circle_wire_2d(pos, x, y, radius + 1, 40); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); /* Draw line for lazy mouse */ if ((last_mouse_position) && (brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP)) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); copy_v3_v3(color, brush->add_col); immUniformColor4f(color[0], color[1], color[2], 0.8f); @@ -1981,7 +1979,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat last_mouse_position[1] + region->winrct.ymin); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/include/ED_info.h b/source/blender/editors/include/ED_info.h index df6b6a20ddc..e3ce494e09a 100644 --- a/source/blender/editors/include/ED_info.h +++ b/source/blender/editors/include/ED_info.h @@ -31,8 +31,13 @@ struct Main; /* info_stats.c */ void ED_info_stats_clear(struct ViewLayer *view_layer); const char *ED_info_statusbar_string(struct Main *bmain, - struct bScreen *screen, - struct bContext *C); + struct Scene *scene, + struct ViewLayer *view_layer); + +const char *ED_info_statistics_string(struct Main *bmain, + struct Scene *scene, + struct ViewLayer *view_layer); + void ED_info_draw_stats( struct Main *bmain, Scene *scene, ViewLayer *view_layer, int x, int *y, int height); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index f2cad1acc84..660e4de09d3 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -59,6 +59,7 @@ void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const int axis, const bool use_self, const bool use_select, + const bool respecthide, const bool use_topology, float maxdist, int *r_index); @@ -66,6 +67,7 @@ void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const int axis, const bool use_self, const bool use_select, + const bool respecthide, const bool use_toplogy); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 4c7dd4fe66c..f1ddc10f1a8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -62,6 +62,11 @@ struct Object *ED_object_context(const struct bContext *C); struct Object *ED_object_active_context(const struct bContext *C); void ED_collection_hide_menu_draw(const struct bContext *C, struct uiLayout *layout); +Object **ED_object_array_in_mode_or_selected(struct bContext *C, + bool (*filter_fn)(struct Object *ob, void *user_data), + void *filter_user_data, + uint *r_objects_len); + /* object_utils.c */ bool ED_object_calc_active_center_for_editmode(struct Object *obedit, const bool select_only, diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 29fe766b2d0..d9c7128c2ee 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -81,18 +81,12 @@ void ED_region_tag_refresh_ui(struct ARegion *region); void ED_region_tag_redraw_editor_overlays(struct ARegion *region); void ED_region_panels_init(struct wmWindowManager *wm, struct ARegion *region); -void ED_region_panels_ex(const struct bContext *C, - struct ARegion *region, - const char *contexts[], - int contextnr, - const bool vertical); +void ED_region_panels_ex(const struct bContext *C, struct ARegion *region, const char *contexts[]); void ED_region_panels(const struct bContext *C, struct ARegion *region); void ED_region_panels_layout_ex(const struct bContext *C, struct ARegion *region, struct ListBase *paneltypes, const char *contexts[], - int contextnr, - const bool vertical, const char *category_override); void ED_region_panels_layout(const struct bContext *C, struct ARegion *region); @@ -187,11 +181,7 @@ void ED_area_newspace(struct bContext *C, ScrArea *area, int type, const bool sk void ED_area_prevspace(struct bContext *C, ScrArea *area); void ED_area_swapspace(struct bContext *C, ScrArea *sa1, ScrArea *sa2); int ED_area_headersize(void); -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_header_alignment(const ScrArea *area); int ED_area_footersize(void); -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback); -int ED_area_footer_alignment(const ScrArea *area); int ED_area_global_size_y(const ScrArea *area); int ED_area_global_min_size_y(const ScrArea *area); int ED_area_global_max_size_y(const ScrArea *area); @@ -354,6 +344,7 @@ bool ED_operator_console_active(struct bContext *C); bool ED_operator_object_active(struct bContext *C); bool ED_operator_object_active_editable_ex(struct bContext *C, const Object *ob); bool ED_operator_object_active_editable(struct bContext *C); +bool ED_operator_object_active_local_editable_ex(struct bContext *C, const Object *ob); bool ED_operator_object_active_local_editable(struct bContext *C); bool ED_operator_object_active_editable_mesh(struct bContext *C); bool ED_operator_object_active_editable_font(struct bContext *C); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index c3abde479f1..bfc46534b99 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -53,6 +53,10 @@ void ED_sculpt_undosys_type(struct UndoType *ut); void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name); void ED_sculpt_undo_geometry_end(struct Object *ob); +/* Face sets. */ +int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh); +void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id); + /* Undo for changes happening on a base mesh for multires sculpting. * if there is no multires sculpt active regular undo is used. */ void ED_sculpt_undo_push_multires_mesh_begin(struct bContext *C, const char *str); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 5d936cdfaa3..1fa9ed0b2c0 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1667,19 +1667,13 @@ void UI_panels_end(const struct bContext *C, struct ARegion *region, int *r_x, i void UI_panels_draw(const struct bContext *C, struct ARegion *region); struct Panel *UI_panel_find_by_type(struct ListBase *lb, struct PanelType *pt); -struct Panel *UI_panel_begin(struct ScrArea *area, - struct ARegion *region, +struct Panel *UI_panel_begin(struct ARegion *region, struct ListBase *lb, uiBlock *block, struct PanelType *pt, struct Panel *panel, bool *r_open); -void UI_panel_end(const struct ScrArea *area, - const struct ARegion *region, - uiBlock *block, - int width, - int height, - bool open); +void UI_panel_end(const struct ARegion *region, uiBlock *block, int width, int height, bool open); void UI_panels_scale(struct ARegion *region, float new_width); void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y); @@ -1709,8 +1703,7 @@ struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContex void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data); /* Polyinstantiated panels for representing a list of data. */ -struct Panel *UI_panel_add_instanced(struct ScrArea *area, - struct ARegion *region, +struct Panel *UI_panel_add_instanced(struct ARegion *region, struct ListBase *panels, char *panel_idname, int list_index, diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index ddc235fa5d2..a7b87d38472 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -263,7 +263,6 @@ typedef enum ThemeColorID { TH_PAINT_CURVE_PIVOT, TH_UV_SHADOW, - TH_UV_OTHERS, TH_FREESTYLE_EDGE_MARK, TH_FREESTYLE_FACE_MARK, @@ -432,12 +431,9 @@ void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], // (for anything fancy use UI_GetThemeColor[Fancy] then BLF_color) void UI_FontThemeColor(int fontid, int colorid); -// clear the openGL ClearColor using the input colorid +// clear the framebuffer using the input colorid void UI_ThemeClearColor(int colorid); -// clear the openGL ClearColor using the input colorid using optional transparency -void UI_ThemeClearColorAlpha(int colorid, float alpha); - // internal (blender) usage only, for init and set active void UI_SetTheme(int spacetype, int regionid); diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index 6e0f4434b7b..d14731b81b7 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -120,6 +120,12 @@ void UI_view2d_curRect_validate(struct View2D *v2d); void UI_view2d_curRect_reset(struct View2D *v2d); void UI_view2d_sync(struct bScreen *screen, struct ScrArea *area, struct View2D *v2dcur, int flag); +/* Perform all required updates after `v2d->cur` as been modified. + * This includes like validation view validation (#UI_view2d_curRect_validate). + * + * Current intent is to use it from user code, such as view navigation and zoom operations. */ +void UI_view2d_curRect_changed(const struct bContext *C, struct View2D *v2d); + void UI_view2d_totRect_set(struct View2D *v2d, int width, int height); void UI_view2d_totRect_set_resize(struct View2D *v2d, int width, int height, bool resize); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 22fbffa9030..9cede126890 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -44,6 +44,8 @@ #include "BLI_utildefines.h" +#include "BLO_readfile.h" + #include "BKE_animsys.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -69,7 +71,9 @@ #include "RNA_access.h" -#include "BPY_extern.h" +#ifdef WITH_PYTHON +# include "BPY_extern_run.h" +#endif #include "ED_numinput.h" #include "ED_screen.h" @@ -300,11 +304,11 @@ static void ui_update_flexible_spacing(const ARegion *region, uiBlock *block) /* How much the next block overlap with the current segment */ int overlap = ((i == sepr_flex_len - 1) ? buttons_width - spacers_pos[i] : (spacers_pos[i + 1] - spacers_pos[i]) / 2); - int segment_end = segment_width * (i + 1); - int spacer_end = segment_end - overlap; - int spacer_sta = spacers_pos[i] + offset; + const int segment_end = segment_width * (i + 1); + const int spacer_end = segment_end - overlap; + const int spacer_sta = spacers_pos[i] + offset; if (spacer_end > spacer_sta) { - float step = min_ff(remaining_space, spacer_end - spacer_sta); + const float step = min_ff(remaining_space, spacer_end - spacer_sta); remaining_space -= step; offset += step; } @@ -325,9 +329,9 @@ static void ui_update_window_matrix(const wmWindow *window, const ARegion *regio else { /* No subwindow created yet, for menus for example, so we use the main * window instead, since buttons are created there anyway. */ - int width = WM_window_pixels_x(window); - int height = WM_window_pixels_y(window); - rcti winrct = {0, width - 1, 0, height - 1}; + const int width = WM_window_pixels_x(window); + const int height = WM_window_pixels_y(window); + const rcti winrct = {0, width - 1, 0, height - 1}; wmGetProjectionMatrix(block->winmat, &winrct); block->aspect = 2.0f / fabsf(width * block->winmat[0][0]); @@ -354,9 +358,7 @@ void ui_region_winrct_get_no_margin(const struct ARegion *region, struct rcti *r void UI_block_translate(uiBlock *block, int x, int y) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { BLI_rctf_translate(&but->rect, x, y); } @@ -366,12 +368,13 @@ void UI_block_translate(uiBlock *block, int x, int y) static void ui_block_bounds_calc_text(uiBlock *block, float offset) { const uiStyle *style = UI_style_get(); - uiBut *bt, *init_col_bt, *col_bt; + uiBut *col_bt; int i = 0, j, x1addval = offset; UI_fontstyle_set(&style->widget); - for (init_col_bt = bt = block->buttons.first; bt; bt = bt->next) { + uiBut *init_col_bt = block->buttons.first; + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (!ELEM(bt->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE, UI_BTYPE_SEPR_SPACER)) { j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); @@ -407,7 +410,6 @@ static void ui_block_bounds_calc_text(uiBlock *block, float offset) void ui_block_bounds_calc(uiBlock *block) { - uiBut *bt; int xof; if (BLI_listbase_is_empty(&block->buttons)) { @@ -422,7 +424,7 @@ void ui_block_bounds_calc(uiBlock *block) BLI_rctf_init_minmax(&block->rect); - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { BLI_rctf_union(&block->rect, &bt->rect); } @@ -435,7 +437,7 @@ void ui_block_bounds_calc(uiBlock *block) block->rect.xmax = block->rect.xmin + max_ff(BLI_rctf_size_x(&block->rect), block->minbounds); /* hardcoded exception... but that one is annoying with larger safety */ - bt = block->buttons.first; + uiBut *bt = block->buttons.first; if (bt && STREQLEN(bt->str, "ERROR", 5)) { xof = 10; } @@ -697,9 +699,10 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new) { - uiBut *but_old; - for (but_old = block_old->buttons.first; but_old; but_old = but_old->next) { - if (ui_but_equals_old(but_new, but_old)) { + uiBut *but_old = NULL; + LISTBASE_FOREACH (uiBut *, but, &block_old->buttons) { + if (ui_but_equals_old(but_new, but)) { + but_old = but; break; } } @@ -707,9 +710,10 @@ uiBut *ui_but_find_old(uiBlock *block_old, const uiBut *but_new) } uiBut *ui_but_find_new(uiBlock *block_new, const uiBut *but_old) { - uiBut *but_new; - for (but_new = block_new->buttons.first; but_new; but_new = but_new->next) { - if (ui_but_equals_old(but_new, but_old)) { + uiBut *but_new = NULL; + LISTBASE_FOREACH (uiBut *, but, &block_new->buttons) { + if (ui_but_equals_old(but, but_old)) { + but_new = but; break; } } @@ -767,8 +771,6 @@ static bool ui_but_update_from_old_block(const bContext *C, but->editstr = oldbut->editstr; but->editval = oldbut->editval; but->editvec = oldbut->editvec; - but->editcoba = oldbut->editcoba; - but->editcumap = oldbut->editcumap; but->selsta = oldbut->selsta; but->selend = oldbut->selend; but->softmin = oldbut->softmin; @@ -1128,7 +1130,7 @@ static bool ui_but_event_operator_string_from_menu(const bContext *C, IDProperty *prop_menu; /* annoying, create a property */ - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; prop_menu = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */ IDP_AddToGroup(prop_menu, IDP_NewString(mt->idname, "name", sizeof(mt->idname))); @@ -1154,7 +1156,7 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C, IDProperty *prop_panel; /* annoying, create a property */ - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; prop_panel = IDP_New(IDP_GROUP, &val, __func__); /* dummy, name is unimportant */ IDP_AddToGroup(prop_panel, IDP_NewString(pt->idname, "name", sizeof(pt->idname))); IDP_AddToGroup(prop_panel, @@ -1359,7 +1361,7 @@ static bool ui_but_event_property_operator_string(const bContext *C, /* create a property to host the "datapath" property we're sending to the operators */ IDProperty *prop_path; - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; prop_path = IDP_New(IDP_GROUP, &val, __func__); if (data_path) { IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1)); @@ -1368,11 +1370,11 @@ static bool ui_but_event_property_operator_string(const bContext *C, const EnumPropertyItem *item; bool free; RNA_property_enum_items((bContext *)C, ptr, prop, &item, NULL, &free); - int index = RNA_enum_from_value(item, prop_enum_value); + const int index = RNA_enum_from_value(item, prop_enum_value); if (index != -1) { IDProperty *prop_value; if (prop_enum_value_is_int) { - int value = item[index].value; + const int value = item[index].value; prop_value = IDP_New(IDP_INT, &(IDPropertyTemplate){ .i = value, @@ -1463,7 +1465,6 @@ static void ui_but_pie_direction_string(uiBut *but, char *buf, int size) static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) { - uiBut *but; char buf[128]; BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)); @@ -1477,7 +1478,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } if (block->flag & UI_BLOCK_RADIAL) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir != UI_RADIAL_NONE) { ui_but_pie_direction_string(but, buf, sizeof(buf)); ui_but_add_shortcut(but, buf, false); @@ -1485,7 +1486,7 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) } } else { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (block->flag & UI_BLOCK_SHOW_SHORTCUT_ALWAYS) { /* Skip icon-only buttons (as used in the toolbar). */ if (but->drawstr[0] == '\0') { @@ -1573,10 +1574,7 @@ static void ui_but_extra_operator_icon_free(uiButExtraOpIcon *extra_icon) void ui_but_extra_operator_icons_free(uiBut *but) { - - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.first, *op_icon_next; op_icon; - op_icon = op_icon_next) { - op_icon_next = op_icon->next; + LISTBASE_FOREACH_MUTABLE (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { ui_but_extra_operator_icon_free(op_icon); } BLI_listbase_clear(&but->extra_op_icons); @@ -1658,7 +1656,7 @@ static PredefinedExtraOpIconType ui_but_icon_extra_get(uiBut *but) */ static void ui_but_predefined_extra_operator_icons_add(uiBut *but) { - PredefinedExtraOpIconType extra_icon = ui_but_icon_extra_get(but); + const PredefinedExtraOpIconType extra_icon = ui_but_icon_extra_get(but); wmOperatorType *optype = NULL; BIFIconID icon = ICON_NONE; @@ -1708,7 +1706,6 @@ static void ui_but_predefined_extra_operator_icons_add(uiBut *but) void UI_block_update_from_old(const bContext *C, uiBlock *block) { uiBut *but_old; - uiBut *but; if (!block->oldblock) { return; @@ -1720,7 +1717,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block) UI_butstore_update(block); } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (ui_but_update_from_old_block(C, block, &but, &but_old)) { ui_but_update(but); @@ -1745,7 +1742,6 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x Scene *scene = CTX_data_scene(C); ARegion *region = CTX_wm_region(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - uiBut *but; BLI_assert(block->active); @@ -1755,7 +1751,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_x * on matching buttons, we need this to make button event handling non * blocking, while still allowing buttons to be remade each redraw as it * is expected by blender code */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* temp? Proper check for graying out */ if (but->optype) { wmOperatorType *ot = but->optype; @@ -1875,7 +1871,6 @@ void UI_block_draw(const bContext *C, uiBlock *block) { uiStyle style = *UI_style_get_dpi(); /* XXX pass on as arg */ ARegion *region; - uiBut *but; rcti rect; /* get menu region or area region */ @@ -1889,8 +1884,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) } /* we set this only once */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* scale fonts */ ui_fontscale(&style.paneltitle.points, block->aspect); @@ -1941,7 +1935,7 @@ void UI_block_draw(const bContext *C, uiBlock *block) UI_widgetbase_draw_cache_begin(); /* widgets */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (!(but->flag & (UI_HIDDEN | UI_SCROLLED))) { ui_but_to_pixelrect(&rect, region, block, but); @@ -2053,7 +2047,7 @@ int ui_but_is_pushed_ex(uiBut *but, double *value) /* uiBut.custom_data points to data this tab represents (e.g. workspace). * uiBut.rnapoin/prop store an active value (e.g. active workspace). */ if (RNA_property_type(but->rnaprop) == PROP_POINTER) { - PointerRNA active_ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop); + const PointerRNA active_ptr = RNA_property_pointer_get(&but->rnapoin, but->rnaprop); if (active_ptr.data == but->custom_data) { is_push = true; } @@ -2507,23 +2501,24 @@ int ui_but_string_get_max_length(uiBut *but) uiBut *ui_but_drag_multi_edit_get(uiBut *but) { - uiBut *but_iter; + uiBut *return_but = NULL; BLI_assert(but->flag & UI_BUT_DRAG_MULTI); - for (but_iter = but->block->buttons.first; but_iter; but_iter = but_iter->next) { + LISTBASE_FOREACH (uiBut *, but_iter, &but->block->buttons) { if (but_iter->editstr) { + return_but = but_iter; break; } } - return but_iter; + return return_but; } static double ui_get_but_scale_unit(uiBut *but, double value) { UnitSettings *unit = but->block->unit; - int unit_type = UI_but_unit_type_get(but); + const int unit_type = UI_but_unit_type_get(but); /* Time unit is a bit special, not handled by BKE_scene_unit_scale() for now. */ if (unit_type == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */ @@ -2538,7 +2533,7 @@ void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) { if (ui_but_is_unit(but)) { UnitSettings *unit = but->block->unit; - int unit_type = UI_but_unit_type_get(but); + const int unit_type = UI_but_unit_type_get(but); char *orig_str; orig_str = BLI_strdup(str); @@ -2556,7 +2551,7 @@ static void ui_get_but_string_unit( uiBut *but, char *str, int len_max, double value, bool pad, int float_precision) { UnitSettings *unit = but->block->unit; - int unit_type = UI_but_unit_type_get(but); + const int unit_type = UI_but_unit_type_get(but); int precision; if (unit->scale_length < 0.0001f) { @@ -2589,7 +2584,7 @@ static void ui_get_but_string_unit( static float ui_get_but_step_unit(uiBut *but, float step_default) { - int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); + const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); const double step_orig = step_default * UI_PRECISION_FLOAT_SCALE; /* Scaling up 'step_origg ' here is a bit arbitrary, * its just giving better scales from user POV */ @@ -2660,7 +2655,7 @@ void ui_but_string_get_ex(uiBut *but, } else if (type == PROP_ENUM) { /* RNA enum */ - int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); + const int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); if (RNA_property_enum_name(but->block->evil_C, &but->rnapoin, but->rnaprop, value, &buf)) { BLI_strncpy(str, buf, maxlen); buf = str; @@ -2779,7 +2774,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size) } else if (type == PROP_ENUM) { /* RNA enum */ - int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); + const int value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); const char *value_id; if (!RNA_property_enum_name( but->block->evil_C, &but->rnapoin, but->rnaprop, value, &value_id)) { @@ -2814,7 +2809,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size) } /** - * Report a generic error prefix when evaluating a string with #BPY_execute_string_as_number + * Report a generic error prefix when evaluating a string with #BPY_run_string_as_number * as the Python error on it's own doesn't provide enough context. */ #define UI_NUMBER_EVAL_ERROR_PREFIX IFACE_("Error evaluating number, see Info editor for details") @@ -2839,7 +2834,7 @@ static bool ui_number_from_string(bContext *C, const char *str, double *r_value) { bool ok; #ifdef WITH_PYTHON - ok = BPY_execute_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); + ok = BPY_run_string_as_number(C, NULL, str, UI_NUMBER_EVAL_ERROR_PREFIX, r_value); #else UNUSED_VARS(C); *r_value = atof(str); @@ -2850,10 +2845,10 @@ static bool ui_number_from_string(bContext *C, const char *str, double *r_value) static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value) { - int len = strlen(str); + const int len = strlen(str); if (BLI_strn_endswith(str, "%", len)) { char *str_new = BLI_strdupn(str, len - 1); - bool success = ui_number_from_string(C, str_new, r_value); + const bool success = ui_number_from_string(C, str_new, r_value); MEM_freeN(str_new); *r_value /= 100.0; return success; @@ -2869,10 +2864,10 @@ static bool ui_number_from_string_factor(bContext *C, const char *str, double *r static bool ui_number_from_string_percentage(bContext *C, const char *str, double *r_value) { - int len = strlen(str); + const int len = strlen(str); if (BLI_strn_endswith(str, "%", len)) { char *str_new = BLI_strdupn(str, len - 1); - bool success = ui_number_from_string(C, str_new, r_value); + const bool success = ui_number_from_string(C, str_new, r_value); MEM_freeN(str_new); return success; } @@ -3083,7 +3078,7 @@ static double soft_range_round_up(double value, double max) { /* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. * checking for 0.0 prevents floating point exceptions */ - double newmax = (value != 0.0) ? pow(10.0, ceil(log(value) / M_LN10)) : 0.0; + const double newmax = (value != 0.0) ? pow(10.0, ceil(log(value) / M_LN10)) : 0.0; if (newmax * 0.2 >= max && newmax * 0.2 >= value) { return newmax * 0.2; @@ -3098,7 +3093,7 @@ static double soft_range_round_down(double value, double max) { /* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. * checking for 0.0 prevents floating point exceptions */ - double newmax = (value != 0.0) ? pow(10.0, floor(log(value) / M_LN10)) : 0.0; + const double newmax = (value != 0.0) ? pow(10.0, floor(log(value) / M_LN10)) : 0.0; if (newmax * 5.0 <= max && newmax * 5.0 <= value) { return newmax * 5.0; @@ -3377,11 +3372,7 @@ void UI_blocklist_free(const bContext *C, ListBase *lb) void UI_blocklist_free_inactive(const bContext *C, ListBase *lb) { - uiBlock *block, *nextblock; - - for (block = lb->first; block; block = nextblock) { - nextblock = block->next; - + LISTBASE_FOREACH_MUTABLE (uiBlock *, block, lb) { if (!block->handle) { if (!block->active) { BLI_remlink(lb, block); @@ -3490,6 +3481,9 @@ static void ui_but_build_drawstr_float(uiBut *but, double value) subtype = RNA_property_subtype(but->rnaprop); } + /* Change negative zero to regular zero, without altering anything else. */ + value += +0.0f; + if (value == (double)FLT_MAX) { STR_CONCAT(but->drawstr, slen, "inf"); } @@ -3497,15 +3491,15 @@ static void ui_but_build_drawstr_float(uiBut *but, double value) STR_CONCAT(but->drawstr, slen, "-inf"); } else if (subtype == PROP_PERCENTAGE) { - int prec = ui_but_calc_float_precision(but, value); + const int prec = ui_but_calc_float_precision(but, value); STR_CONCATF(but->drawstr, slen, "%.*f%%", prec, value); } else if (subtype == PROP_PIXEL) { - int prec = ui_but_calc_float_precision(but, value); + const int prec = ui_but_calc_float_precision(but, value); STR_CONCATF(but->drawstr, slen, "%.*f px", prec, value); } else if (subtype == PROP_FACTOR) { - int precision = ui_but_calc_float_precision(but, value); + const int precision = ui_but_calc_float_precision(but, value); if (U.factor_display_type == USER_FACTOR_AS_FACTOR) { STR_CONCATF(but->drawstr, slen, "%.*f", precision, value); @@ -3520,7 +3514,7 @@ static void ui_but_build_drawstr_float(uiBut *but, double value) STR_CONCAT(but->drawstr, slen, new_str); } else { - int prec = ui_but_calc_float_precision(but, value); + const int prec = ui_but_calc_float_precision(but, value); STR_CONCATF(but->drawstr, slen, "%.*f", prec, value); } } @@ -3610,12 +3604,12 @@ static void ui_but_update_ex(uiBut *but, const bool validate) /* only needed for menus in popup blocks that don't recreate buttons on redraw */ if (but->block->flag & UI_BLOCK_LOOP) { if (but->rnaprop && (RNA_property_type(but->rnaprop) == PROP_ENUM)) { - int value_enum = RNA_property_enum_get(&but->rnapoin, but->rnaprop); + const int value_enum = RNA_property_enum_get(&but->rnapoin, but->rnaprop); EnumPropertyItem item; if (RNA_property_enum_item_from_value_gettexted( but->block->evil_C, &but->rnapoin, but->rnaprop, value_enum, &item)) { - size_t slen = strlen(item.name); + const size_t slen = strlen(item.name); ui_but_string_free_internal(but); ui_but_string_set_internal(but, item.name, slen); but->icon = item.icon; @@ -3797,6 +3791,18 @@ static void ui_but_alloc_info(const eButType type, alloc_size = sizeof(uiButHSVCube); alloc_str = "uiButHSVCube"; break; + case UI_BTYPE_COLORBAND: + alloc_size = sizeof(uiButColorBand); + alloc_str = "uiButColorBand"; + break; + case UI_BTYPE_CURVE: + alloc_size = sizeof(uiButCurveMapping); + alloc_str = "uiButCurveMapping"; + break; + case UI_BTYPE_CURVEPROFILE: + alloc_size = sizeof(uiButCurveProfile); + alloc_str = "uiButCurveProfile"; + break; default: alloc_size = sizeof(uiBut); alloc_str = "uiBut"; @@ -4794,7 +4800,7 @@ static uiBut *uiDefButBit(uiBlock *block, float a2, const char *tip) { - int bitIdx = findBitIndex(bit); + const int bitIdx = findBitIndex(bit); if (bitIdx == -1) { return NULL; } @@ -5179,7 +5185,7 @@ static uiBut *uiDefIconButBit(uiBlock *block, float a2, const char *tip) { - int bitIdx = findBitIndex(bit); + const int bitIdx = findBitIndex(bit); if (bitIdx == -1) { return NULL; } @@ -5565,7 +5571,7 @@ static uiBut *uiDefIconTextButBit(uiBlock *block, float a2, const char *tip) { - int bitIdx = findBitIndex(bit); + const int bitIdx = findBitIndex(bit); if (bitIdx == -1) { return NULL; } @@ -5943,10 +5949,9 @@ uiBut *uiDefIconTextButO(uiBlock *block, int UI_blocklist_min_y_get(ListBase *lb) { - uiBlock *block; int min = 0; - for (block = lb->first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, lb) { if (block == lb->first || block->rect.ymin < min) { min = block->rect.ymin; } @@ -5963,7 +5968,6 @@ void UI_block_direction_set(uiBlock *block, char direction) /* this call escapes if there's alignment flags */ void UI_block_order_flip(uiBlock *block) { - uiBut *but; float centy, miny = 10000, maxy = -10000; if (U.uiflag & USER_MENUFIXEDORDER) { @@ -5973,7 +5977,7 @@ void UI_block_order_flip(uiBlock *block) return; } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->drawflag & UI_BUT_ALIGN) { return; } @@ -5986,7 +5990,7 @@ void UI_block_order_flip(uiBlock *block) } /* mirror trick */ centy = (miny + maxy) / 2.0f; - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { but->rect.ymin = centy - (but->rect.ymin - centy); but->rect.ymax = centy - (but->rect.ymax - centy); SWAP(float, but->rect.ymin, but->rect.ymax); @@ -6126,7 +6130,7 @@ void UI_but_unit_type_set(uiBut *but, const int unit_type) int UI_but_unit_type_get(const uiBut *but) { - int ownUnit = (int)but->unit_type; + const int ownUnit = (int)but->unit_type; /* own unit define always takes precedence over RNA provided, allowing for overriding * default value provided in RNA in a few special cases (i.e. Active Keyframe in Graph Edit) @@ -6961,6 +6965,8 @@ void UI_init_userdef(Main *bmain) /* fix saved themes */ init_userdef_do_versions(bmain); uiStyleInit(); + + BLO_sanitize_experimental_features_userpref_blend(&U); } void UI_reinit_font(void) diff --git a/source/blender/editors/interface/interface_align.c b/source/blender/editors/interface/interface_align.c index 4981ef111e0..e92adc8a2ec 100644 --- a/source/blender/editors/interface/interface_align.c +++ b/source/blender/editors/interface/interface_align.c @@ -24,6 +24,7 @@ #include "DNA_screen_types.h" #include "DNA_userdef_types.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -385,7 +386,6 @@ static void ui_block_align_but_to_region(uiBut *but, const ARegion *region) */ void ui_block_align_calc(uiBlock *block, const ARegion *region) { - uiBut *but; int num_buttons = 0; const int sides_to_ui_but_align_flags[4] = SIDE_TO_UI_BUT_ALIGN; @@ -398,7 +398,7 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region) /* First loop: we count number of buttons belonging to an align group, * and clear their align flag. * Tabs get some special treatment here, they get aligned to region border. */ - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* special case: tabs need to be aligned to a region border, drawflag tells which one */ if (but->type == UI_BTYPE_TAB) { ui_block_align_but_to_region(but, region); @@ -431,7 +431,8 @@ void ui_block_align_calc(uiBlock *block, const ARegion *region) memset(butal_array, 0, sizeof(*butal_array) * (size_t)num_buttons); /* Second loop: we initialize our ButAlign data for each button. */ - for (but = block->buttons.first, butal = butal_array; but; but = but->next) { + butal = butal_array; + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->alignnr != 0) { butal->but = but; butal->borders[LEFT] = &but->rect.xmin; @@ -726,11 +727,10 @@ static void ui_block_align_calc_but(uiBut *first, short nr) void ui_block_align_calc(uiBlock *block, const struct ARegion *UNUSED(region)) { - uiBut *but; short nr; /* align buttons with same align nr */ - for (but = block->buttons.first; but;) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->alignnr) { nr = but->alignnr; ui_block_align_calc_but(but, nr); diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index 56df49981e0..6fb9b99632e 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -60,7 +60,7 @@ static FCurve *ui_but_get_fcurve( { /* for entire array buttons we check the first component, it's not perfect * but works well enough in typical cases */ - int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; + const int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; return BKE_fcurve_find_by_rna_context_ui( but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special); @@ -158,7 +158,7 @@ void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but) return; } - int flag = but_anim->flag; + const int flag = but_anim->flag; if (flag & UI_BUT_DRIVEN) { but->icon = ICON_DECORATE_DRIVER; diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c index 46876fca9a5..02a9c3742d7 100644 --- a/source/blender/editors/interface/interface_context_menu.c +++ b/source/blender/editors/interface/interface_context_menu.c @@ -47,7 +47,10 @@ #include "RNA_access.h" -#include "BPY_extern.h" +#ifdef WITH_PYTHON +# include "BPY_extern.h" +# include "BPY_extern_run.h" +#endif #include "WM_api.h" #include "WM_types.h" @@ -88,7 +91,7 @@ static IDProperty *shortcut_property_from_rna(bContext *C, uiBut *but) /* Create ID property of data path, to pass to the operator. */ IDProperty *prop; - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; prop = IDP_New(IDP_GROUP, &val, __func__); IDP_AddToGroup(prop, IDP_NewString(final_data_path, "data_path", strlen(final_data_path) + 1)); @@ -407,7 +410,7 @@ static void ui_but_user_menu_add(bContext *C, uiBut *but, bUserMenu *um) "'%s').label", idname); char *expr_result = NULL; - if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { + if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { STRNCPY(drawstr, expr_result); MEM_freeN(expr_result); } @@ -545,9 +548,9 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) const PropertyType type = RNA_property_type(prop); const PropertySubType subtype = RNA_property_subtype(prop); bool is_anim = RNA_property_animateable(ptr, prop); - bool is_editable = RNA_property_editable(ptr, prop); - bool is_idprop = RNA_property_is_idprop(prop); - bool is_set = RNA_property_is_set(ptr, prop); + const bool is_editable = RNA_property_editable(ptr, prop); + const bool is_idprop = RNA_property_is_idprop(prop); + const bool is_set = RNA_property_is_set(ptr, prop); /* second slower test, * saved people finding keyframe items in menus when its not possible */ @@ -1041,7 +1044,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but) if (idname != NULL) { uiBlock *block = uiLayoutGetBlock(layout); uiBut *but2; - int w = uiLayoutGetWidth(layout); + const int w = uiLayoutGetWidth(layout); wmKeyMap *km; /* We want to know if this op has a shortcut, be it hotkey or not. */ diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 05f6e61ff40..13dd4ce3001 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -161,13 +161,13 @@ void UI_draw_roundbox_aa( GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void UI_draw_roundbox_4fv( @@ -290,13 +290,13 @@ void UI_draw_roundbox_4fv( GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #if 0 @@ -479,14 +479,14 @@ void UI_draw_roundbox_shade_x(bool filled, .alpha_discard = 1.0f, }; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); - GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 11, (float(*)[4]) & widget_params); GPU_batch_draw(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #if 0 /* unused */ @@ -622,10 +622,10 @@ void UI_draw_roundbox_shade_y(bool filled, void UI_draw_text_underline(int pos_x, int pos_y, int len, int height, const float color[4]) { - int ofs_y = 4 * U.pixelsize; + const int ofs_y = 4 * U.pixelsize; GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(color); @@ -644,8 +644,9 @@ void ui_draw_but_TAB_outline(const rcti *rect, uchar highlight_fade[3]) { GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint col = GPU_vertformat_attr_add( + format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); /* add a 1px offset, looks nicer */ const int minx = rect->xmin + U.pixelsize, maxx = rect->xmax - U.pixelsize; const int miny = rect->ymin + U.pixelsize, maxy = rect->ymax - U.pixelsize; @@ -741,20 +742,19 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), return; } - int w = BLI_rcti_size_x(rect); - int h = BLI_rcti_size_y(rect); + const int w = BLI_rcti_size_x(rect); + const int h = BLI_rcti_size_y(rect); /* scissor doesn't seem to be doing the right thing...? */ # if 0 /* prevent drawing outside widget area */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor(rect->xmin, rect->ymin, w, h); # endif - GPU_blend(true); /* Combine with premultiplied alpha. */ - GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); if (w != ibuf->x || h != ibuf->y) { /* We scale the bitmap, rather than have OGL do a worse job. */ @@ -780,10 +780,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), 1.0f, col); - GPU_blend(false); - /* Reset default. */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_NONE); # if 0 // restore scissortest @@ -817,26 +814,22 @@ void UI_draw_safe_areas(uint pos, for (int i = 0; i < safe_len; i++) { if (safe_areas[i][0] || safe_areas[i][1]) { - float margin_x = safe_areas[i][0] * size_x_half; - float margin_y = safe_areas[i][1] * size_y_half; + const float margin_x = safe_areas[i][0] * size_x_half; + const float margin_y = safe_areas[i][1] * size_y_half; - float minx = x1 + margin_x; - float miny = y1 + margin_y; - float maxx = x2 - margin_x; - float maxy = y2 - margin_y; + const float minx = x1 + margin_x; + const float miny = y1 + margin_y; + const float maxx = x2 - margin_x; + const float maxy = y2 - margin_y; imm_draw_box_wire_2d(pos, minx, miny, maxx, maxy); } } } -static void draw_scope_end(const rctf *rect, GLint *scissor) +static void draw_scope_end(const rctf *rect) { - /* Restore scissor test. */ - GPU_scissor(scissor[0], scissor[1], scissor[2], scissor[3]); - - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* outline */ UI_draw_roundbox_corner_set(UI_CNR_ALL); @@ -866,7 +859,7 @@ static void histogram_draw_one(float r, } GPU_line_smooth(true); - GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE, GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); immUniformColor4fv(color); @@ -876,7 +869,7 @@ static void histogram_draw_one(float r, immBegin(GPU_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { - float x2 = x + i * (w / (float)res); + const float x2 = x + i * (w / (float)res); immVertex2f(pos_attr, x2, y + (data[i] * h)); } immEnd(); @@ -887,7 +880,7 @@ static void histogram_draw_one(float r, immVertex2f(pos_attr, x, y); immVertex2f(pos_attr, x, y + (data[0] * h)); for (int i = 1; i < res; i++) { - float x2 = x + i * (w / (float)res); + const float x2 = x + i * (w / (float)res); immVertex2f(pos_attr, x2, y + (data[i] * h)); immVertex2f(pos_attr, x2, y); } @@ -896,11 +889,10 @@ static void histogram_draw_one(float r, /* curve outline */ immUniformColor4f(0.0f, 0.0f, 0.0f, 0.25f); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_LINE_STRIP, res); for (int i = 0; i < res; i++) { - float x2 = x + i * (w / (float)res); + const float x2 = x + i * (w / (float)res); immVertex2f(pos_attr, x2, y + (data[i] * h)); } immEnd(); @@ -917,7 +909,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), const rcti *recti) { Histogram *hist = (Histogram *)but->poin; - int res = hist->x_resolution; + const int res = hist->x_resolution; const bool is_line = (hist->flag & HISTO_FLAG_LINE) != 0; rctf rect = { @@ -927,12 +919,10 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), .ymax = (float)recti->ymax - 1, }; - float w = BLI_rctf_size_x(&rect); - float h = BLI_rctf_size_y(&rect) * hist->ymax; + const float w = BLI_rctf_size_x(&rect); + const float h = BLI_rctf_size_y(&rect) * hist->ymax; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -942,14 +932,14 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), /* need scissor test, histogram can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -999,8 +989,11 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); + /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); } #undef HISTOGRAM_TOT_GRID_LINES @@ -1008,7 +1001,7 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), static void waveform_draw_one(float *waveform, int nbr, const float col[3]) { GPUVertFormat format = {0}; - uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format); GPU_vertbuf_data_alloc(vbo, nbr); @@ -1051,13 +1044,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), if (scopes->wavefrm_yfac < 0.5f) { scopes->wavefrm_yfac = 0.98f; } - float w = BLI_rctf_size_x(&rect) - 7; - float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac; - float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f; - float w3 = w / 3.0f; + const float w = BLI_rctf_size_x(&rect) - 7; + const float h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac; + const float yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) * 0.5f; + const float w3 = w / 3.0f; /* log scale for alpha */ - float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha; + const float alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha; unit_m3(colors); @@ -1071,9 +1064,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), /* Flush text cache before changing scissors. */ BLF_batch_draw_flush(); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -1082,7 +1073,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), true, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f, color); /* need scissor test, waveform can draw outside of boundary */ - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -1100,12 +1091,10 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), /* Flush text cache before drawing things on top. */ BLF_batch_draw_flush(); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1167,7 +1156,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), } if (scopes->ok && scopes->waveform_1 != NULL) { - GPU_blend_set_func(GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); GPU_point_size(1.0); /* LUMA (1 channel) */ @@ -1212,7 +1201,7 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709, SCOPES_WAVEFRM_YCC_JPEG)) { - int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE); + const int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB_PARADE); GPU_matrix_push(); GPU_matrix_translate_2f(rect.xmin, yofs); @@ -1257,10 +1246,13 @@ void ui_draw_but_WAVEFORM(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); + /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static float polar_to_x(float center, float diam, float ampli, float angle) @@ -1393,17 +1385,15 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), .ymax = (float)recti->ymax - 1, }; - float w = BLI_rctf_size_x(&rect); - float h = BLI_rctf_size_y(&rect); - float centerx = rect.xmin + w * 0.5f; - float centery = rect.ymin + h * 0.5f; - float diam = (w < h) ? w : h; + const float w = BLI_rctf_size_x(&rect); + const float h = BLI_rctf_size_y(&rect); + const float centerx = rect.xmin + w * 0.5f; + const float centery = rect.ymin + h * 0.5f; + const float diam = (w < h) ? w : h; - float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha; + const float alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4]; UI_GetThemeColor4fv(TH_PREVIEW_BACK, color); @@ -1413,14 +1403,14 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), /* need scissor test, hvectorscope can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1467,7 +1457,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), /* pixel point cloud */ const float col[3] = {alpha, alpha, alpha}; - GPU_blend_set_func(GPU_ONE, GPU_ONE); + GPU_blend(GPU_BLEND_ADDITIVE); GPU_point_size(1.0); GPU_matrix_push(); @@ -1481,10 +1471,12 @@ void ui_draw_but_VECTORSCOPE(ARegion *UNUSED(region), immUnbindProgram(); + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void ui_draw_colorband_handle_tri_hlight( @@ -1547,11 +1539,11 @@ static void ui_draw_colorband_handle(uint shdr_pos, const float min_width = 3.0f; float colf[3] = {UNPACK3(rgb)}; - float half_width = floorf(sizey / 3.5f); - float height = half_width * 1.4f; + const float half_width = floorf(sizey / 3.5f); + const float height = half_width * 1.4f; float y1 = rect->ymin + (sizey * 0.16f); - float y2 = rect->ymax; + const float y2 = rect->ymax; /* align to pixels */ x = floorf(x + 0.5f); @@ -1595,7 +1587,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, shdr_pos, x - half_width, y1 - 1, x + half_width, y1 + height, false); /* draw all triangles blended */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); ui_draw_colorband_handle_tri(shdr_pos, x, y1 + height, half_width, half_width, true); @@ -1619,7 +1611,7 @@ static void ui_draw_colorband_handle(uint shdr_pos, immUniformColor3ub(0, 0, 0); ui_draw_colorband_handle_tri_hlight(shdr_pos, x, y1 + height, half_width, half_width); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUniformColor3ub(128, 128, 128); ui_draw_colorband_handle_box( @@ -1639,16 +1631,18 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const struct ColorManagedDisplay *display = ui_block_cm_display_get(but->block); uint pos_id, col_id; - ColorBand *coba = (ColorBand *)(but->editcoba ? but->editcoba : but->poin); + uiButColorBand *but_coba = (uiButColorBand *)but; + ColorBand *coba = (but_coba->edit_coba == NULL) ? (ColorBand *)but->poin : but_coba->edit_coba; + if (coba == NULL) { return; } - float x1 = rect->xmin; - float sizex = rect->xmax - x1; - float sizey = BLI_rcti_size_y(rect); - float sizey_solid = sizey * 0.25f; - float y1 = rect->ymin; + const float x1 = rect->xmin; + const float sizex = rect->xmax - x1; + const float sizey = BLI_rcti_size_y(rect); + const float sizey_solid = sizey * 0.25f; + const float y1 = rect->ymin; /* exit early if too narrow */ if (sizex <= 0) { @@ -1675,7 +1669,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); /* layer: color ramp */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); CBData *cbd = coba->data; @@ -1687,7 +1681,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { - float pos = ((float)a) / sizex; + const float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); if (display) { IMB_colormanagement_scene_linear_to_display_v3(colf, display); @@ -1707,7 +1701,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immBegin(GPU_PRIM_TRI_STRIP, (sizex + 1) * 2); for (int a = 0; a <= sizex; a++) { - float pos = ((float)a) / sizex; + const float pos = ((float)a) / sizex; BKE_colorband_evaluate(coba, pos, colf); if (display) { IMB_colormanagement_scene_linear_to_display_v3(colf, display); @@ -1723,7 +1717,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* New format */ format = immVertexFormat(); @@ -1735,7 +1729,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const imm_draw_box_wire_2d(pos_id, x1, y1, x1 + sizex, rect->ymax); /* layer: box outline */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f); immBegin(GPU_PRIM_LINES, 2); @@ -1750,12 +1744,12 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const immVertex2f(pos_id, x1 + sizex, y1 - 1); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* layer: draw handles */ for (int a = 0; a < coba->tot; a++, cbd++) { if (a != coba->cur) { - float pos = x1 + cbd->pos * (sizex - 1) + 1; + const float pos = x1 + cbd->pos * (sizex - 1) + 1; ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, false); } } @@ -1763,7 +1757,7 @@ void ui_draw_but_COLORBAND(uiBut *but, const uiWidgetColors *UNUSED(wcol), const /* layer: active handle */ if (coba->tot != 0) { cbd = &coba->data[coba->cur]; - float pos = x1 + cbd->pos * (sizex - 1) + 1; + const float pos = x1 + cbd->pos * (sizex - 1) + 1; ui_draw_colorband_handle(pos_id, rect, pos, &cbd->r, display, true); } @@ -1790,7 +1784,7 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec /* transform to button */ GPU_matrix_push(); - bool use_project_matrix = (size >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT); + const bool use_project_matrix = (size >= -GPU_MATRIX_ORTHO_CLIP_NEAR_DEFAULT); if (use_project_matrix) { GPU_matrix_push_projection(); GPU_matrix_ortho_set_z(-size, size); @@ -1811,14 +1805,14 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec /* AA circle */ GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ubv(wcol->inner); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); imm_draw_circle_wire_2d(pos, 0.0f, 0.0f, 1.0f, 32); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); if (use_project_matrix) { @@ -1831,37 +1825,35 @@ void ui_draw_but_UNITVEC(uiBut *but, const uiWidgetColors *wcol, const rcti *rec immUnbindProgram(); } -static void ui_draw_but_curve_grid( - uint pos, const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step) +static void ui_draw_but_curve_grid(const uint pos, + const rcti *rect, + const float zoom_x, + const float zoom_y, + const float offset_x, + const float offset_y, + const float step) { - float dx = step * zoomx; - float fx = rect->xmin + zoomx * (-offsx); - if (fx > rect->xmin) { - fx -= dx * (floorf(fx - rect->xmin)); - } + const float start_x = (ceilf(offset_x / step) * step - offset_x) * zoom_x + rect->xmin; + const float start_y = (ceilf(offset_y / step) * step - offset_y) * zoom_y + rect->ymin; - float dy = step * zoomy; - float fy = rect->ymin + zoomy * (-offsy); - if (fy > rect->ymin) { - fy -= dy * (floorf(fy - rect->ymin)); - } + const int line_count_x = ceilf((rect->xmax - start_x) / (step * zoom_x)); + const int line_count_y = ceilf((rect->ymax - start_y) / (step * zoom_y)); - float line_count = (floorf((rect->xmax - fx) / dx) + 1.0f + floorf((rect->ymax - fy) / dy) + - 1.0f); + if (line_count_x + line_count_y == 0) { + return; + } - immBegin(GPU_PRIM_LINES, (int)line_count * 2); - while (fx <= rect->xmax) { - immVertex2f(pos, fx, rect->ymin); - immVertex2f(pos, fx, rect->ymax); - fx += dx; + immBegin(GPU_PRIM_LINES, (line_count_x + line_count_y) * 2); + for (int i = 0; i < line_count_x; i++) { + const float x = start_x + i * step * zoom_x; + immVertex2f(pos, x, rect->ymin); + immVertex2f(pos, x, rect->ymax); } - while (fy <= rect->ymax) { - immVertex2f(pos, rect->xmin, fy); - immVertex2f(pos, rect->xmax, fy); - fy += dy; + for (int i = 0; i < line_count_y; i++) { + const float y = start_y + i * step * zoom_y; + immVertex2f(pos, rect->xmin, y); + immVertex2f(pos, rect->xmax, y); } - /* Note: Assertion fails with here when the view is moved farther below the center. - * Missing two points from the number given with immBegin. */ immEnd(); } @@ -1888,17 +1880,12 @@ static void gl_shaded_color(const uchar *color, int shade) void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, const rcti *rect) { - CurveMapping *cumap; - - if (but->editcumap) { - cumap = but->editcumap; - } - else { - cumap = (CurveMapping *)but->poin; - } + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + CurveMapping *cumap = (but_cumap->edit_cumap == NULL) ? (CurveMapping *)but->poin : + but_cumap->edit_cumap; - float clip_size_x = BLI_rctf_size_x(&cumap->curr); - float clip_size_y = BLI_rctf_size_y(&cumap->curr); + const float clip_size_x = BLI_rctf_size_x(&cumap->curr); + const float clip_size_y = BLI_rctf_size_y(&cumap->curr); /* zero-sized curve */ if (clip_size_x == 0.0f || clip_size_y == 0.0f) { @@ -1906,10 +1893,10 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, } /* calculate offset and zoom */ - float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / clip_size_x; - float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / clip_size_y; - float offsx = cumap->curr.xmin - (1.0f / zoomx); - float offsy = cumap->curr.ymin - (1.0f / zoomy); + const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / clip_size_x; + const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / clip_size_y; + const float offsx = cumap->curr.xmin - (1.0f / zoomx); + const float offsy = cumap->curr.ymin - (1.0f / zoomy); /* exit early if too narrow */ if (zoomx == 0.0f) { @@ -1920,14 +1907,14 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, /* need scissor test, curve can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); rcti scissor_new = { .xmin = rect->xmin, .ymin = rect->ymin, .xmax = rect->xmax, .ymax = rect->ymax, }; - rcti scissor_region = {0, region->winx, 0, region->winy}; + const rcti scissor_region = {0, region->winx, 0, region->winy}; BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new); GPU_scissor(scissor_new.xmin, scissor_new.ymin, @@ -1960,13 +1947,11 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, if (but->a1 == UI_GRAD_H) { /* grid, hsv uses different grid */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); ARRAY_SET_ITEMS(color_backdrop, 0, 0, 0, 48.0 / 255.0); immUniformColor4fv(color_backdrop); ui_draw_but_curve_grid(pos, rect, zoomx, zoomy, offsx, offsy, 0.1666666f); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { if (cumap->flag & CUMA_DO_CLIP) { @@ -2028,7 +2013,7 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, immVertex2f(pos, rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax); } else if (cumap->cur == 3) { - float lum = IMB_colormanagement_get_luminance(cumap->sample); + const float lum = IMB_colormanagement_get_luminance(cumap->sample); immUniformColor3ub(240, 240, 240); immVertex2f(pos, rect->xmin + zoomx * (lum - offsx), rect->ymin); @@ -2079,24 +2064,22 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, } immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Curve filled. */ immUniformColor3ubvAlpha(wcol->item, 128); - GPU_polygon_smooth(true); immBegin(GPU_PRIM_TRI_STRIP, (CM_TABLE * 2 + 2) + 4); immVertex2f(pos, line_range.xmin, rect->ymin); immVertex2f(pos, line_range.xmin, line_range.ymin); for (int a = 0; a <= CM_TABLE; a++) { - float fx = rect->xmin + zoomx * (cmp[a].x - offsx); - float fy = rect->ymin + zoomy * (cmp[a].y - offsy); + const float fx = rect->xmin + zoomx * (cmp[a].x - offsx); + const float fy = rect->ymin + zoomy * (cmp[a].y - offsy); immVertex2f(pos, fx, rect->ymin); immVertex2f(pos, fx, fy); } immVertex2f(pos, line_range.xmax, rect->ymin); immVertex2f(pos, line_range.xmax, line_range.ymax); immEnd(); - GPU_polygon_smooth(false); /* Curve line. */ GPU_line_width(1.0f); @@ -2105,8 +2088,8 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, immBegin(GPU_PRIM_LINE_STRIP, (CM_TABLE + 1) + 2); immVertex2f(pos, line_range.xmin, line_range.ymin); for (int a = 0; a <= CM_TABLE; a++) { - float fx = rect->xmin + zoomx * (cmp[a].x - offsx); - float fy = rect->ymin + zoomy * (cmp[a].y - offsy); + const float fx = rect->xmin + zoomx * (cmp[a].x - offsx); + const float fy = rect->ymin + zoomy * (cmp[a].y - offsy); immVertex2f(pos, fx, fy); } immVertex2f(pos, line_range.xmax, line_range.ymax); @@ -2114,13 +2097,13 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, /* Reset state for fill & line. */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); /* The points, use aspect to make them visible on edges. */ format = immVertexFormat(); pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + const uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); /* Calculate vertex colors based on text theme. */ @@ -2139,8 +2122,8 @@ void ui_draw_but_CURVE(ARegion *region, uiBut *but, const uiWidgetColors *wcol, GPU_point_size(max_ff(1.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f))); immBegin(GPU_PRIM_POINTS, cuma->totpoint); for (int a = 0; a < cuma->totpoint; a++) { - float fx = rect->xmin + zoomx * (cmp[a].x - offsx); - float fy = rect->ymin + zoomy * (cmp[a].y - offsy); + const float fx = rect->xmin + zoomx * (cmp[a].x - offsx); + const float fy = rect->ymin + zoomy * (cmp[a].y - offsy); immAttr4fv(col, (cmp[a].flag & CUMA_SELECT) ? color_vert_select : color_vert); immVertex2f(pos, fx, fy); } @@ -2181,19 +2164,16 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, { uint i; float fx, fy; - CurveProfile *profile; - if (but->editprofile) { - profile = but->editprofile; - } - else { - profile = (CurveProfile *)but->poin; - } + + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + CurveProfile *profile = (but_profile->edit_profile == NULL) ? (CurveProfile *)but->poin : + but_profile->edit_profile; /* Calculate offset and zoom. */ - float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect); - float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect); - float offsx = profile->view_rect.xmin - (1.0f / zoomx); - float offsy = profile->view_rect.ymin - (1.0f / zoomy); + const float zoomx = (BLI_rcti_size_x(rect) - 2.0f) / BLI_rctf_size_x(&profile->view_rect); + const float zoomy = (BLI_rcti_size_y(rect) - 2.0f) / BLI_rctf_size_y(&profile->view_rect); + const float offsx = profile->view_rect.xmin - (1.0f / zoomx); + const float offsy = profile->view_rect.ymin - (1.0f / zoomy); /* Exit early if too narrow. */ if (zoomx == 0.0f) { @@ -2202,14 +2182,14 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Test needed because path can draw outside of boundary. */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); rcti scissor_new = { .xmin = rect->xmin, .ymin = rect->ymin, .xmax = rect->xmax, .ymax = rect->ymax, }; - rcti scissor_region = {0, region->winx, 0, region->winy}; + const rcti scissor_region = {0, region->winx, 0, region->winy}; BLI_rcti_isect(&scissor_new, &scissor_region, &scissor_new); GPU_scissor(scissor_new.xmin, scissor_new.ymin, @@ -2254,10 +2234,10 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, } CurveProfilePoint *pts = profile->table; /* Also add the last points on the right and bottom edges to close off the fill polygon. */ - bool add_left_tri = profile->view_rect.xmin < 0.0f; - bool add_bottom_tri = profile->view_rect.ymin < 0.0f; + const bool add_left_tri = profile->view_rect.xmin < 0.0f; + const bool add_bottom_tri = profile->view_rect.ymin < 0.0f; uint tot_points = (uint)PROF_TABLE_LEN(profile->path_len) + 1 + add_left_tri + add_bottom_tri; - uint tot_triangles = tot_points - 2; + const uint tot_triangles = tot_points - 2; /* Create array of the positions of the table's points. */ float(*table_coords)[2] = MEM_mallocN(sizeof(*table_coords) * tot_points, "table x coords"); @@ -2301,7 +2281,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the triangles for the profile fill. */ immUniformColor3ubvAlpha((const uchar *)wcol->item, 128); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_polygon_smooth(false); immBegin(GPU_PRIM_TRIS, 3 * tot_triangles); for (i = 0; i < tot_triangles; i++) { @@ -2368,7 +2348,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* New GPU instructions for control points and sampled points. */ format = immVertexFormat(); pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + const uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); /* Calculate vertex colors based on text theme. */ @@ -2389,7 +2369,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the control points. */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_point_size(max_ff(3.0f, min_ff(UI_DPI_FAC / but->block->aspect * 5.0f, 5.0f))); immBegin(GPU_PRIM_POINTS, tot_points); for (i = 0; i < tot_points; i++) { @@ -2403,7 +2383,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Draw the handle points. */ if (selected_free_points > 0) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_point_size(max_ff(2.0f, min_ff(UI_DPI_FAC / but->block->aspect * 4.0f, 4.0f))); immBegin(GPU_PRIM_POINTS, selected_free_points * 2); for (i = 0; i < tot_points; i++) { @@ -2467,16 +2447,14 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), .ymax = (float)recti->ymax - 1, }; - int width = BLI_rctf_size_x(&rect) + 1; - int height = BLI_rctf_size_y(&rect); + const int width = BLI_rctf_size_x(&rect) + 1; + const int height = BLI_rctf_size_y(&rect); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* need scissor test, preview image can draw outside of boundary */ int scissor[4]; - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor((rect.xmin - 1), (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), @@ -2556,8 +2534,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), GPU_scissor(rect.xmin, rect.ymin, BLI_rctf_size_x(&rect), BLI_rctf_size_y(&rect)); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); UI_GetThemeColor4fv(TH_SEL_MARKER, col_sel); @@ -2568,10 +2546,10 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), const float pos_sel[8] = {-10.0f, -7.0f, -4.0f, -1.0f, 2.0f, 5.0f, 8.0f, 11.0f}; for (int axe = 0; axe < 2; axe++) { for (int i = 0; i < 7; i++) { - float x1 = pos_sel[i] * (1 - axe); - float y1 = pos_sel[i] * axe; - float x2 = pos_sel[i + 1] * (1 - axe); - float y2 = pos_sel[i + 1] * axe; + const float x1 = pos_sel[i] * (1 - axe); + const float y1 = pos_sel[i] * axe; + const float x2 = pos_sel[i + 1] * (1 - axe); + const float y2 = pos_sel[i + 1] * axe; if (i % 2 == 1) { immAttr4fv(col, col_sel); @@ -2601,10 +2579,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *UNUSED(region), true, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f, color); } + /* Restore scissor test. */ + GPU_scissor(UNPACK4(scissor)); /* outline */ - draw_scope_end(&rect, scissor); + draw_scope_end(&rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* ****************************************************** */ @@ -2685,10 +2665,10 @@ static void ui_shadowbox(uint pos, void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float maxy) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint color = GPU_vertformat_attr_add( format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); @@ -2705,7 +2685,7 @@ void UI_draw_box_shadow(uchar alpha, float minx, float miny, float maxx, float m immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ui_draw_dropshadow( @@ -2731,7 +2711,7 @@ void ui_draw_dropshadow( a = i * aspect; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const float dalpha = alpha * 2.0f / 255.0f; float calpha = dalpha; float visibility = 1.0f; @@ -2768,7 +2748,7 @@ void ui_draw_dropshadow( GPUBatch *batch = ui_batch_roundbox_shadow_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_SHADOW); - GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float *)&widget_params); + GPU_batch_uniform_4fv_array(batch, "parameters", 4, (float(*)[4]) & widget_params); GPU_batch_uniform_1f(batch, "alpha", 1.0f - visibility); GPU_batch_draw(batch); @@ -2782,5 +2762,5 @@ void ui_draw_dropshadow( radius + 0.5f, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c index b757341ae13..76b361a9e68 100644 --- a/source/blender/editors/interface/interface_eyedropper_colorband.c +++ b/source/blender/editors/interface/interface_eyedropper_colorband.c @@ -109,7 +109,7 @@ static bool eyedropper_colorband_init(bContext *C, wmOperator *op) } if (!band) { - PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp); + const PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp); if (ptr.data != NULL) { band = ptr.data; @@ -200,7 +200,7 @@ static void eyedropper_colorband_apply(bContext *C, wmOperator *op) { EyedropperColorband *eye = op->customdata; /* Always filter, avoids noise in resulting color-band. */ - bool filter_samples = true; + const bool filter_samples = true; BKE_colorband_init_from_table_rgba( eye->color_band, eye->color_buffer, eye->color_buffer_len, filter_samples); eye->is_set = true; @@ -339,7 +339,7 @@ static bool eyedropper_colorband_poll(bContext *C) if (but && but->type == UI_BTYPE_COLORBAND) { return true; } - PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp); + const PointerRNA ptr = CTX_data_pointer_get_type(C, "color_ramp", &RNA_ColorRamp); if (ptr.data != NULL) { return true; } diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c index a162cac1b02..dd55d2c364b 100644 --- a/source/blender/editors/interface/interface_eyedropper_datablock.c +++ b/source/blender/editors/interface/interface_eyedropper_datablock.c @@ -117,7 +117,7 @@ static int datadropper_init(bContext *C, wmOperator *op) * because this struct has very short lifetime. */ ddr->idcode_name = TIP_(BKE_idtype_idcode_to_name(ddr->idcode)); - PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop); + const PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop); ddr->init_id = ptr.owner_id; return true; diff --git a/source/blender/editors/interface/interface_eyedropper_driver.c b/source/blender/editors/interface/interface_eyedropper_driver.c index 0162e205c29..d13e47624ee 100644 --- a/source/blender/editors/interface/interface_eyedropper_driver.c +++ b/source/blender/editors/interface/interface_eyedropper_driver.c @@ -95,8 +95,8 @@ static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *eve DriverDropper *ddr = (DriverDropper *)op->customdata; uiBut *but = eyedropper_get_property_button_under_mouse(C, event); - short mapping_type = RNA_enum_get(op->ptr, "mapping_type"); - short flag = 0; + const short mapping_type = RNA_enum_get(op->ptr, "mapping_type"); + const short flag = 0; /* we can only add a driver if we know what RNA property it corresponds to */ if (but == NULL) { @@ -105,7 +105,7 @@ static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *eve /* Get paths for src... */ PointerRNA *target_ptr = &but->rnapoin; PropertyRNA *target_prop = but->rnaprop; - int target_index = but->rnaindex; + const int target_index = but->rnaindex; char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop); diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c index aa5b4d2c255..f7c41a7142b 100644 --- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c +++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c @@ -38,6 +38,7 @@ #include "BKE_context.h" #include "BKE_gpencil.h" +#include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_paint.h" @@ -208,9 +209,13 @@ static void eyedropper_add_palette_color(bContext *C, const float col_conv[4]) /* Check for Palette in Draw and Vertex Paint Mode. */ if (paint->palette == NULL) { - paint->palette = BKE_palette_add(bmain, "Grease Pencil"); + Palette *palette = BKE_palette_add(bmain, "Grease Pencil"); + id_us_min(&palette->id); + + BKE_paint_palette_set(paint, palette); + if (vertexpaint->palette == NULL) { - vertexpaint->palette = paint->palette; + BKE_paint_palette_set(vertexpaint, palette); } } /* Check if the color exist already. */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2d3a6181f09..bf88b3c0318 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -85,23 +85,45 @@ # include "wm_window.h" #endif -/* place the mouse at the scaled down location when un-grabbing */ +/* -------------------------------------------------------------------- */ +/** \name Feature Defines + * + * These defines allow developers to locally toggle functionality which + * may be useful for testing (especially conflicts in dragging). + * Ideally the code would be refactored to support this functionality in a less fragile way. + * Until then keep these defines. + * \{ */ + +/** Place the mouse at the scaled down location when un-grabbing. */ #define USE_CONT_MOUSE_CORRECT -/* support dragging toggle buttons */ +/** Support dragging toggle buttons. */ #define USE_DRAG_TOGGLE -/* support dragging multiple number buttons at once */ +/** Support dragging multiple number buttons at once. */ #define USE_DRAG_MULTINUM -/* allow dragging/editing all other selected items at once */ +/** Allow dragging/editing all other selected items at once. */ #define USE_ALLSELECT -/* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */ +/** + * Check to avoid very small mouse-moves from jumping away from keyboard navigation, + * while larger mouse motion will override keyboard input, see: T34936. + */ #define USE_KEYNAV_LIMIT -/* drag popups by their header */ +/** Support dragging popups by their header. */ #define USE_DRAG_POPUP +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Local Defines + * \{ */ + +/** + * The buffer side used for password strings, where the password is stored internally, + * but not displayed. + */ #define UI_MAX_PASSWORD_STR 128 /** @@ -117,7 +139,12 @@ */ #define UI_DRAG_MAP_SOFT_RANGE_PIXEL_MAX 1000 -/* proto */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Local Prototypes + * \{ */ + static int ui_do_but_EXIT(bContext *C, uiBut *but, struct uiHandleButtonData *data, @@ -131,6 +158,8 @@ static void ui_mouse_motion_keynav_init(struct uiKeyNavLock *keynav, const wmEve static bool ui_mouse_motion_keynav_test(struct uiKeyNavLock *keynav, const wmEvent *event); #endif +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Structs & Defines * \{ */ @@ -667,9 +696,7 @@ static ListBase UIAfterFuncs = {NULL, NULL}; static uiAfterFunc *ui_afterfunc_new(void) { - uiAfterFunc *after; - - after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); + uiAfterFunc *after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); BLI_addtail(&UIAfterFuncs, after); @@ -718,7 +745,6 @@ static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but) static void ui_apply_but_func(bContext *C, uiBut *but) { - uiAfterFunc *after; uiBlock *block = but->block; /* these functions are postponed and only executed after all other @@ -726,7 +752,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) * with these functions removing the buttons we are working with */ if (ui_afterfunc_check(block, but)) { - after = ui_afterfunc_new(); + uiAfterFunc *after = ui_afterfunc_new(); if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) { /* exception, this will crash due to removed button otherwise */ @@ -788,8 +814,6 @@ static void ui_apply_but_func(bContext *C, uiBut *but) /* typically call ui_apply_but_undo(), ui_apply_but_autokey() */ static void ui_apply_but_undo(uiBut *but) { - uiAfterFunc *after; - if (but->flag & UI_BUT_UNDO) { const char *str = NULL; bool skip_undo = false; @@ -842,7 +866,7 @@ static void ui_apply_but_undo(uiBut *but) } /* delayed, after all other funcs run, popups are closed, etc */ - after = ui_afterfunc_new(); + uiAfterFunc *after = ui_afterfunc_new(); BLI_strncpy(after->undostr, str, sizeof(after->undostr)); } } @@ -874,16 +898,12 @@ static void ui_apply_but_autokey(bContext *C, uiBut *but) static void ui_apply_but_funcs_after(bContext *C) { - uiAfterFunc *afterf, after; - PointerRNA opptr; - ListBase funcs; - /* copy to avoid recursive calls */ - funcs = UIAfterFuncs; + ListBase funcs = UIAfterFuncs; BLI_listbase_clear(&UIAfterFuncs); - for (afterf = funcs.first; afterf; afterf = after.next) { - after = *afterf; /* copy to avoid memleak on exit() */ + LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) { + uiAfterFunc after = *afterf; /* copy to avoid memleak on exit() */ BLI_freelinkN(&funcs, afterf); if (after.context) { @@ -894,6 +914,7 @@ static void ui_apply_but_funcs_after(bContext *C) popup_check(C, after.popup_op); } + PointerRNA opptr; if (after.opptr) { /* free in advance to avoid leak on exit */ opptr = *after.opptr; @@ -1009,14 +1030,12 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) { - uiBut *bt; - ui_but_value_set(but, but->hardmax); ui_apply_but_func(C, but); /* states of other row buttons */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt != but && bt->poin == but->poin && ELEM(bt->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { ui_but_update_edited(bt); } @@ -1144,12 +1163,10 @@ static void ui_apply_but_CURVEPROFILE(bContext *C, uiBut *but, uiHandleButtonDat /* small multi-but api */ static void ui_multibut_add(uiHandleButtonData *data, uiBut *but) { - uiButMultiState *mbut_state; - BLI_assert(but->flag & UI_BUT_DRAG_MULTI); BLI_assert(data->multi_data.has_mbuts); - mbut_state = MEM_callocN(sizeof(*mbut_state), __func__); + uiButMultiState *mbut_state = MEM_callocN(sizeof(*mbut_state), __func__); mbut_state->but = but; mbut_state->origvalue = ui_but_value_get(but); # ifdef USE_ALLSELECT @@ -1163,9 +1180,7 @@ static void ui_multibut_add(uiHandleButtonData *data, uiBut *but) static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut *but) { - LinkNode *l; - - for (l = data->multi_data.mbuts; l; l = l->next) { + for (LinkNode *l = data->multi_data.mbuts; l; l = l->next) { uiButMultiState *mbut_state; mbut_state = l->link; @@ -1180,9 +1195,7 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->flag & UI_BUT_DRAG_MULTI) { uiButMultiState *mbut_state = ui_multibut_lookup(data, but); if (mbut_state) { @@ -1235,7 +1248,6 @@ static bool ui_multibut_states_tag(uiBut *but_active, uiHandleButtonData *data, const wmEvent *event) { - uiBut *but; float seg[2][2]; bool changed = false; @@ -1253,7 +1265,7 @@ static bool ui_multibut_states_tag(uiBut *but_active, data->multi_data.has_mbuts = false; /* follow ui_but_find_mouse_over_ex logic */ - for (but = but_active->block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &but_active->block->buttons) { bool drag_prev = false; bool drag_curr = false; @@ -1318,12 +1330,11 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl const double value_delta = data->value - data->origvalue; const double value_scale = data->multi_data.is_proportional ? (data->value / data->origvalue) : 0.0; - uiBut *but; BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_ENABLE); BLI_assert(data->multi_data.skip == false); - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->flag & UI_BUT_DRAG_MULTI) { /* mbut_states for delta */ uiButMultiState *mbut_state = ui_multibut_lookup(data, but); @@ -1447,18 +1458,15 @@ static bool ui_drag_toggle_set_xy_xy( /* popups such as layers won't re-evaluate on redraw */ const bool do_check = (region->regiontype == RGN_TYPE_TEMPORARY); bool changed = false; - uiBlock *block; - - for (block = region->uiblocks.first; block; block = block->next) { - uiBut *but; + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { float xy_a_block[2] = {UNPACK2(xy_src)}; float xy_b_block[2] = {UNPACK2(xy_dst)}; ui_window_to_block_fl(region, block, &xy_a_block[0], &xy_a_block[1]); ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]); - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* Note: ctrl is always true here because (at least for now) * we always want to consider text control in this case, even when not embossed. */ if (ui_but_is_interactive(but, true)) { @@ -1467,7 +1475,7 @@ static bool ui_drag_toggle_set_xy_xy( /* execute the button */ if (ui_drag_toggle_but_is_supported(but)) { /* is it pressed? */ - int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but); + const int pushed_state_but = ui_drag_toggle_but_pushed_state(C, but); if (pushed_state_but != pushed_state) { UI_but_execute(C, region, but); if (do_check) { @@ -1496,7 +1504,6 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const { ARegion *region = CTX_wm_region(C); bool do_draw = false; - int xy[2]; /** * Initialize Locking: @@ -1535,6 +1542,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const } /* done with axis locking */ + int xy[2]; xy[0] = (drag_info->xy_lock[0] == false) ? xy_input[0] : drag_info->xy_last[0]; xy[1] = (drag_info->xy_lock[1] == false) ? xy_input[1] : drag_info->xy_last[1]; @@ -1608,17 +1616,16 @@ static bool ui_but_is_drag_toggle(const uiBut *but) static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore *selctx_data) { - PointerRNA ptr, lptr, idptr; - PropertyRNA *prop, *lprop; + PointerRNA lptr, idptr; + PropertyRNA *lprop; bool success = false; - int index; char *path = NULL; ListBase lb = {NULL}; - ptr = but->rnapoin; - prop = but->rnaprop; - index = but->rnaindex; + PointerRNA ptr = but->rnapoin; + PropertyRNA *prop = but->rnaprop; + const int index = but->rnaindex; /* for now don't support whole colors */ if (index == -1) { @@ -1627,9 +1634,7 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore /* if there is a valid property that is editable... */ if (ptr.data && prop) { - CollectionPointerLink *link; bool use_path_from_id; - int i; /* some facts we want to know */ const bool is_array = RNA_property_array_check(prop); @@ -1640,8 +1645,11 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore selctx_data->elems_len = BLI_listbase_count(&lb); selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__); - - for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) { + int i; + LISTBASE_FOREACH_INDEX (CollectionPointerLink *, link, &lb, i) { + if (i >= selctx_data->elems_len) { + break; + } uiSelectContextElem *other = &selctx_data->elems[i]; /* TODO,. de-duplicate copy_to_selected_button */ if (link->ptr.data != ptr.data) { @@ -1745,8 +1753,7 @@ static void ui_selectcontext_apply(bContext *C, if (selctx_data->elems) { PropertyRNA *prop = but->rnaprop; PropertyRNA *lprop = but->rnaprop; - int index = but->rnaindex; - int i; + const int index = but->rnaindex; const bool use_delta = (selctx_data->is_copy == false); union { @@ -1789,7 +1796,7 @@ static void ui_selectcontext_apply(bContext *C, # ifdef USE_ALLSELECT_LAYER_HACK /* make up for not having 'handle_layer_buttons' */ { - PropertySubType subtype = RNA_property_subtype(prop); + const PropertySubType subtype = RNA_property_subtype(prop); if ((rna_type == PROP_BOOLEAN) && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER) && is_array && /* could check for 'handle_layer_buttons' */ @@ -1801,7 +1808,7 @@ static void ui_selectcontext_apply(bContext *C, tmparray[index] = true; - for (i = 0; i < selctx_data->elems_len; i++) { + for (int i = 0; i < selctx_data->elems_len; i++) { uiSelectContextElem *other = &selctx_data->elems[i]; PointerRNA lptr = other->ptr; RNA_property_boolean_set_array(&lptr, lprop, tmparray); @@ -1816,7 +1823,7 @@ static void ui_selectcontext_apply(bContext *C, } # endif - for (i = 0; i < selctx_data->elems_len; i++) { + for (int i = 0; i < selctx_data->elems_len; i++) { uiSelectContextElem *other = &selctx_data->elems[i]; PointerRNA lptr = other->ptr; @@ -2025,12 +2032,7 @@ static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDat static void ui_apply_but( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive) { - char *editstr; - double *editval; - float *editvec; - ColorBand *editcoba; - CurveMapping *editcumap; - CurveProfile *editprofile; + const eButType but_type = but->type; /* Store as const to quiet maybe uninitialized warning. */ data->retval = 0; @@ -2083,21 +2085,42 @@ static void ui_apply_but( } /* ensures we are writing actual values */ - editstr = but->editstr; - editval = but->editval; - editvec = but->editvec; - editcoba = but->editcoba; - editcumap = but->editcumap; - editprofile = but->editprofile; + char *editstr = but->editstr; + double *editval = but->editval; + float *editvec = but->editvec; + ColorBand *editcoba; + CurveMapping *editcumap; + CurveProfile *editprofile; + if (but_type == UI_BTYPE_COLORBAND) { + uiButColorBand *but_coba = (uiButColorBand *)but; + editcoba = but_coba->edit_coba; + } + else if (but_type == UI_BTYPE_CURVE) { + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + editcumap = but_cumap->edit_cumap; + } + else if (but_type == UI_BTYPE_CURVEPROFILE) { + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + editprofile = but_profile->edit_profile; + } but->editstr = NULL; but->editval = NULL; but->editvec = NULL; - but->editcoba = NULL; - but->editcumap = NULL; - but->editprofile = NULL; + if (but_type == UI_BTYPE_COLORBAND) { + uiButColorBand *but_coba = (uiButColorBand *)but; + but_coba->edit_coba = NULL; + } + else if (but_type == UI_BTYPE_CURVE) { + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + but_cumap->edit_cumap = NULL; + } + else if (but_type == UI_BTYPE_CURVEPROFILE) { + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + but_profile->edit_profile = NULL; + } /* handle different types */ - switch (but->type) { + switch (but_type) { case UI_BTYPE_BUT: case UI_BTYPE_DECORATOR: ui_apply_but_BUT(C, but, data); @@ -2203,9 +2226,18 @@ static void ui_apply_but( but->editstr = editstr; but->editval = editval; but->editvec = editvec; - but->editcoba = editcoba; - but->editcumap = editcumap; - but->editprofile = editprofile; + if (but_type == UI_BTYPE_COLORBAND) { + uiButColorBand *but_coba = (uiButColorBand *)but; + but_coba->edit_coba = editcoba; + } + else if (but_type == UI_BTYPE_CURVE) { + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + but_cumap->edit_cumap = editcumap; + } + else if (but_type == UI_BTYPE_CURVEPROFILE) { + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + but_profile->edit_profile = editprofile; + } } /** \} */ @@ -2217,10 +2249,9 @@ static void ui_apply_but( /* only call if event type is EVT_DROP */ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleButtonData *data) { - wmDrag *wmd; ListBase *drags = event->customdata; /* drop event type has listbase customdata by default */ - for (wmd = drags->first; wmd; wmd = wmd->next) { + LISTBASE_FOREACH (wmDrag *, wmd, drags) { if (wmd->type == WM_DRAG_ID) { /* align these types with UI_but_active_drop_name */ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { @@ -2249,10 +2280,9 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB static void ui_but_get_pasted_text_from_clipboard(char **buf_paste, int *buf_len) { - char *text; - int length; /* get only first line even if the clipboard contains multiple lines */ - text = WM_clipboard_text_get_firstline(false, &length); + int length; + char *text = WM_clipboard_text_get_firstline(false, &length); if (text) { *buf_paste = text; @@ -2323,7 +2353,7 @@ static void float_array_to_string(float *values, static void ui_but_copy_numeric_array(uiBut *but, char *output, int output_len_max) { - int array_length = get_but_property_array_length(but); + const int array_length = get_but_property_array_length(but); float *values = alloca(array_length * sizeof(float)); RNA_property_float_get_array(&but->rnapoin, but->rnaprop, values); float_array_to_string(values, array_length, output, output_len_max); @@ -2335,7 +2365,8 @@ static bool parse_float_array(char *text, float *values, int expected_length) BLI_assert(0 <= expected_length && expected_length <= 4); float v[5]; - int actual_length = sscanf(text, "[%f, %f, %f, %f, %f]", &v[0], &v[1], &v[2], &v[3], &v[4]); + const int actual_length = sscanf( + text, "[%f, %f, %f, %f, %f]", &v[0], &v[1], &v[2], &v[3], &v[4]); if (actual_length == expected_length) { memcpy(values, v, sizeof(float) * expected_length); @@ -2349,7 +2380,7 @@ static void ui_but_paste_numeric_array(bContext *C, uiHandleButtonData *data, char *buf_paste) { - int array_length = get_but_property_array_length(but); + const int array_length = get_but_property_array_length(but); if (array_length > 4) { // not supported for now return; @@ -2379,7 +2410,6 @@ static void ui_but_paste_numeric_value(bContext *C, char *buf_paste) { double value; - if (ui_but_string_eval_number(C, but, buf_paste, &value)) { button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); data->value = value; @@ -2441,7 +2471,7 @@ static void ui_but_paste_color(bContext *C, uiBut *but, char *buf_paste) } /* Some color properties are RGB, not RGBA. */ - int array_len = get_but_property_array_length(but); + const int array_len = get_but_property_array_length(but); BLI_assert(ELEM(array_len, 3, 4)); ui_but_set_float_array(C, but, NULL, rgba, array_len); } @@ -2537,8 +2567,7 @@ static void ui_but_paste_CurveProfile(bContext *C, uiBut *but) static void ui_but_copy_operator(bContext *C, uiBut *but, char *output, int output_len_max) { - PointerRNA *opptr; - opptr = UI_but_operator_ptr_get(but); + PointerRNA *opptr = UI_but_operator_ptr_get(but); char *str; str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr); @@ -2579,7 +2608,7 @@ static void ui_but_copy(bContext *C, uiBut *but, const bool copy_array) /* Left false for copying internal data (color-band for eg). */ bool is_buf_set = false; - bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL); + const bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL); switch (but->type) { case UI_BTYPE_NUM: @@ -2670,7 +2699,7 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons char *buf_paste; ui_but_get_pasted_text_from_clipboard(&buf_paste, &buf_paste_len); - bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL); + const bool has_required_data = !(but->poin == NULL && but->rnapoin.data == NULL); switch (but->type) { case UI_BTYPE_NUM: @@ -2750,12 +2779,9 @@ void ui_but_clipboard_free(void) static int ui_text_position_from_hidden(uiBut *but, int pos) { - const char *strpos, *butstr; - int i; - - butstr = (but->editstr) ? but->editstr : but->drawstr; - - for (i = 0, strpos = butstr; i < pos; i++) { + const char *butstr = (but->editstr) ? but->editstr : but->drawstr; + const char *strpos = butstr; + for (int i = 0; i < pos; i++) { strpos = BLI_str_find_next_char_utf8(strpos, NULL); } @@ -2772,13 +2798,11 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *but, const bool restore) { - char *butstr; - if (!(but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_PASSWORD)) { return; } - butstr = (but->editstr) ? but->editstr : but->drawstr; + char *butstr = (but->editstr) ? but->editstr : but->drawstr; if (restore) { /* restore original string */ @@ -2879,7 +2903,7 @@ static bool ui_textedit_set_cursor_pos_foreach_glyph(const char *UNUSED(str), void *user_data) { int *cursor_data = user_data; - float center = glyph_step_bounds->xmin + (BLI_rctf_size_x(glyph_bounds) / 2.0f); + const float center = glyph_step_bounds->xmin + (BLI_rctf_size_x(glyph_bounds) / 2.0f); if (cursor_data[0] < center) { cursor_data[1] = str_step_ofs; return false; @@ -2948,7 +2972,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con else { str_last = &str[but->ofs]; const int str_last_len = strlen(str_last); - int x_pos = (int)(x - startx); + const int x_pos = (int)(x - startx); int glyph_data[2] = { x_pos, /* horizontal position to test. */ -1, /* Write the character offset here. */ @@ -2996,7 +3020,7 @@ static bool ui_textedit_insert_buf(uiBut *but, int buf_len) { int len = strlen(data->str); - int len_new = len - (but->selend - but->selsta) + 1; + const int len_new = len - (but->selend - but->selsta) + 1; bool changed = false; if (data->is_str_dynamic) { @@ -3148,11 +3172,9 @@ static bool ui_textedit_delete(uiBut *but, static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) { - char *str; - int changed; - - str = data->str; + char *str = data->str; + int changed; if (data->searchbox) { changed = ui_searchbox_autocomplete(C, data->searchbox, but, data->str); } @@ -3175,14 +3197,13 @@ enum { static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const int mode) { - char *pbuf; bool changed = false; - int buf_len; /* paste */ if (mode == UI_TEXTEDIT_PASTE) { /* extract the first line from the clipboard */ - pbuf = WM_clipboard_text_get_firstline(false, &buf_len); + int buf_len; + char *pbuf = WM_clipboard_text_get_firstline(false, &buf_len); if (pbuf) { if (UI_but_is_utf8(but)) { @@ -3199,7 +3220,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in /* cut & copy */ else if (ELEM(mode, UI_TEXTEDIT_COPY, UI_TEXTEDIT_CUT)) { /* copy the contents to the copypaste buffer */ - int sellen = but->selend - but->selsta; + const int sellen = but->selend - but->selsta; char *buf = MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste"); BLI_strncpy(buf, data->str + but->selsta, sellen + 1); @@ -3262,7 +3283,6 @@ wmIMEData *ui_but_ime_data_get(uiBut *but) static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) { wmWindow *win = data->window; - int len; const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER); bool no_zero_strip = false; @@ -3317,7 +3337,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) } /* won't change from now on */ - len = strlen(data->str); + const int len = strlen(data->str); data->origstr = BLI_strdupn(data->str, len); data->sel_pos_init = 0; @@ -3360,7 +3380,7 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) if (but) { if (UI_but_is_utf8(but)) { - int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr)); + const int strip = BLI_utf8_invalid_strip(but->editstr, strlen(but->editstr)); /* not a file?, strip non utf-8 chars */ if (strip) { /* wont happen often so isn't that annoying to keep it here for a while */ @@ -3405,8 +3425,6 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data) { - uiBut *but; - /* label and roundbox can overlap real buttons (backdrops...) */ if (ELEM(actbut->type, UI_BTYPE_LABEL, @@ -3417,7 +3435,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; } - for (but = actbut->next; but; but = but->next) { + for (uiBut *but = actbut->next; but; but = but->next) { if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; @@ -3426,7 +3444,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } } - for (but = block->buttons.first; but != actbut; but = but->next) { + for (uiBut *but = block->buttons.first; but != actbut; but = but->next) { if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; @@ -3439,8 +3457,6 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonData *data) { - uiBut *but; - /* label and roundbox can overlap real buttons (backdrops...) */ if (ELEM(actbut->type, UI_BTYPE_LABEL, @@ -3451,7 +3467,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa return; } - for (but = actbut->prev; but; but = but->prev) { + for (uiBut *but = actbut->prev; but; but = but->prev) { if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; @@ -3460,7 +3476,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa } } } - for (but = block->buttons.last; but != actbut; but = but->prev) { + for (uiBut *but = block->buttons.last; but != actbut; but = but->prev) { if (ui_but_is_editable_as_text(but)) { if (!(but->flag & UI_BUT_DISABLED)) { data->postbut = but; @@ -3480,9 +3496,9 @@ static void ui_do_but_textedit( #ifdef WITH_INPUT_IME wmWindow *win = CTX_wm_window(C); wmIMEData *ime_data = win->ime_data; - bool is_ime_composing = ime_data && ime_data->is_ime_composing; + const bool is_ime_composing = ime_data && ime_data->is_ime_composing; #else - bool is_ime_composing = false; + const bool is_ime_composing = false; #endif switch (event->type) { @@ -3498,7 +3514,7 @@ static void ui_do_but_textedit( ui_searchbox_event(C, data->searchbox, but, data->region, event); } #else - ui_searchbox_event(C, data->searchbox, but, event); + ui_searchbox_event(C, data->searchbox, but, data->region, event); #endif } @@ -3529,7 +3545,7 @@ static void ui_do_but_textedit( } break; case LEFTMOUSE: { - bool had_selection = but->selsta != but->selend; + const bool had_selection = but->selsta != but->selend; /* exit on LMB only on RELEASE for searchbox, to mimic other popups, * and allow multiple menu levels */ @@ -3540,10 +3556,8 @@ static void ui_do_but_textedit( /* for double click: we do a press again for when you first click on button * (selects all text, no cursor pos) */ if (event->val == KM_PRESS || event->val == KM_DBL_CLICK) { - float mx, my; - - mx = event->x; - my = event->y; + float mx = event->x; + float my = event->y; ui_window_to_block_fl(data->region, block, &mx, &my); if (ui_but_contains_pt(but, mx, my)) { @@ -3689,7 +3703,7 @@ static void ui_do_but_textedit( case EVT_TABKEY: /* there is a key conflict here, we can't tab with autocomplete */ if (but->autocomplete_func || data->searchbox) { - int autocomplete = ui_textedit_autocomplete(C, but, data); + const int autocomplete = ui_textedit_autocomplete(C, but, data); changed = autocomplete != AUTOCOMPLETE_NO_MATCH; if (autocomplete == AUTOCOMPLETE_FULL_MATCH) { @@ -3753,7 +3767,7 @@ static void ui_do_but_textedit( } if (utf8_buf && utf8_buf[0]) { - int utf8_buf_len = BLI_str_utf8_size(utf8_buf); + const int utf8_buf_len = BLI_str_utf8_size(utf8_buf); BLI_assert(utf8_buf_len != -1); changed = ui_textedit_insert_buf(but, data, event->utf8_buf, utf8_buf_len); } @@ -3813,12 +3827,12 @@ static void ui_do_but_textedit( static void ui_do_but_textedit_select( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my, retval = WM_UI_HANDLER_CONTINUE; + int retval = WM_UI_HANDLER_CONTINUE; switch (event->type) { case MOUSEMOVE: { - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); ui_textedit_set_cursor_select(but, data, event->x); @@ -3848,14 +3862,17 @@ static void ui_do_but_textedit_select( static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data) { if (but->type == UI_BTYPE_CURVE) { - but->editcumap = (CurveMapping *)but->poin; + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + but_cumap->edit_cumap = (CurveMapping *)but->poin; } - if (but->type == UI_BTYPE_CURVEPROFILE) { - but->editprofile = (CurveProfile *)but->poin; + else if (but->type == UI_BTYPE_CURVEPROFILE) { + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + but_profile->edit_profile = (CurveProfile *)but->poin; } else if (but->type == UI_BTYPE_COLORBAND) { + uiButColorBand *but_coba = (uiButColorBand *)but; data->coba = (ColorBand *)but->poin; - but->editcoba = data->coba; + but_coba->edit_coba = data->coba; } else if (ELEM(but->type, UI_BTYPE_UNITVEC, @@ -3941,10 +3958,18 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) { but->editval = NULL; but->editvec = NULL; - but->editcoba = NULL; - but->editcumap = NULL; - but->editprofile = NULL; - + if (but->type == UI_BTYPE_COLORBAND) { + uiButColorBand *but_coba = (uiButColorBand *)but; + but_coba->edit_coba = NULL; + } + else if (but->type == UI_BTYPE_CURVE) { + uiButCurveMapping *but_cumap = (uiButCurveMapping *)but; + but_cumap->edit_cumap = NULL; + } + else if (but->type == UI_BTYPE_CURVEPROFILE) { + uiButCurveProfile *but_profile = (uiButCurveProfile *)but; + but_profile->edit_profile = NULL; + } data->dragstartx = 0; data->draglastx = 0; data->dragchange = false; @@ -4138,7 +4163,7 @@ static uiButExtraOpIcon *ui_but_extra_operator_icon_mouse_over_get(uiBut *but, } /* Inverse order, from right to left. */ - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) { + LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { if ((x > (xmax - icon_size)) && x < xmax) { return op_icon; } @@ -4267,7 +4292,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, if (event->type == LEFTMOUSE && event->val == KM_PRESS) { /* only cancel if click outside the button */ - if (ui_but_contains_point_px(but, but->active->region, event->x, event->y) == 0) { + if (ui_but_contains_point_px(but, but->active->region, event->x, event->y) == false) { /* data->cancel doesn't work, this button opens immediate */ if (but->flag & UI_BUT_IMMEDIATE) { ui_but_value_set(but, 0); @@ -4377,7 +4402,7 @@ static int ui_do_but_TAB( return WM_UI_HANDLER_BREAK; } if (ELEM(event->type, LEFTMOUSE, EVT_PADENTER, EVT_RETKEY)) { - int event_val = (is_property) ? KM_PRESS : KM_CLICK; + const int event_val = (is_property) ? KM_PRESS : KM_CLICK; if (event->val == event_val) { button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; @@ -4516,7 +4541,6 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - if (data->state == BUTTON_STATE_HIGHLIGHT) { /* first handle click on icondrag type button */ @@ -4586,7 +4610,7 @@ static float ui_numedit_apply_snapf( if (ui_but_is_unit(but)) { UnitSettings *unit = but->block->unit; - int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); + const int unit_type = RNA_SUBTYPE_UNIT_VALUE(UI_but_unit_type_get(but)); if (bUnit_IsValid(unit->system, unit_type)) { fac = (float)bUnit_BaseScalar(unit->system, unit_type); @@ -4609,7 +4633,7 @@ static float ui_numedit_apply_snapf( * but allow for rotations */ if (softrange >= 21.0f) { UnitSettings *unit = but->block->unit; - int unit_type = UI_but_unit_type_get(but); + const int unit_type = UI_but_unit_type_get(but); if ((unit_type == PROP_UNIT_ROTATION) && (unit->system_rotation != USER_UNIT_ROT_RADIANS)) { /* pass (degrees)*/ } @@ -4805,7 +4829,7 @@ static bool ui_numedit_but_NUM(uiBut *but, if (is_float == false) { /* at minimum, moving cursor 2 pixels should change an int button. */ - CLAMP_MIN(non_linear_scale, 0.5f * U.pixelsize); + CLAMP_MIN(non_linear_scale, 0.5f * UI_DPI_FAC); } data->dragf += (((float)(mx - data->draglastx)) / deler) * non_linear_scale; @@ -4853,7 +4877,7 @@ static bool ui_numedit_but_NUM(uiBut *but, static void ui_numedit_set_active(uiBut *but) { - int oldflag = but->drawflag; + const int oldflag = but->drawflag; but->drawflag &= ~(UI_BUT_ACTIVE_LEFT | UI_BUT_ACTIVE_RIGHT); uiHandleButtonData *data = but->active; @@ -4903,13 +4927,14 @@ static void ui_numedit_set_active(uiBut *but) static int ui_do_but_NUM( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; /* mouse location scaled to fit the UI */ - int screen_mx, screen_my; /* mouse location kept at screen pixel coords */ int click = 0; int retval = WM_UI_HANDLER_CONTINUE; - mx = screen_mx = event->x; - my = screen_my = event->y; + /* mouse location scaled to fit the UI */ + int mx = event->x; + int my = event->y; + /* mouse location kept at screen pixel coords */ + const int screen_mx = event->x; ui_window_to_block(data->region, block, &mx, &my); ui_numedit_set_active(but); @@ -5124,7 +5149,7 @@ static bool ui_numedit_but_SLI(uiBut *but, (but->softmax - but->softmin + but->a1); } else { - float offs = (BLI_rctf_size_y(&but->rect) / 2.0f); + const float offs = (BLI_rctf_size_y(&but->rect) / 2.0f); cursor_x_range = (BLI_rctf_size_x(&but->rect) - offs); } @@ -5215,11 +5240,11 @@ static bool ui_numedit_but_SLI(uiBut *but, static int ui_do_but_SLI( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my, click = 0; + int click = 0; int retval = WM_UI_HANDLER_CONTINUE; - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -5418,12 +5443,11 @@ static int ui_do_but_SLI( static int ui_do_but_SCROLL( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my /*, click = 0 */; int retval = WM_UI_HANDLER_CONTINUE; - bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect)); + const bool horizontal = (BLI_rctf_size_x(&but->rect) > BLI_rctf_size_y(&but->rect)); - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -5440,12 +5464,6 @@ static int ui_do_but_SCROLL( button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); retval = WM_UI_HANDLER_BREAK; } - /* UNUSED - otherwise code is ok, add back if needed */ -#if 0 - else if (ELEM(event->type, PADENTER, RETKEY) && event->val == KM_PRESS) { - click = 1; - } -#endif } } else if (data->state == BUTTON_STATE_NUM_EDITING) { @@ -5476,7 +5494,6 @@ static int ui_do_but_SCROLL( static int ui_do_but_GRIP( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; int retval = WM_UI_HANDLER_CONTINUE; const bool horizontal = (BLI_rctf_size_x(&but->rect) < BLI_rctf_size_y(&but->rect)); @@ -5486,8 +5503,8 @@ static int ui_do_but_GRIP( * See T37739. */ - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -5551,7 +5568,6 @@ static int ui_do_but_LISTROW(bContext *C, static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - if (data->state == BUTTON_STATE_HIGHLIGHT) { /* first handle click on icondrag type button */ @@ -5636,8 +5652,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co static bool ui_numedit_but_UNITVEC( uiBut *but, uiHandleButtonData *data, int mx, int my, const enum eSnapType snap) { - float dx, dy, rad, radsq, mrad, *fp; - int mdx, mdy; + float mrad; bool changed = true; /* button is presumed square */ @@ -5646,10 +5661,11 @@ static bool ui_numedit_but_UNITVEC( /* note that both data->vec and data->origvec should be normalized * else we'll get a harmless but annoying jump when first clicking */ - fp = data->origvec; - rad = BLI_rctf_size_x(&but->rect); - radsq = rad * rad; + float *fp = data->origvec; + const float rad = BLI_rctf_size_x(&but->rect); + const float radsq = rad * rad; + int mdx, mdy; if (fp[2] > 0.0f) { mdx = (rad * fp[0]); mdy = (rad * fp[1]); @@ -5664,8 +5680,8 @@ static bool ui_numedit_but_UNITVEC( mdx = mdy = 0; } - dx = (float)(mx + mdx - data->dragstartx); - dy = (float)(my + mdy - data->dragstarty); + float dx = (float)(mx + mdx - data->dragstartx); + float dy = (float)(my + mdy - data->dragstarty); fp = data->vec; mrad = dx * dx + dy * dy; @@ -5694,11 +5710,10 @@ static bool ui_numedit_but_UNITVEC( const int snap_steps = (snap == SNAP_ON) ? 4 : 12; /* 45 or 15 degree increments */ const float snap_steps_angle = M_PI / snap_steps; float angle, angle_snap; - int i; /* round each axis of 'fp' to the next increment * do this in "angle" space - this gives increments of same size */ - for (i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) { angle = asinf(fp[i]); angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle; fp[i] = sinf(angle_snap); @@ -5769,7 +5784,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co hsv[2] = clamp_f(hsv[2] + 0.05f, 0.0f, 1.0f); } else { - float fac = 0.005 * (event->y - event->prevy); + const float fac = 0.005 * (event->y - event->prevy); hsv[2] = clamp_f(hsv[2] + fac, 0.0f, 1.0f); } @@ -5873,10 +5888,8 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co static int ui_do_but_UNITVEC( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -5990,7 +6003,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, float rgb[3]; float x, y; float mx_fl, my_fl; - bool changed = true; + const bool changed = true; ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); @@ -6063,7 +6076,7 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, break; case UI_GRAD_V_ALT: { /* vertical 'value' strip */ - float min = but->softmin, max = but->softmax; + const float min = but->softmin, max = but->softmax; /* exception only for value strip - use the range set in but->min/max */ hsv[2] = y * (max - min) + min; break; @@ -6106,7 +6119,7 @@ static void ui_ndofedit_but_HSVCUBE(uiButHSVCube *hsv_but, float *hsv = cpicker->color_data; const float hsv_v_max = max_ff(hsv[2], hsv_but->but.softmax); float rgb[3]; - float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; + const float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; ui_but_v3_get(&hsv_but->but, rgb); ui_scene_linear_to_color_picker_space(&hsv_but->but, rgb); @@ -6169,10 +6182,8 @@ static int ui_do_but_HSVCUBE( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { uiButHSVCube *hsv_but = (uiButHSVCube *)but; - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -6271,13 +6282,11 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, const enum eSnapType snap, const bool shift) { - rcti rect; - bool changed = true; - float mx_fl, my_fl; - float rgb[3]; + const bool changed = true; ColorPicker *cpicker = but->custom_data; float *hsv = cpicker->color_data; + float mx_fl, my_fl; ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); #ifdef USE_CONT_MOUSE_CORRECT @@ -6296,8 +6305,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, } #endif + rcti rect; BLI_rcti_rctf_copy(&rect, &but->rect); + float rgb[3]; ui_but_v3_get(but, rgb); ui_scene_linear_to_color_picker_space(but, rgb); ui_rgb_to_color_picker_compat_v(rgb, hsv); @@ -6375,7 +6386,7 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, float *hsv = cpicker->color_data; float rgb[3]; float phi, r /*, sqr */ /* UNUSED */, v[2]; - float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt; + const float sensitivity = (shift ? 0.06f : 0.3f) * ndof->dt; ui_but_v3_get(but, rgb); ui_scene_linear_to_color_picker_space(but, rgb); @@ -6447,9 +6458,8 @@ static int ui_do_but_HSVCIRCLE( { ColorPicker *cpicker = but->custom_data; float *hsv = cpicker->color_data; - int mx, my; - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -6551,7 +6561,6 @@ static int ui_do_but_HSVCIRCLE( static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx) { - float dx; bool changed = false; if (data->draglastx == mx) { @@ -6562,7 +6571,7 @@ static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int m return changed; } - dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect); + const float dx = ((float)(mx - data->draglastx)) / BLI_rctf_size_x(&but->rect); data->dragcbd->pos += dx; CLAMP(data->dragcbd->pos, 0.0f, 1.0f); @@ -6578,33 +6587,32 @@ static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int m static int ui_do_but_COLORBAND( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - ColorBand *coba; - CBData *cbd; - /* ignore zoom-level for mindist */ - int mindist = (50 * UI_DPI_FAC) * block->aspect; - int mx, my, a, xco; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE && event->val == KM_PRESS) { - coba = (ColorBand *)but->poin; + ColorBand *coba = (ColorBand *)but->poin; if (event->ctrl) { /* insert new key on mouse location */ - float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect); + const float pos = ((float)(mx - but->rect.xmin)) / BLI_rctf_size_x(&but->rect); BKE_colorband_element_add(coba, pos); button_activate_state(C, but, BUTTON_STATE_EXIT); } else { + CBData *cbd; + /* ignore zoom-level for mindist */ + int mindist = (50 * UI_DPI_FAC) * block->aspect; + int xco; data->dragstartx = mx; data->dragstarty = my; data->draglastx = mx; data->draglasty = my; /* activate new key when mouse is close */ + int a; for (a = 0, cbd = coba->data; a < coba->tot; a++, cbd++) { xco = but->rect.xmin + (cbd->pos * BLI_rctf_size_x(&but->rect)); xco = abs(xco - mx); @@ -6663,22 +6671,19 @@ static bool ui_numedit_but_CURVE(uiBlock *block, CurveMapping *cumap = (CurveMapping *)but->poin; CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; - float fx, fy, zoomx, zoomy; - int mx, my, dragx, dragy; - int a; bool changed = false; /* evtx evty and drag coords are absolute mousecoords, * prevents errors when editing when layout changes */ - mx = evtx; - my = evty; + int mx = evtx; + int my = evty; ui_window_to_block(data->region, block, &mx, &my); - dragx = data->draglastx; - dragy = data->draglasty; + int dragx = data->draglastx; + int dragy = data->draglasty; ui_window_to_block(data->region, block, &dragx, &dragy); - zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr); - zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr); + const float zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&cumap->curr); + const float zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&cumap->curr); if (snap) { float d[2]; @@ -6691,20 +6696,20 @@ static bool ui_numedit_but_CURVE(uiBlock *block, } } + float fx = (mx - dragx) / zoomx; + float fy = (my - dragy) / zoomy; + if (data->dragsel != -1) { CurveMapPoint *cmp_last = NULL; const float mval_factor = ui_mouse_scale_warp_factor(shift); bool moved_point = false; /* for ctrl grid, can't use orig coords because of sorting */ - fx = (mx - dragx) / zoomx; - fy = (my - dragy) / zoomy; - fx *= mval_factor; fy *= mval_factor; - for (a = 0; a < cuma->totpoint; a++) { + for (int a = 0; a < cuma->totpoint; a++) { if (cmp[a].flag & CUMA_SELECT) { - float origx = cmp[a].x, origy = cmp[a].y; + const float origx = cmp[a].x, origy = cmp[a].y; cmp[a].x += fx; cmp[a].y += fy; if (snap) { @@ -6741,9 +6746,6 @@ static bool ui_numedit_but_CURVE(uiBlock *block, data->dragchange = true; /* mark for selection */ } else { - fx = (mx - dragx) / zoomx; - fy = (my - dragy) / zoomy; - /* clamp for clip */ if (cumap->flag & CUMA_DO_CLIP) { if (cumap->curr.xmin - fx < cumap->clipr.xmin) { @@ -6777,20 +6779,18 @@ static bool ui_numedit_but_CURVE(uiBlock *block, static int ui_do_but_CURVE( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my, a; bool changed = false; Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { if (event->type == LEFTMOUSE && event->val == KM_PRESS) { CurveMapping *cumap = (CurveMapping *)but->poin; CurveMap *cuma = cumap->cm + cumap->cur; - CurveMapPoint *cmp; const float m_xy[2] = {mx, my}; float dist_min_sq = square_f(U.dpi_fac * 14.0f); /* 14 pixels radius */ int sel = -1; @@ -6805,8 +6805,8 @@ static int ui_do_but_CURVE( } /* check for selecting of a point */ - cmp = cuma->curve; /* ctrl adds point, new malloc */ - for (a = 0; a < cuma->totpoint; a++) { + CurveMapPoint *cmp = cuma->curve; /* ctrl adds point, new malloc */ + for (int a = 0; a < cuma->totpoint; a++) { float f_xy[2]; BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[a].x); const float dist_sq = len_squared_v2v2(m_xy, f_xy); @@ -6817,7 +6817,6 @@ static int ui_do_but_CURVE( } if (sel == -1) { - int i; float f_xy[2], f_xy_prev[2]; /* if the click didn't select anything, check if it's clicked on the @@ -6830,7 +6829,7 @@ static int ui_do_but_CURVE( dist_min_sq = square_f(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++) { + for (int i = 1; i <= CM_TABLE; i++) { copy_v2_v2(f_xy_prev, f_xy); BLI_rctf_transform_pt_v(&but->rect, &cumap->curr, f_xy, &cmp[i].x); @@ -6847,7 +6846,7 @@ static int ui_do_but_CURVE( cmp = cuma->curve; /* find newly added point and make it 'sel' */ - for (a = 0; a < cuma->totpoint; a++) { + for (int a = 0; a < cuma->totpoint; a++) { if (cmp[a].x == f_xy[0]) { sel = a; } @@ -6861,7 +6860,7 @@ static int ui_do_but_CURVE( /* ok, we move a point */ /* deselect all if this one is deselect. except if we hold shift */ if (!event->shift) { - for (a = 0; a < cuma->totpoint; a++) { + for (int a = 0; a < cuma->totpoint; a++) { cmp[a].flag &= ~CUMA_SELECT; } cmp[sel].flag |= CUMA_SELECT; @@ -6905,7 +6904,7 @@ static int ui_do_but_CURVE( if (data->dragchange == false) { /* deselect all, select one */ if (!event->shift) { - for (a = 0; a < cuma->totpoint; a++) { + for (int a = 0; a < cuma->totpoint; a++) { cmp[a].flag &= ~CUMA_SELECT; } cmp[data->dragsel].flag |= CUMA_SELECT; @@ -6940,22 +6939,19 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block, { CurveProfile *profile = (CurveProfile *)but->poin; CurveProfilePoint *pts = profile->path; - float fx, fy, zoomx, zoomy; - int mx, my, dragx, dragy; - int a; bool changed = false; /* evtx evty and drag coords are absolute mousecoords, * prevents errors when editing when layout changes */ - mx = evtx; - my = evty; + int mx = evtx; + int my = evty; ui_window_to_block(data->region, block, &mx, &my); - dragx = data->draglastx; - dragy = data->draglasty; + int dragx = data->draglastx; + int dragy = data->draglasty; ui_window_to_block(data->region, block, &dragx, &dragy); - zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&profile->view_rect); - zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&profile->view_rect); + const float zoomx = BLI_rctf_size_x(&but->rect) / BLI_rctf_size_x(&profile->view_rect); + const float zoomy = BLI_rctf_size_y(&but->rect) / BLI_rctf_size_y(&profile->view_rect); if (snap) { float d[2]; @@ -6968,8 +6964,8 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block, } } - fx = (mx - dragx) / zoomx; - fy = (my - dragy) / zoomy; + float fx = (mx - dragx) / zoomx; + float fy = (my - dragy) / zoomy; if (data->dragsel != -1) { float last_x, last_y; @@ -6981,7 +6977,7 @@ static bool ui_numedit_but_CURVEPROFILE(uiBlock *block, /* Move all selected points. */ const float delta[2] = {fx, fy}; - for (a = 0; a < profile->path_len; a++) { + for (int a = 0; a < profile->path_len; a++) { /* Don't move the last and first control points. */ if ((pts[a].flag & PROF_SELECT) && (a != 0) && (a != profile->path_len)) { moved_point |= BKE_curveprofile_move_point(profile, &pts[a], snap, delta); @@ -7235,8 +7231,8 @@ static int ui_do_but_CURVEPROFILE( static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my) { Histogram *hist = (Histogram *)but->poin; - bool changed = true; - float dy = my - data->draglasty; + const bool changed = true; + const float dy = my - data->draglasty; /* scale histogram values (dy / 10 for better control) */ const float yfac = min_ff(pow2f(hist->ymax), 1.0f) * 0.5f; @@ -7254,10 +7250,8 @@ static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int m static int ui_do_but_HISTOGRAM( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -7311,10 +7305,9 @@ static int ui_do_but_HISTOGRAM( static bool ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my) { Scopes *scopes = (Scopes *)but->poin; - bool changed = true; - float dy; + const bool changed = true; - dy = my - data->draglasty; + const float dy = my - data->draglasty; /* scale waveform values */ scopes->wavefrm_yfac += dy / 200.0f; @@ -7330,10 +7323,8 @@ static bool ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx static int ui_do_but_WAVEFORM( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -7388,11 +7379,10 @@ static bool ui_numedit_but_TRACKPREVIEW( bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, const bool shift) { MovieClipScopes *scopes = (MovieClipScopes *)but->poin; - bool changed = true; - float dx, dy; + const bool changed = true; - dx = mx - data->draglastx; - dy = my - data->draglasty; + float dx = mx - data->draglastx; + float dy = my - data->draglasty; if (shift) { dx /= 5.0f; @@ -7401,7 +7391,7 @@ static bool ui_numedit_but_TRACKPREVIEW( if (!scopes->track_locked) { const MovieClip *clip = CTX_data_edit_movieclip(C); - int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scopes->framenr); + const int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scopes->framenr); if (scopes->marker->framenr != clip_framenr) { scopes->marker = BKE_tracking_marker_ensure(scopes->track, clip_framenr); } @@ -7424,10 +7414,8 @@ static bool ui_numedit_but_TRACKPREVIEW( static int ui_do_but_TRACKPREVIEW( bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_HIGHLIGHT) { @@ -7472,13 +7460,10 @@ static int ui_do_but_TRACKPREVIEW( static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event) { - uiHandleButtonData *data; - int retval; - - data = but->active; - retval = WM_UI_HANDLER_CONTINUE; + uiHandleButtonData *data = but->active; + int retval = WM_UI_HANDLER_CONTINUE; - bool is_disabled = but->flag & UI_BUT_DISABLED; + const bool is_disabled = but->flag & UI_BUT_DISABLED; /* if but->pointype is set, but->poin should be too */ BLI_assert(!but->pointype || but->poin); @@ -7491,8 +7476,8 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* handle copy and paste */ bool is_press_ctrl_but_no_shift = event->val == KM_PRESS && IS_EVENT_MOD(event, ctrl, oskey) && !event->shift; - bool do_copy = event->type == EVT_CKEY && is_press_ctrl_but_no_shift; - bool do_paste = event->type == EVT_VKEY && is_press_ctrl_but_no_shift; + const bool do_copy = event->type == EVT_CKEY && is_press_ctrl_but_no_shift; + const bool do_paste = event->type == EVT_VKEY && is_press_ctrl_but_no_shift; /* Specific handling for listrows, we try to find their overlapping tex button. */ if ((do_copy || do_paste) && but->type == UI_BTYPE_LISTROW) { @@ -7737,15 +7722,13 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * static void ui_blocks_set_tooltips(ARegion *region, const bool enable) { - uiBlock *block; - if (!region) { return; } /* we disabled buttons when when they were already shown, and * re-enable them on mouse move */ - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { block->tooltipdisabled = !enable; } } @@ -7770,9 +7753,7 @@ void UI_but_tooltip_refresh(bContext *C, uiBut *but) */ void UI_but_tooltip_timer_remove(bContext *C, uiBut *but) { - uiHandleButtonData *data; - - data = but->active; + uiHandleButtonData *data = but->active; if (data) { if (data->autoopentimer) { WM_event_remove_timer(data->wm, data->window, data->autoopentimer); @@ -7813,8 +7794,8 @@ static void button_tooltip_timer_reset(bContext *C, uiBut *but) if ((U.flag & USER_TOOLTIPS) || (data->tooltip_force)) { if (!but->block->tooltipdisabled) { if (!wm->drags.first) { - bool is_label = UI_but_has_tooltip_label(but); - double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY; + const bool is_label = UI_but_has_tooltip_label(but); + const double delay = is_label ? UI_TOOLTIP_DELAY_LABEL : UI_TOOLTIP_DELAY; WM_tooltip_timer_init_ex( C, data->window, data->area, data->region, ui_but_tooltip_init, delay); if (is_label) { @@ -7847,9 +7828,7 @@ static bool button_modal_state(uiHandleButtonState state) static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state) { - uiHandleButtonData *data; - - data = but->active; + uiHandleButtonData *data = but->active; if (data->state == state) { return; } @@ -8019,13 +7998,11 @@ static void button_activate_init(bContext *C, uiBut *but, uiButtonActivateType type) { - uiHandleButtonData *data; - /* Only ever one active button! */ BLI_assert(ui_region_find_active_but(region) == NULL); /* setup struct */ - data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData"); + uiHandleButtonData *data = MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData"); data->wm = CTX_wm_manager(C); data->window = CTX_wm_window(C); data->area = CTX_wm_area(C); @@ -8124,7 +8101,6 @@ static void button_activate_exit( { wmWindow *win = data->window; uiBlock *block = but->block; - uiBut *bt; if (but->type == UI_BTYPE_GRIP) { WM_cursor_modal_restore(win); @@ -8142,7 +8118,7 @@ static void button_activate_exit( #ifdef USE_DRAG_MULTINUM if (data->multi_data.has_mbuts) { - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->flag & UI_BUT_DRAG_MULTI) { bt->flag &= ~UI_BUT_DRAG_MULTI; @@ -8198,12 +8174,12 @@ static void button_activate_exit( } /* disable tooltips until mousemove + last active flag */ - for (block = data->region->uiblocks.first; block; block = block->next) { - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBlock *, block_iter, &data->region->uiblocks) { + LISTBASE_FOREACH (uiBut *, bt, &block_iter->buttons) { bt->flag &= ~UI_BUT_LAST_ACTIVE; } - block->tooltipdisabled = 1; + block_iter->tooltipdisabled = 1; } ui_blocks_set_tooltips(data->region, false); @@ -8250,13 +8226,11 @@ static void button_activate_exit( void ui_but_active_free(const bContext *C, uiBut *but) { - uiHandleButtonData *data; - /* this gets called when the button somehow disappears while it is still * active, this is bad for user interaction, but we need to handle this * case cleanly anyway in case it happens */ if (but->active) { - data = but->active; + uiHandleButtonData *data = but->active; data->cancel = true; button_activate_exit((bContext *)C, but, data, false, true); } @@ -8268,12 +8242,11 @@ static uiBut *ui_context_button_active(ARegion *region, bool (*but_check_cb)(uiB uiBut *but_found = NULL; while (region) { - uiBlock *block; - uiBut *but, *activebut = NULL; + uiBut *activebut = NULL; /* find active button */ - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->active) { activebut = but; } @@ -8396,7 +8369,6 @@ void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region) wmOperator *UI_context_active_operator_get(const struct bContext *C) { ARegion *region_ctx = CTX_wm_region(C); - uiBlock *block; /* background mode */ if (region_ctx == NULL) { @@ -8404,7 +8376,7 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C) } /* scan active regions ui */ - for (block = region_ctx->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion_ctx->uiblocks) { if (block->ui_operator) { return block->ui_operator; } @@ -8413,13 +8385,12 @@ wmOperator *UI_context_active_operator_get(const struct bContext *C) /* scan popups */ { bScreen *screen = CTX_wm_screen(C); - ARegion *region; - for (region = screen->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) { if (region == region_ctx) { continue; } - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { if (block->ui_operator) { return block->ui_operator; } @@ -8438,15 +8409,13 @@ void UI_context_update_anim_flag(const bContext *C) struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( depsgraph, (scene) ? scene->r.cfra : 0.0f); - uiBlock *block; - uiBut *but, *activebut; while (region) { /* find active button */ - activebut = NULL; + uiBut *activebut = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { ui_but_anim_flag(but, &anim_eval_context); ui_but_override_flag(CTX_data_main(C), but); if (UI_but_is_decorator(but)) { @@ -8489,11 +8458,8 @@ void UI_context_update_anim_flag(const bContext *C) static uiBut *ui_but_find_open_event(ARegion *region, const wmEvent *event) { - uiBlock *block; - uiBut *but; - - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but == event->customdata) { return but; } @@ -8504,10 +8470,8 @@ static uiBut *ui_but_find_open_event(ARegion *region, const wmEvent *event) static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *region) { - uiBut *but; - if (event->type == MOUSEMOVE) { - but = ui_but_find_mouse_over(region, event); + uiBut *but = ui_but_find_mouse_over(region, event); if (but) { button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER); @@ -8518,7 +8482,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg } } else if (event->type == EVT_BUT_OPEN) { - but = ui_but_find_open_event(region, event); + uiBut *but = ui_but_find_open_event(region, event); if (but) { button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER); ui_do_button(C, but->block, but, event); @@ -8536,10 +8500,10 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *reg void ui_but_activate_event(bContext *C, ARegion *region, uiBut *but) { wmWindow *win = CTX_wm_window(C); - wmEvent event; button_activate_init(C, region, but, BUTTON_ACTIVATE_OVER); + wmEvent event; wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; @@ -8597,12 +8561,9 @@ static void ui_handle_button_activate(bContext *C, uiBut *but, uiButtonActivateType type) { - uiBut *oldbut; - uiHandleButtonData *data; - - oldbut = ui_region_find_active_but(region); + uiBut *oldbut = ui_region_find_active_but(region); if (oldbut) { - data = oldbut->active; + uiHandleButtonData *data = oldbut->active; data->cancel = true; button_activate_exit(C, oldbut, data, false, false); } @@ -8645,7 +8606,7 @@ static bool ui_handle_button_activate_by_type(bContext *C, ARegion *region, uiBu static bool ui_button_value_default(uiBut *but, double *r_value) { if (but->rnaprop != NULL && ui_but_is_rna_valid(but)) { - int type = RNA_property_type(but->rnaprop); + const int type = RNA_property_type(but->rnaprop); if (ELEM(type, PROP_FLOAT, PROP_INT)) { double default_value; switch (type) { @@ -8679,14 +8640,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) { uiHandleButtonData *data = but->active; const uiHandleButtonState state_orig = data->state; - uiBlock *block; - ARegion *region; - int retval; - block = but->block; - region = data->region; + uiBlock *block = but->block; + ARegion *region = data->region; - retval = WM_UI_HANDLER_CONTINUE; + int retval = WM_UI_HANDLER_CONTINUE; if (data->state == BUTTON_STATE_HIGHLIGHT) { switch (event->type) { @@ -8898,7 +8856,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) data = but->active; if (data && data->state == BUTTON_STATE_EXIT) { uiBut *post_but = data->postbut; - uiButtonActivateType post_type = data->posttype; + const uiButtonActivateType post_type = data->posttype; /* Reset the button value when empty text is typed. */ if ((data->cancel == false) && (data->str != NULL) && (data->str[0] == '\0') && @@ -8953,21 +8911,18 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *region, uiBut *listbox) { - uiList *ui_list; - uiListDyn *dyn_data; int retval = WM_UI_HANDLER_CONTINUE; int type = event->type, val = event->val; bool redraw = false; - int mx, my; - ui_list = listbox->custom_data; + uiList *ui_list = listbox->custom_data; if (!ui_list || !ui_list->dyn_data) { return retval; } - dyn_data = ui_list->dyn_data; + uiListDyn *dyn_data = ui_list->dyn_data; - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(region, listbox->block, &mx, &my); /* Convert pan to scroll-wheel. */ @@ -9003,11 +8958,11 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi * collection order, we have some work! */ int *org_order = MEM_mallocN(dyn_data->items_shown * sizeof(int), __func__); const int *new_order = dyn_data->items_filter_neworder; - int i, org_idx = -1, len = dyn_data->items_len; + int org_idx = -1, len = dyn_data->items_len; int current_idx = -1; - int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE; + const int filter_exclude = ui_list->filter_flag & UILST_FLT_EXCLUDE; - for (i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { if (!dyn_data->items_filter_flags || ((dyn_data->items_filter_flags[i] & UILST_FLT_ITEM) ^ filter_exclude)) { org_order[new_order ? new_order[++org_idx] : ++org_idx] = i; @@ -9086,11 +9041,8 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *regi static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, uiBut *but) { - uiHandleButtonData *data; - uiPopupBlockHandle *menu; - - data = but->active; - menu = data->menu; + uiHandleButtonData *data = but->active; + uiPopupBlockHandle *menu = data->menu; /* copy over return values from the closing menu */ if ((menu->menuretval & UI_RETURN_OK) || (menu->menuretval & UI_RETURN_UPDATE)) { @@ -9192,13 +9144,6 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, const int xy[2], const bool use_wiggle_room) { - float p1[2], p2[2], p3[2], p4[2]; - float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]}; - const float newp[2] = {xy[0], xy[1]}; - bool closer; - const float margin = MENU_TOWARDS_MARGIN; - rctf rect_px; - BLI_assert(block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER)); /* annoying fix for [#36269], this is a bit odd but in fact works quite well @@ -9220,6 +9165,8 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, return false; } + float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]}; + const float newp[2] = {xy[0], xy[1]}; if (len_squared_v2v2(oldp, newp) < (4.0f * 4.0f)) { return menu->dotowards; } @@ -9227,19 +9174,15 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, /* verify that we are moving towards one of the edges of the * menu block, in other words, in the triangle formed by the * initial mouse location and two edge points. */ + rctf rect_px; ui_block_to_window_rctf(menu->region, block, &rect_px, &block->rect); - p1[0] = rect_px.xmin - margin; - p1[1] = rect_px.ymin - margin; - - p2[0] = rect_px.xmax + margin; - p2[1] = rect_px.ymin - margin; - - p3[0] = rect_px.xmax + margin; - p3[1] = rect_px.ymax + margin; + const float margin = MENU_TOWARDS_MARGIN; - p4[0] = rect_px.xmin - margin; - p4[1] = rect_px.ymax + margin; + const float p1[2] = {rect_px.xmin - margin, rect_px.ymin - margin}; + const float p2[2] = {rect_px.xmax + margin, rect_px.ymin - margin}; + const float p3[2] = {rect_px.xmax + margin, rect_px.ymax + margin}; + const float p4[2] = {rect_px.xmin - margin, rect_px.ymax + margin}; /* allow for some wiggle room, if the user moves a few pixels away, * don't immediately quit (only for top level menus) */ @@ -9252,8 +9195,9 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, add_v2_v2(oldp, delta); } - closer = (isect_point_tri_v2(newp, oldp, p1, p2) || isect_point_tri_v2(newp, oldp, p2, p3) || - isect_point_tri_v2(newp, oldp, p3, p4) || isect_point_tri_v2(newp, oldp, p4, p1)); + bool closer = (isect_point_tri_v2(newp, oldp, p1, p2) || + isect_point_tri_v2(newp, oldp, p2, p3) || + isect_point_tri_v2(newp, oldp, p3, p4) || isect_point_tri_v2(newp, oldp, p4, p1)); if (!closer) { menu->dotowards = false; @@ -9455,7 +9399,6 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock { ARegion *region = menu->region; uiBut *but = ui_region_find_active_but(region); - int retval; if (but) { /* Its possible there is an active menu item NOT under the mouse, @@ -9483,6 +9426,7 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock } } + int retval; if (but) { ScrArea *ctx_area = CTX_wm_area(C); ARegion *ctx_region = CTX_wm_region(C); @@ -9513,8 +9457,6 @@ static int ui_handle_menu_button(bContext *C, const wmEvent *event, uiPopupBlock float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2]) { float seg1[2]; - float seg2[2]; - float len; if (block->pie_data.flags & UI_PIE_INITIAL_DIRECTION) { copy_v2_v2(seg1, block->pie_data.pie_center_init); @@ -9523,9 +9465,10 @@ float ui_block_calc_pie_segment(uiBlock *block, const float event_xy[2]) copy_v2_v2(seg1, block->pie_data.pie_center_spawned); } + float seg2[2]; sub_v2_v2v2(seg2, event_xy, seg1); - len = normalize_v2_v2(block->pie_data.pie_dir, seg2); + const float len = normalize_v2_v2(block->pie_data.pie_dir, seg2); if (len < U.pie_menu_threshold * U.dpi_fac) { block->pie_data.flags |= UI_PIE_INVALID_DIR; @@ -9545,25 +9488,20 @@ static int ui_handle_menu_event(bContext *C, const bool is_parent_menu, const bool is_floating) { - ARegion *region; - uiBlock *block; uiBut *but; - int mx, my, retval; - bool inside; - bool inside_title; /* check for title dragging */ - - region = menu->region; - block = region->uiblocks.first; + ARegion *region = menu->region; + uiBlock *block = region->uiblocks.first; - retval = WM_UI_HANDLER_CONTINUE; + int retval = WM_UI_HANDLER_CONTINUE; - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(region, block, &mx, &my); /* check if mouse is inside block */ - inside = BLI_rctf_isect_pt(&block->rect, mx, my); - inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax); + const bool inside = BLI_rctf_isect_pt(&block->rect, mx, my); + /* check for title dragging */ + const bool inside_title = inside && ((my + (UI_UNIT_Y * 1.5f)) > block->rect.ymax); /* if there's an active modal button, don't check events or outside, except for search menu */ but = ui_region_find_active_but(region); @@ -9742,7 +9680,7 @@ static int ui_handle_menu_event(bContext *C, if (val == KM_PRESS) { /* Determine scroll operation. */ uiMenuScrollType scrolltype; - bool ui_block_flipped = (block->flag & UI_BLOCK_IS_FLIP) != 0; + const bool ui_block_flipped = (block->flag & UI_BLOCK_IS_FLIP) != 0; if (ELEM(type, EVT_PAGEUPKEY, EVT_HOMEKEY)) { scrolltype = ui_block_flipped ? MENU_SCROLL_TOP : MENU_SCROLL_BOTTOM; @@ -9987,7 +9925,7 @@ static int ui_handle_menu_event(bContext *C, * Events handled above may have already set the return value, * don't overwrite them, see: T61015. */ - if ((inside == 0) && (menu->menuretval == 0)) { + if ((inside == false) && (menu->menuretval == 0)) { uiSafetyRct *saferct = block->saferct.first; if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) { @@ -10074,7 +10012,7 @@ static int ui_handle_menu_event(bContext *C, else { /* check mouse moving outside of the menu */ - if (inside == 0 && (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER))) { + if (inside == false && (block->flag & (UI_BLOCK_MOVEMOUSE_QUIT | UI_BLOCK_POPOVER))) { uiSafetyRct *saferct; ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false); @@ -10153,21 +10091,15 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu) { - ARegion *region; - uiBut *but; - uiBlock *block; - uiHandleButtonData *data; - uiPopupBlockHandle *submenu; - - region = menu->region; - block = region->uiblocks.first; + ARegion *region = menu->region; + uiBlock *block = region->uiblocks.first; - but = ui_region_find_active_but(region); + uiBut *but = ui_region_find_active_but(region); BLI_assert(but); - data = but->active; - submenu = data->menu; + uiHandleButtonData *data = but->active; + uiPopupBlockHandle *submenu = data->menu; if (submenu->menuretval) { bool update; @@ -10214,7 +10146,7 @@ static int ui_but_pie_menu_apply(bContext *C, uiBut *but, bool force_close) { - int retval = WM_UI_HANDLER_BREAK; + const int retval = WM_UI_HANDLER_BREAK; if (but && ui_but_pie_menu_supported_apply(but)) { if (but->type == UI_BTYPE_MENU) { @@ -10249,10 +10181,8 @@ static int ui_but_pie_menu_apply(bContext *C, static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, RadialDirection dir) { - uiBut *but; - if ((block->flag & UI_BLOCK_NUMSELECT) && event->val == KM_PRESS) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir == dir && !ELEM(but->type, UI_BTYPE_SEPR, UI_BTYPE_SEPR_LINE)) { return but; } @@ -10264,13 +10194,11 @@ static uiBut *ui_block_pie_dir_activate(uiBlock *block, const wmEvent *event, Ra static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandle *menu) { - uiBut *active_but; - if (but == NULL) { return WM_UI_HANDLER_BREAK; } - active_but = ui_region_find_active_but(menu->region); + uiBut *active_but = ui_region_find_active_but(menu->region); if (active_but) { button_activate_exit(C, active_but, active_but->active, false, false); @@ -10282,14 +10210,6 @@ static int ui_but_pie_button_activate(bContext *C, uiBut *but, uiPopupBlockHandl static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu) { - ARegion *region; - uiBlock *block; - uiBut *but; - float event_xy[2]; - double duration; - bool is_click_style; - float dist; - /* we block all events, this is modal interaction, * except for drop events which is described below */ int retval = WM_UI_HANDLER_BREAK; @@ -10300,13 +10220,13 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle retval = WM_UI_HANDLER_CONTINUE; } - region = menu->region; - block = region->uiblocks.first; + ARegion *region = menu->region; + uiBlock *block = region->uiblocks.first; - is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE); + const bool is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE); /* if there's an active modal button, don't check events or outside, except for search menu */ - but = ui_region_find_active_but(region); + uiBut *but_active = ui_region_find_active_but(region); if (menu->scrolltimer == NULL) { menu->scrolltimer = WM_event_add_timer( @@ -10314,17 +10234,16 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle menu->scrolltimer->duration = 0.0; } - duration = menu->scrolltimer->duration; + const double duration = menu->scrolltimer->duration; - event_xy[0] = event->x; - event_xy[1] = event->y; + float event_xy[2] = {event->x, event->y}; ui_window_to_block_fl(region, block, &event_xy[0], &event_xy[1]); /* Distance from initial point. */ - dist = ui_block_calc_pie_segment(block, event_xy); + const float dist = ui_block_calc_pie_segment(block, event_xy); - if (but && button_modal_state(but->active->state)) { + if (but_active && button_modal_state(but_active->active->state)) { retval = ui_handle_menu_button(C, event, menu); } else { @@ -10337,16 +10256,16 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle /* handle animation */ if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) { - double final_time = 0.01 * U.pie_animation_timeout; + const double final_time = 0.01 * U.pie_animation_timeout; float fac = duration / final_time; - float pie_radius = U.pie_menu_radius * UI_DPI_FAC; + const float pie_radius = U.pie_menu_radius * UI_DPI_FAC; if (fac > 1.0f) { fac = 1.0f; block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED; } - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->pie_dir != UI_RADIAL_NONE) { float vec[2]; float center[2]; @@ -10385,7 +10304,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle } if (len_sq < 1.0f) { - but = ui_region_find_active_but(menu->region); + uiBut *but = ui_region_find_active_but(menu->region); if (but) { return ui_but_pie_menu_apply(C, menu, but, true); @@ -10411,7 +10330,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle block->pie_data.flags |= UI_PIE_CLICK_STYLE; } else { - but = ui_region_find_active_but(menu->region); + uiBut *but = ui_region_find_active_but(menu->region); if (but && (U.pie_menu_confirm > 0) && (dist >= U.dpi_fac * (U.pie_menu_threshold + U.pie_menu_confirm))) { @@ -10429,7 +10348,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle switch (event->type) { case MOUSEMOVE: if (!is_click_style) { - float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init); + const float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init); /* here we use the initial position explicitly */ if (len_sq > PIE_CLICK_THRESHOLD_SQ) { @@ -10496,7 +10415,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle case EVT_ZKEY: { if ((event->val == KM_PRESS || event->val == KM_DBL_CLICK) && !IS_EVENT_MOD(event, shift, ctrl, oskey)) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->menu_key == event->type) { ui_but_pie_button_activate(C, but, menu); } @@ -10529,7 +10448,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle ATTR_FALLTHROUGH; CASE_NUM_TO_DIR(9, UI_RADIAL_NE); { - but = ui_block_pie_dir_activate(block, event, num_dir); + uiBut *but = ui_block_pie_dir_activate(block, event, num_dir); retval = ui_but_pie_button_activate(C, but, menu); break; } @@ -10552,16 +10471,13 @@ static int ui_handle_menus_recursive(bContext *C, const bool is_parent_menu, const bool is_floating) { - uiBut *but; - uiHandleButtonData *data; - uiPopupBlockHandle *submenu; int retval = WM_UI_HANDLER_CONTINUE; bool do_towards_reinit = false; /* check if we have a submenu, and handle events for it first */ - but = ui_region_find_active_but(menu->region); - data = (but) ? but->active : NULL; - submenu = (data) ? data->menu : NULL; + uiBut *but = ui_region_find_active_but(menu->region); + uiHandleButtonData *data = (but) ? but->active : NULL; + uiPopupBlockHandle *submenu = (data) ? data->menu : NULL; if (submenu) { uiBlock *block = menu->region->uiblocks.first; @@ -10569,14 +10485,13 @@ static int ui_handle_menus_recursive(bContext *C, bool inside = false; /* root pie menus accept the key that spawned * them as double click to improve responsiveness */ - bool do_recursion = (!(block->flag & UI_BLOCK_RADIAL) || event->type != block->pie_data.event); + const bool do_recursion = (!(block->flag & UI_BLOCK_RADIAL) || + event->type != block->pie_data.event); if (do_recursion) { if (is_parent_inside == false) { - int mx, my; - - mx = event->x; - my = event->y; + int mx = event->x; + int my = event->y; ui_window_to_block(menu->region, block, &mx, &my); inside = BLI_rctf_isect_pt(&block->rect, mx, my); } @@ -10596,7 +10511,7 @@ static int ui_handle_menus_recursive(bContext *C, (void)submenu; /* we may want to quit the submenu and handle the even in this menu, * if its important to use it, check 'data->menu' first */ - if (((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) == 0) { + if (((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) == false) { /* skip applying the event */ return retval; } @@ -10626,7 +10541,7 @@ static int ui_handle_menus_recursive(bContext *C, bool handled = false; if (listbox) { - int retval_test = ui_handle_list_event(C, event, menu->region, listbox); + const int retval_test = ui_handle_list_event(C, event, menu->region, listbox); if (retval_test != WM_UI_HANDLER_CONTINUE) { retval = retval_test; handled = true; @@ -10668,21 +10583,17 @@ void UI_popup_menu_retval_set(const uiBlock *block, const int retval, const bool static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata)) { - ARegion *region; - uiBut *but, *listbox; - int retval; - /* here we handle buttons at the region level, non-modal */ - region = CTX_wm_region(C); - retval = WM_UI_HANDLER_CONTINUE; + ARegion *region = CTX_wm_region(C); + int retval = WM_UI_HANDLER_CONTINUE; if (region == NULL || BLI_listbase_is_empty(®ion->uiblocks)) { return retval; } /* either handle events for already activated button or try to activate */ - but = ui_region_find_active_but(region); - listbox = ui_list_find_mouse_over(region, event); + uiBut *but = ui_region_find_active_but(region); + uiBut *listbox = ui_list_find_mouse_over(region, event); retval = ui_handler_panel_region(C, event, region, listbox ? listbox : but); @@ -10719,17 +10630,14 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(use static void ui_region_handler_remove(bContext *C, void *UNUSED(userdata)) { - bScreen *screen; - ARegion *region; - - region = CTX_wm_region(C); + ARegion *region = CTX_wm_region(C); if (region == NULL) { return; } UI_blocklist_free(C, ®ion->uiblocks); - screen = CTX_wm_screen(C); + bScreen *screen = CTX_wm_screen(C); if (screen == NULL) { return; } @@ -10748,18 +10656,16 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE { ARegion *menu_region = CTX_wm_menu(C); ARegion *region = menu_region ? menu_region : CTX_wm_region(C); - uiBut *but; int retval = WM_UI_HANDLER_CONTINUE; - but = ui_region_find_active_but(region); + uiBut *but = ui_region_find_active_but(region); if (but) { bScreen *screen = CTX_wm_screen(C); uiBut *but_other; - uiHandleButtonData *data; /* handle activated button events */ - data = but->active; + uiHandleButtonData *data = but->active; if ((data->state == BUTTON_STATE_MENU_OPEN) && /* Make sure this popup isn't dragging a button. @@ -10841,13 +10747,12 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata) { uiPopupBlockHandle *menu = userdata; - struct ARegion *menu_region; /* we block all events, this is modal interaction, * except for drop events which is described below */ int retval = WM_UI_HANDLER_BREAK; bool reset_pie = false; - menu_region = CTX_wm_menu(C); + ARegion *menu_region = CTX_wm_menu(C); CTX_wm_menu_set(C, menu->region); if (event->type == EVT_DROP || event->val == KM_DBL_CLICK) { @@ -10869,7 +10774,7 @@ static int ui_popup_handler(bContext *C, const wmEvent *event, void *userdata) if (menu->menuretval) { wmWindow *win = CTX_wm_window(C); /* copy values, we have to free first (closes region) */ - uiPopupBlockHandle temp = *menu; + const uiPopupBlockHandle temp = *menu; uiBlock *block = menu->region->uiblocks.first; /* set last pie event to allow chained pie spawning */ @@ -10993,26 +10898,28 @@ bool UI_textbutton_activate_rna(const bContext *C, const void *rna_poin_data, const char *rna_prop_id) { - uiBlock *block; - uiBut *but = NULL; + uiBlock *block_text = NULL; + uiBut *but_text = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_TEXT) { if (but->rnaprop && but->rnapoin.data == rna_poin_data) { if (STREQ(RNA_property_identifier(but->rnaprop), rna_prop_id)) { + block_text = block; + but_text = but; break; } } } } - if (but) { + if (but_text) { break; } } - if (but) { - UI_but_active_only(C, region, block, but); + if (but_text) { + UI_but_active_only(C, region, block_text, but_text); return true; } return false; @@ -11021,23 +10928,25 @@ bool UI_textbutton_activate_rna(const bContext *C, bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) { ARegion *region = CTX_wm_region(C); - uiBlock *block; - uiBut *but = NULL; + uiBlock *block_text = NULL; + uiBut *but_text = NULL; - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but == actbut && but->type == UI_BTYPE_TEXT) { + block_text = block; + but_text = but; break; } } - if (but) { + if (but_text) { break; } } - if (but) { - UI_but_active_only(C, region, block, but); + if (but_text) { + UI_but_active_only(C, region, block_text, but_text); return true; } return false; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index a7b7bad2fe6..aae0d7c525f 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -28,6 +28,7 @@ #include "MEM_guardedalloc.h" #include "GPU_batch.h" +#include "GPU_batch_presets.h" #include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_state.h" @@ -264,9 +265,9 @@ static void viconutil_set_point(GLint pt[2], int x, int y) static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float alpha) { GLint pts[3][2]; - int cx = x + w / 2 - 4; - int cy = y + w / 2; - int d = w / 5, d2 = w / 7; + const int cx = x + w / 2 - 4; + const int cy = y + w / 2; + const int d = w / 5, d2 = w / 7; viconutil_set_point(pts[0], cx - d2, cy + d); viconutil_set_point(pts[1], cx - d2, cy - d); @@ -301,17 +302,17 @@ static void vicon_keytype_draw_wrapper( * while the draw_keyframe_shape() function needs the midpoint for * the keyframe */ - float xco = x + w / 2 + 0.5f; - float yco = y + h / 2 + 0.5f; + const float xco = x + w / 2 + 0.5f; + const float yco = y + h / 2 + 0.5f; GPUVertFormat *format = immVertexFormat(); - uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + const uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add( format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint outline_color_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); - uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); + const uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); GPU_program_point_size(true); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); @@ -323,7 +324,7 @@ static void vicon_keytype_draw_wrapper( * - size: (default icon size == 16, default dopesheet icon size == 10) * - sel: true unless in handletype icons (so that "keyframe" state shows the iconic yellow icon) */ - bool sel = (handle_type == KEYFRAME_HANDLE_NONE); + const bool sel = (handle_type == KEYFRAME_HANDLE_NONE); draw_keyframe_shape(xco, yco, @@ -490,7 +491,7 @@ static void init_brush_icons(void) # define INIT_BRUSH_ICON(icon_id, name) \ { \ uchar *rect = (uchar *)datatoc_##name##_png; \ - int size = datatoc_##name##_png_size; \ + const int size = datatoc_##name##_png_size; \ DrawInfo *di; \ \ di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER, 0); \ @@ -732,7 +733,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, for (int y = 0; y < ICON_GRID_ROWS; y++) { for (int x = 0; x < ICON_GRID_COLS; x++) { - IconType icontype = icontypes[y * ICON_GRID_COLS + x]; + const IconType icontype = icontypes[y * ICON_GRID_COLS + x]; if (icontype.type != ICON_TYPE_MONO_TEXTURE) { continue; } @@ -743,7 +744,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, sy = sy / resolution_divider; /* blur the alpha channel and store it in blurred_alpha_buffer */ - int blur_size = 2 / resolution_divider; + const int blur_size = 2 / resolution_divider; for (int bx = 0; bx < icon_width; bx++) { const int asx = MAX2(bx - blur_size, 0); const int aex = MIN2(bx + blur_size + 1, icon_width); @@ -758,7 +759,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, for (int ax = asx; ax < aex; ax++) { for (int ay = asy; ay < aey; ay++) { const int offset_read = (sy + ay) * buf->x + (sx + ax); - uint color_read = buf->rect[offset_read]; + const uint color_read = buf->rect[offset_read]; const float alpha_read = ((color_read & 0xff000000) >> 24) / 255.0; alpha_accum += alpha_read; alpha_samples += 1; @@ -790,8 +791,8 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, blend_color_interpolate_float(dest_rgba, orig_rgba, border_rgba, 1.0 - orig_rgba[3]); linearrgb_to_srgb_v4(dest_srgb, dest_rgba); - uint alpha_mask = ((uint)(dest_srgb[3] * 255)) << 24; - uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask; + const uint alpha_mask = ((uint)(dest_srgb[3] * 255)) << 24; + const uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask; result->rect[offset_write] = cpack; } } @@ -820,7 +821,7 @@ void UI_icons_reload_internal_textures(void) bTheme *btheme = UI_GetTheme(); ImBuf *b16buf = NULL, *b32buf = NULL, *b16buf_border = NULL, *b32buf_border = NULL; const float icon_border_intensity = btheme->tui.icon_border_intensity; - bool need_icons_with_border = icon_border_intensity > 0.0f; + const bool need_icons_with_border = icon_border_intensity > 0.0f; if (b16buf == NULL) { b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png, @@ -936,7 +937,7 @@ static void init_internal_icons(void) for (y = 0; y < ICON_GRID_ROWS; y++) { /* Row W has monochrome icons. */ for (x = 0; x < ICON_GRID_COLS; x++) { - IconType icontype = icontypes[y * ICON_GRID_COLS + x]; + const IconType icontype = icontypes[y * ICON_GRID_COLS + x]; if (!ELEM(icontype.type, ICON_TYPE_COLOR_TEXTURE, ICON_TYPE_MONO_TEXTURE)) { continue; } @@ -1130,7 +1131,7 @@ void UI_icons_free_drawinfo(void *drawinfo) */ static DrawInfo *icon_create_drawinfo(Icon *icon) { - int icon_data_type = icon->obj_type; + const int icon_data_type = icon->obj_type; DrawInfo *di = NULL; di = MEM_callocN(sizeof(DrawInfo), "di_icon"); @@ -1246,7 +1247,7 @@ int UI_preview_render_size(enum eIconSizes size) */ static void icon_create_rect(struct PreviewImage *prv_img, enum eIconSizes size) { - uint render_size = UI_preview_render_size(size); + const uint render_size = UI_preview_render_size(size); if (!prv_img) { if (G.debug & G_DEBUG) { @@ -1351,7 +1352,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi img->w = STUDIOLIGHT_ICON_SIZE; img->h = STUDIOLIGHT_ICON_SIZE; - size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint); + const size_t size = STUDIOLIGHT_ICON_SIZE * STUDIOLIGHT_ICON_SIZE * sizeof(uint); img->rect = MEM_mallocN(size, __func__); memset(img->rect, 0, size); di->data.buffer.image = img; @@ -1479,7 +1480,7 @@ static void icon_draw_rect(float x, return; } /* modulate color */ - float col[4] = {alpha, alpha, alpha, alpha}; + const float col[4] = {alpha, alpha, alpha, alpha}; /* rect contains image in 'rendersize', we only scale if needed */ if (rw != w || rh != h) { @@ -1565,15 +1566,17 @@ static void icon_draw_cache_texture_flush_ex(GPUTexture *texture, GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_MULTI_RECT_COLOR); GPU_shader_bind(shader); - int img_binding = GPU_shader_get_texture_binding(shader, "image"); - int data_loc = GPU_shader_get_uniform(shader, "calls_data"); + const int img_binding = GPU_shader_get_texture_binding(shader, "image"); + const int data_loc = GPU_shader_get_uniform(shader, "calls_data"); GPU_texture_bind(texture, img_binding); GPU_sampler_icon_bind(img_binding); GPU_shader_uniform_vector( shader, data_loc, 4, ICON_DRAW_CACHE_SIZE * 3, (float *)texture_draw_calls->drawcall_cache); - GPU_draw_primitive(GPU_PRIM_TRIS, 6 * texture_draw_calls->calls); + GPUBatch *quad = GPU_batch_preset_quad(); + GPU_batch_set_shader(quad, shader); + GPU_batch_draw_instanced(quad, texture_draw_calls->calls); GPU_texture_unbind(texture); @@ -1595,7 +1598,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches) /* We need to flush widget base first to ensure correct ordering. */ UI_widgetbase_draw_cache_flush(); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); if (!only_full_caches || g_icon_draw_cache.normal.calls == ICON_DRAW_CACHE_SIZE) { icon_draw_cache_texture_flush_ex(icongltex.tex[0], &g_icon_draw_cache.normal); @@ -1605,8 +1608,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches) icon_draw_cache_texture_flush_ex(icongltex.tex[1], &g_icon_draw_cache.border); } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } } @@ -1620,9 +1622,9 @@ void UI_icon_draw_cache_end(void) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); icon_draw_cache_flush_ex(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void icon_draw_texture_cached(float x, @@ -1690,7 +1692,7 @@ static void icon_draw_texture(float x, /* We need to flush widget base first to ensure correct ordering. */ UI_widgetbase_draw_cache_flush(); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); float x1, x2, y1, y2; @@ -1704,10 +1706,10 @@ static void icon_draw_texture(float x, GPUShader *shader = GPU_shader_get_builtin_shader(GPU_SHADER_2D_IMAGE_RECT_COLOR); GPU_shader_bind(shader); - int img_binding = GPU_shader_get_texture_binding(shader, "image"); - int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR); - int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon"); - int rect_geom_loc = GPU_shader_get_uniform(shader, "rect_geom"); + const int img_binding = GPU_shader_get_texture_binding(shader, "image"); + const int color_loc = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_COLOR); + const int rect_tex_loc = GPU_shader_get_uniform(shader, "rect_icon"); + const int rect_geom_loc = GPU_shader_get_uniform(shader, "rect_geom"); if (rgb) { GPU_shader_uniform_vector(shader, color_loc, 4, 1, (float[4]){UNPACK3(rgb), alpha}); @@ -1722,12 +1724,13 @@ static void icon_draw_texture(float x, GPU_texture_bind(texture, img_binding); GPU_sampler_icon_bind(img_binding); - GPU_draw_primitive(GPU_PRIM_TRI_STRIP, 4); + GPUBatch *quad = GPU_batch_preset_quad(); + GPU_batch_set_shader(quad, shader); + GPU_batch_draw(quad); GPU_texture_unbind(texture); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* Drawing size for preview images */ @@ -1815,11 +1818,9 @@ static void icon_draw_size(float x, di->data.geom.inverted = invert; } - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } else if (di->type == ICON_TYPE_EVENT) { const short event_type = di->data.input.event_type; @@ -1842,7 +1843,7 @@ static void icon_draw_size(float x, } else if (di->type == ICON_TYPE_MONO_TEXTURE) { /* Monochrome icon that uses text or theme color. */ - bool with_border = mono_border && (btheme->tui.icon_border_intensity > 0.0f); + const bool with_border = mono_border && (btheme->tui.icon_border_intensity > 0.0f); float color[4]; if (mono_rgba) { rgba_uchar_to_float(color, (const uchar *)mono_rgba); @@ -1900,12 +1901,10 @@ static void icon_draw_size(float x, } /* Preview images use premultiplied alpha. */ - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); icon_draw_rect( x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } } else if (di->type == ICON_TYPE_GPLAYER) { @@ -2228,7 +2227,7 @@ int UI_rnaptr_icon_get(bContext *C, PointerRNA *ptr, int rnaicon, const bool big /* get icon from ID */ if (id) { - int icon = ui_id_icon_get(C, id, big); + const int icon = ui_id_icon_get(C, id, big); return icon ? icon : rnaicon; } @@ -2340,7 +2339,7 @@ void UI_icon_draw_ex(float x, const uchar mono_color[4], const bool mono_border) { - int draw_size = get_draw_size(ICON_SIZE_ICON); + const int draw_size = get_draw_size(ICON_SIZE_ICON); icon_draw_size(x, y, icon_id, diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c index 4be2dbc0b4e..223fcbfd45b 100644 --- a/source/blender/editors/interface/interface_icons_event.c +++ b/source/blender/editors/interface/interface_icons_event.c @@ -85,8 +85,8 @@ static void icon_draw_rect_input_text(const rctf *rect, BLF_size(font_id, font_size * U.pixelsize, U.dpi); float width, height; BLF_width_and_height(font_id, str, BLF_DRAW_STR_DUMMY_MAX, &width, &height); - float x = rect->xmin + (((rect->xmax - rect->xmin) - width) / 2.0f); - float y = rect->ymin + (((rect->ymax - rect->ymin) - height) / 2.0f); + const float x = rect->xmin + (((rect->xmax - rect->xmin) - width) / 2.0f); + const float y = rect->ymin + (((rect->ymax - rect->ymin) - height) / 2.0f); BLF_position(font_id, x, y, 0.0f); BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX); BLF_batch_draw_flush(); @@ -98,8 +98,8 @@ static void icon_draw_rect_input_symbol(const rctf *rect, const float color[4], const int font_id = blf_mono_font; BLF_color4fv(font_id, color); BLF_size(font_id, 19 * U.pixelsize, U.dpi); - float x = rect->xmin + (2.0f * U.pixelsize); - float y = rect->ymin + (1.0f * U.pixelsize); + const float x = rect->xmin + (2.0f * U.pixelsize); + const float y = rect->ymin + (1.0f * U.pixelsize); BLF_position(font_id, x, y, 0.0f); BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX); BLF_batch_draw_flush(); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 6718db39e61..87be3745f87 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -33,6 +33,8 @@ struct AnimationEvalContext; struct ARegion; +struct CurveMapping; +struct CurveProfile; struct ID; struct ImBuf; struct Scene; @@ -266,9 +268,6 @@ struct uiBut { char *editstr; double *editval; float *editvec; - void *editcoba; - void *editcumap; - void *editprofile; uiButPushedStateFunc pushed_state_func; void *pushed_state_arg; @@ -320,6 +319,7 @@ typedef struct uiButDecorator { int rnaindex; } uiButDecorator; +/** Derived struct for #UI_BTYPE_PROGRESS_BAR. */ typedef struct uiButProgressbar { uiBut but; @@ -327,12 +327,34 @@ typedef struct uiButProgressbar { float progress; } uiButProgressbar; +/** Derived struct for #UI_BTYPE_HSVCUBE. */ typedef struct uiButHSVCube { uiBut but; eButGradientType gradient_type; } uiButHSVCube; +/** Derived struct for #UI_BTYPE_CURVEPROFILE. */ +typedef struct uiButColorBand { + uiBut but; + + struct ColorBand *edit_coba; +} uiButColorBand; + +/** Derived struct for #UI_BTYPE_CURVEPROFILE. */ +typedef struct uiButCurveProfile { + uiBut but; + + struct CurveProfile *edit_profile; +} uiButCurveProfile; + +/** Derived struct for #UI_BTYPE_CURVE. */ +typedef struct uiButCurveMapping { + uiBut but; + + struct CurveMapping *edit_cumap; +} uiButCurveMapping; + /** * Additional, superimposed icon for a button, invoking an operator. */ @@ -772,8 +794,8 @@ extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event, struct ARegion *region, const uiBut *active_but); -extern void ui_draw_aligned_panel(struct uiStyle *style, - uiBlock *block, +extern void ui_draw_aligned_panel(const struct uiStyle *style, + const uiBlock *block, const rcti *rect, const bool show_pin, const bool show_background); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 888cacb64eb..f7955c15dc4 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -225,7 +225,7 @@ typedef struct uiLayoutItemRoot { static const char *ui_item_name_add_colon(const char *name, char namestr[UI_MAX_NAME_STR]) { - int len = strlen(name); + const int len = strlen(name); if (len != 0 && len + 1 < UI_MAX_NAME_STR) { memcpy(namestr, name, len); @@ -251,7 +251,7 @@ static int ui_item_fit( return available - pos; } - float width = *extra_pixel + (item * available) / (float)all; + const float width = *extra_pixel + (item * available) / (float)all; *extra_pixel = width - (int)width; return (int)width; } @@ -262,7 +262,7 @@ static int ui_item_fit( return available - pos; } - float width = *extra_pixel + (item * available) / (float)all; + const float width = *extra_pixel + (item * available) / (float)all; *extra_pixel = width - (int)width; return (int)width; } @@ -453,12 +453,12 @@ static uiLayout *ui_item_local_sublayout(uiLayout *test, uiLayout *layout, bool static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) { wmWindow *win = CTX_wm_window(C); - uiBut *but = arg_but, *cbut; + uiBut *but = arg_but; PointerRNA *ptr = &but->rnapoin; PropertyRNA *prop = but->rnaprop; int i, index = POINTER_AS_INT(arg_index); - int shift = win->eventstate->shift; - int len = RNA_property_array_length(ptr, prop); + const int shift = win->eventstate->shift; + const int len = RNA_property_array_length(ptr, prop); if (!shift) { RNA_property_boolean_set_index(ptr, prop, index, true); @@ -471,7 +471,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) RNA_property_update(C, ptr, prop); - for (cbut = but->block->buttons.first; cbut; cbut = cbut->next) { + LISTBASE_FOREACH (uiBut *, cbut, &but->block->buttons) { ui_but_update(cbut); } } @@ -519,7 +519,7 @@ static void ui_item_array(uiLayout *layout, if (type == PROP_BOOLEAN && ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER)) { /* special check for layer layout */ int butw, buth, unit; - int cols = (len >= 20) ? 2 : 1; + const int cols = (len >= 20) ? 2 : 1; const uint colbuts = len / (2 * cols); uint layer_used = 0; uint layer_active = 0; @@ -721,7 +721,7 @@ static void ui_item_enum_expand_handle(bContext *C, void *arg1, void *arg2) if (!win->eventstate->shift) { uiBut *but = (uiBut *)arg1; - int enum_value = POINTER_AS_INT(arg2); + const int enum_value = POINTER_AS_INT(arg2); int current_value = RNA_property_enum_get(&but->rnapoin, but->rnaprop); if (!(current_value & enum_value)) { @@ -814,7 +814,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout, BLI_assert(RNA_property_type(prop) == PROP_ENUM); uiLayout *layout_radial = NULL; - bool radial = (layout->root->type == UI_LAYOUT_PIEMENU); + const bool radial = (layout->root->type == UI_LAYOUT_PIEMENU); if (radial) { RNA_property_enum_items_gettexted_all(block->evil_C, ptr, prop, &item_array, NULL, &free); } @@ -1072,8 +1072,7 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C, bool *r_is_userdef) { ARegion *region = CTX_wm_menu(C) ? CTX_wm_menu(C) : CTX_wm_region(C); - uiBlock *block; - uiBut *but, *prevbut = NULL; + uiBut *prevbut = NULL; memset(r_ptr, 0, sizeof(*r_ptr)); *r_prop = NULL; @@ -1084,8 +1083,8 @@ void UI_context_active_but_prop_get_filebrowser(const bContext *C, return; } - for (block = region->uiblocks.first; block; block = block->next) { - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but && but->rnapoin.data) { if (RNA_property_type(but->rnaprop) == PROP_STRING) { prevbut = but; @@ -1180,7 +1179,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout, w = ui_text_icon_width(layout, name, icon, 0); - int prev_emboss = layout->emboss; + const int prev_emboss = layout->emboss; if (flag & UI_ITEM_R_NO_BG) { layout->emboss = UI_EMBOSS_NONE; } @@ -1224,7 +1223,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout, opptr->data = properties; } else { - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; opptr->data = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } if (r_opptr) { @@ -1978,9 +1977,7 @@ void uiItemFullR(uiLayout *layout, uiLayout *layout; uiBut *but; } ui_decorate = { - .use_prop_decorate = (((layout->item.flag & UI_ITEM_PROP_DECORATE) != 0) && - (use_prop_sep && ptr->owner_id && - id_can_have_animdata(ptr->owner_id))), + .use_prop_decorate = (((layout->item.flag & UI_ITEM_PROP_DECORATE) != 0) && use_prop_sep), }; #endif /* UI_PROP_DECORATE */ @@ -2044,7 +2041,7 @@ void uiItemFullR(uiLayout *layout, 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); + const 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) { @@ -2061,7 +2058,7 @@ void uiItemFullR(uiLayout *layout, } else if (type == PROP_ENUM) { if (index == RNA_ENUM_VALUE) { - int enum_value = RNA_property_enum_get(ptr, prop); + const 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 */ } @@ -2100,7 +2097,7 @@ void uiItemFullR(uiLayout *layout, int w, h; ui_item_rna_size(layout, name, icon, ptr, prop, index, icon_only, compact, &w, &h); - int prev_emboss = layout->emboss; + const int prev_emboss = layout->emboss; if (no_bg) { layout->emboss = UI_EMBOSS_NONE; } @@ -3194,7 +3191,7 @@ uiLayout *uiItemL_respect_property_split(uiLayout *layout, const char *text, int { if (layout->item.flag & UI_ITEM_PROP_SEP) { uiBlock *block = uiLayoutGetBlock(layout); - uiPropertySplitWrapper split_wrapper = uiItemPropertySplitWrapperCreate(layout); + const uiPropertySplitWrapper split_wrapper = uiItemPropertySplitWrapperCreate(layout); /* Further items added to 'layout' will automatically be added to split_wrapper.property_row */ uiItemL_(split_wrapper.label_column, text, icon); @@ -3273,7 +3270,7 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval) void uiItemS_ex(uiLayout *layout, float factor) { uiBlock *block = layout->root->block; - bool is_menu = ui_block_is_menu(block); + const bool is_menu = ui_block_is_menu(block); if (is_menu && !UI_block_can_add_separator(block)) { return; } @@ -3515,14 +3512,13 @@ void uiItemTabsEnumR_prop( /* single-row layout */ static void ui_litem_estimate_row(uiLayout *litem) { - uiItem *item; int itemw, itemh; bool min_size_flag = true; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); @@ -3547,7 +3543,7 @@ static int ui_litem_min_width(int itemw) static void ui_litem_layout_row(uiLayout *litem) { - uiItem *item, *last_free_item = NULL; + uiItem *last_free_item = NULL; int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; float extra_pixel; @@ -3558,7 +3554,7 @@ static void ui_litem_layout_row(uiLayout *litem) totw = 0; tot = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); totw += itemw; tot++; @@ -3581,7 +3577,7 @@ static void ui_litem_layout_row(uiLayout *litem) newtotw = totw; extra_pixel = 0.0f; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { if (item->flag & UI_ITEM_AUTO_FIXED_SIZE) { continue; } @@ -3633,7 +3629,7 @@ static void ui_litem_layout_row(uiLayout *litem) extra_pixel = 0.0f; x = litem->x; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); minw = ui_litem_min_width(itemw); @@ -3682,7 +3678,7 @@ static void ui_litem_layout_row(uiLayout *litem) if (extra_pixel > 0 && litem->alignment == UI_LAYOUT_ALIGN_EXPAND && last_free_item && last_item && last_item->flag & UI_ITEM_AUTO_FIXED_SIZE) { ui_item_move(last_free_item, 0, extra_pixel); - for (item = last_free_item->next; item; item = item->next) { + for (uiItem *item = last_free_item->next; item; item = item->next) { ui_item_move(item, extra_pixel, extra_pixel); } } @@ -3696,14 +3692,13 @@ static void ui_litem_layout_row(uiLayout *litem) /* single-column layout */ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) { - uiItem *item; int itemw, itemh; bool min_size_flag = true; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); min_size_flag = min_size_flag && (item->flag & UI_ITEM_FIXED_SIZE); @@ -3723,13 +3718,12 @@ static void ui_litem_estimate_column(uiLayout *litem, bool is_box) static void ui_litem_layout_column(uiLayout *litem, bool is_box) { - uiItem *item; int itemh, x, y; x = litem->x; y = litem->y; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, NULL, &itemh); y -= itemh; @@ -3789,7 +3783,6 @@ static bool ui_item_is_radial_drawable(uiButtonItem *bitem) static void ui_litem_layout_radial(uiLayout *litem) { - uiItem *item; int itemh, itemw, x, y; int itemnum = 0; int totitems = 0; @@ -3799,7 +3792,7 @@ static void ui_litem_layout_radial(uiLayout *litem) * also the old code at http://developer.blender.org/T5103 */ - int pie_radius = U.pie_menu_radius * UI_DPI_FAC; + const int pie_radius = U.pie_menu_radius * UI_DPI_FAC; x = litem->x; y = litem->y; @@ -3807,7 +3800,7 @@ static void ui_litem_layout_radial(uiLayout *litem) int minx = x, miny = y, maxx = x, maxy = y; /* first count total items */ - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { totitems++; } @@ -3815,7 +3808,7 @@ static void ui_litem_layout_radial(uiLayout *litem) litem->root->block->pie_data.flags |= UI_PIE_DEGREES_RANGE_LARGE; } - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { /* not all button types are drawn in a radial menu, do filtering here */ if (ui_item_is_radial_displayable(item)) { RadialDirection dir; @@ -3965,14 +3958,13 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - uiItem *item; int col, x, y, emh, emy, miny, itemw, itemh, maxw = 0; int toth, totitem; /* compute max needed width and total height */ toth = 0; totitem = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); maxw = MAX2(maxw, itemw); toth += itemh; @@ -4004,7 +3996,7 @@ static void ui_litem_estimate_column_flow(uiLayout *litem) /* create column per column */ col = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); y -= itemh + style->buttonspacey; @@ -4030,14 +4022,13 @@ static void ui_litem_layout_column_flow(uiLayout *litem) { const uiStyle *style = litem->root->style; uiLayoutItemFlow *flow = (uiLayoutItemFlow *)litem; - uiItem *item; int col, x, y, w, emh, emy, miny, itemw, itemh; int toth, totitem; /* compute max needed width and total height */ toth = 0; totitem = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); toth += itemh; totitem++; @@ -4055,7 +4046,7 @@ static void ui_litem_layout_column_flow(uiLayout *litem) /* create column per column */ col = 0; w = (litem->w - (flow->totcol - 1) * style->columnspace) / flow->totcol; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); itemw = (litem->alignment == UI_LAYOUT_ALIGN_EXPAND) ? w : min_ii(w, itemw); @@ -4121,9 +4112,6 @@ static void ui_litem_grid_flow_compute(ListBase *items, UILayoutGridFlowInput *parameters, UILayoutGridFlowOutput *results) { - uiItem *item; - int i; - float tot_w = 0.0f, tot_h = 0.0f; float global_avg_w = 0.0f, global_totweight_w = 0.0f; int global_max_h = 0; @@ -4163,7 +4151,8 @@ static void ui_litem_grid_flow_compute(ListBase *items, memset(max_h, 0, sizeof(*max_h) * parameters->tot_rows); } - for (i = 0, item = items->first; item; item = item->next, i++) { + int i = 0; + LISTBASE_FOREACH (uiItem *, item, items) { int item_w, item_h; ui_item_size(item, &item_w, &item_h); @@ -4186,6 +4175,7 @@ static void ui_litem_grid_flow_compute(ListBase *items, if (results->tot_items) { (*results->tot_items)++; } + i++; } /* Finalize computing of column average sizes */ @@ -4394,10 +4384,8 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) static void ui_litem_layout_grid_flow(uiLayout *litem) { - int i; const uiStyle *style = litem->root->style; uiLayoutItemGridFlow *gflow = (uiLayoutItemGridFlow *)litem; - uiItem *item; if (gflow->tot_items == 0) { litem->w = litem->h = 0; @@ -4436,7 +4424,8 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) .heights_array = heights, })); - for (item = litem->items.first, i = 0; item; item = item->next, i++) { + int i; + LISTBASE_FOREACH_INDEX (uiItem *, item, &litem->items, i) { const int col = gflow->row_major ? i % gflow->tot_columns : i / gflow->tot_rows; const int row = gflow->row_major ? i / gflow->tot_columns : i % gflow->tot_rows; int item_w, item_h; @@ -4459,7 +4448,6 @@ static void ui_litem_layout_grid_flow(uiLayout *litem) /* free layout */ static void ui_litem_estimate_absolute(uiLayout *litem) { - uiItem *item; int itemx, itemy, itemw, itemh, minx, miny; minx = 1e6; @@ -4467,7 +4455,7 @@ static void ui_litem_estimate_absolute(uiLayout *litem) litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4484,7 +4472,6 @@ static void ui_litem_estimate_absolute(uiLayout *litem) static void ui_litem_layout_absolute(uiLayout *litem) { - uiItem *item; float scalex = 1.0f, scaley = 1.0f; int x, y, newx, newy, itemx, itemy, itemh, itemw, minx, miny, totw, toth; @@ -4493,7 +4480,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) totw = 0; toth = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4517,7 +4504,7 @@ static void ui_litem_layout_absolute(uiLayout *litem) x = litem->x; y = litem->y - scaley * toth; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_offset(item, &itemx, &itemy); ui_item_size(item, &itemw, &itemh); @@ -4552,7 +4539,6 @@ static void ui_litem_estimate_split(uiLayout *litem) static void ui_litem_layout_split(uiLayout *litem) { uiLayoutItemSplit *split = (uiLayoutItemSplit *)litem; - uiItem *item; float percentage, extra_pixel = 0.0f; const int tot = BLI_listbase_count(&litem->items); int itemh, x, y, w, colw = 0; @@ -4570,7 +4556,7 @@ static void ui_litem_layout_split(uiLayout *litem) colw = w * percentage; colw = MAX2(colw, 0); - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, NULL, &itemh); ui_item_position(item, x, y - itemh, colw, itemh); @@ -4595,13 +4581,12 @@ static void ui_litem_layout_split(uiLayout *litem) /* overlap layout */ static void ui_litem_estimate_overlap(uiLayout *litem) { - uiItem *item; int itemw, itemh; litem->w = 0; litem->h = 0; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); litem->w = MAX2(itemw, litem->w); @@ -4611,13 +4596,12 @@ static void ui_litem_estimate_overlap(uiLayout *litem) static void ui_litem_layout_overlap(uiLayout *litem) { - uiItem *item; int itemw, itemh, x, y; x = litem->x; y = litem->y; - for (item = litem->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); ui_item_position(item, x, y - itemh, litem->w, itemh); @@ -4775,7 +4759,6 @@ static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type) uiLayout *uiLayoutRadial(uiLayout *layout) { uiLayout *litem; - uiItem *item; /* radial layouts are only valid for radial menus */ if (layout->root->type != UI_LAYOUT_PIEMENU) { @@ -4783,7 +4766,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) } /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ - for (item = layout->root->layout->items.first; item; item = item->next) { + LISTBASE_FOREACH (uiItem *, item, &layout->root->layout->items) { litem = (uiLayout *)item; if (litem->item.type == ITEM_LAYOUT_RADIAL) { UI_block_layout_set_current(layout->root->block, litem); @@ -4813,8 +4796,7 @@ uiLayout *uiLayoutBox(uiLayout *layout) */ void ui_layout_list_set_labels_active(uiLayout *layout) { - uiButtonItem *bitem; - for (bitem = layout->items.first; bitem; bitem = bitem->item.next) { + LISTBASE_FOREACH (uiButtonItem *, bitem, &layout->items) { if (bitem->item.type != ITEM_BUTTON) { ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); } @@ -5055,10 +5037,9 @@ int uiLayoutGetEmboss(uiLayout *layout) static void ui_item_scale(uiLayout *litem, const float scale[2]) { - uiItem *item; int x, y, w, h; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type != ITEM_BUTTON) { uiLayout *subitem = (uiLayout *)item; ui_item_scale(subitem, scale); @@ -5083,12 +5064,10 @@ static void ui_item_scale(uiLayout *litem, const float scale[2]) static void ui_item_estimate(uiItem *item) { - uiItem *subitem; - if (item->type != ITEM_BUTTON) { uiLayout *litem = (uiLayout *)item; - for (subitem = litem->items.first; subitem; subitem = subitem->next) { + LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { ui_item_estimate(subitem); } @@ -5146,11 +5125,10 @@ static void ui_item_estimate(uiItem *item) static void ui_item_align(uiLayout *litem, short nr) { - uiItem *item; uiButtonItem *bitem; uiLayoutItemBx *box; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { bitem = (uiButtonItem *)item; #ifndef USE_UIBUT_SPATIAL_ALIGN @@ -5182,10 +5160,9 @@ static void ui_item_align(uiLayout *litem, short nr) static void ui_item_flag(uiLayout *litem, int flag) { - uiItem *item; uiButtonItem *bitem; - for (item = litem->items.last; item; item = item->prev) { + LISTBASE_FOREACH_BACKWARD (uiItem *, item, &litem->items) { if (item->type == ITEM_BUTTON) { bitem = (uiButtonItem *)item; bitem->but->flag |= flag; @@ -5198,8 +5175,6 @@ static void ui_item_flag(uiLayout *litem, int flag) static void ui_item_layout(uiItem *item) { - uiItem *subitem; - if (item->type != ITEM_BUTTON) { uiLayout *litem = (uiLayout *)item; @@ -5252,7 +5227,7 @@ static void ui_item_layout(uiItem *item) break; } - for (subitem = litem->items.first; subitem; subitem = subitem->next) { + LISTBASE_FOREACH (uiItem *, subitem, &litem->items) { if (item->flag & UI_ITEM_BOX_ITEM) { subitem->flag |= UI_ITEM_BOX_ITEM; } @@ -5286,11 +5261,7 @@ static void ui_layout_end(uiBlock *block, uiLayout *layout, int *r_x, int *r_y) static void ui_layout_free(uiLayout *layout) { - uiItem *item, *next; - - for (item = layout->items.first; item; item = next) { - next = item->next; - + LISTBASE_FOREACH_MUTABLE (uiItem *, item, &layout->items) { if (item->type == ITEM_BUTTON) { MEM_freeN(item); } @@ -5474,8 +5445,6 @@ void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv) void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) { - uiLayoutRoot *root; - BLI_assert(block->active); if (r_x) { @@ -5487,7 +5456,7 @@ void UI_block_layout_resolve(uiBlock *block, int *r_x, int *r_y) block->curlayout = NULL; - for (root = block->layouts.first; root; root = root->next) { + LISTBASE_FOREACH (uiLayoutRoot *, root, &block->layouts) { ui_layout_add_padding_button(root); /* NULL in advance so we don't interfere when adding button */ diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 5a49f3e70d0..d6919fb4de7 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -201,7 +201,7 @@ static int copy_as_driver_button_exec(bContext *C, wmOperator *op) if (ptr.owner_id && ptr.data && prop) { ID *id; - int dim = RNA_property_array_dimension(&ptr, prop, NULL); + const int dim = RNA_property_array_dimension(&ptr, prop, NULL); char *path = RNA_path_from_real_ID_to_property_index(bmain, &ptr, prop, dim, index, &id); if (path) { @@ -378,7 +378,7 @@ static bool assign_default_button_poll(bContext *C) UI_context_active_but_prop_get(C, &ptr, &prop, &index); if (ptr.data && prop && RNA_property_editable(&ptr, prop)) { - PropertyType type = RNA_property_type(prop); + const PropertyType type = RNA_property_type(prop); return RNA_property_is_idprop(prop) && !RNA_property_array_check(prop) && ELEM(type, PROP_INT, PROP_FLOAT); @@ -715,8 +715,7 @@ static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb) lb = CTX_data_collection_get(C, "selected_pose_bones"); if (!BLI_listbase_is_empty(&lb)) { - CollectionPointerLink *link; - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { bPoseChannel *pchan = link->ptr.data; RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr); } @@ -843,12 +842,10 @@ bool UI_context_copy_to_selected_list(bContext *C, /* Now filter by type */ if (node) { - CollectionPointerLink *link, *link_next; lb = CTX_data_collection_get(C, "selected_nodes"); - for (link = lb.first; link; link = link_next) { + LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { bNode *node_data = link->ptr.data; - link_next = link->next; if (node_data->type != node->type) { BLI_remlink(&lb, link); @@ -876,9 +873,7 @@ bool UI_context_copy_to_selected_list(bContext *C, /* de-duplicate obdata */ if (!BLI_listbase_is_empty(&lb)) { - CollectionPointerLink *link, *link_next; - - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; if (ob->data) { ID *id_data = ob->data; @@ -886,10 +881,9 @@ bool UI_context_copy_to_selected_list(bContext *C, } } - for (link = lb.first; link; link = link_next) { + LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; ID *id_data = ob->data; - link_next = link->next; if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) || (GS(id_data->name) != id_code)) { @@ -970,12 +964,11 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) if (ptr.data && prop) { char *path = NULL; bool use_path_from_id; - CollectionPointerLink *link; ListBase lb = {NULL}; if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) && !BLI_listbase_is_empty(&lb)) { - for (link = lb.first; link; link = link->next) { + LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { if (link->ptr.data != ptr.data) { if (use_path_from_id) { /* Path relative to ID. */ @@ -1181,7 +1174,7 @@ bool ui_jump_to_target_button_poll(bContext *C) static int jump_to_target_button_exec(bContext *C, wmOperator *UNUSED(op)) { - bool success = jump_to_target_button(C, false); + const bool success = jump_to_target_button(C, false); return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } @@ -1299,13 +1292,14 @@ static int editsource_text_edit(bContext *C, const int line) { struct Main *bmain = CTX_data_main(C); - Text *text; + Text *text = NULL; /* Developers may wish to copy-paste to an external editor. */ printf("%s:%d\n", filepath, line); - for (text = bmain->texts.first; text; text = text->id.next) { - if (text->filepath && BLI_path_cmp(text->filepath, filepath) == 0) { + LISTBASE_FOREACH (Text *, text_iter, &bmain->texts) { + if (text_iter->filepath && BLI_path_cmp(text_iter->filepath, filepath) == 0) { + text = text_iter; break; } } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index d334007a097..ade77e96bf9 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -64,7 +64,9 @@ #include "interface_intern.h" -/*********************** defines and structs ************************/ +/* -------------------------------------------------------------------- */ +/** \name Defines & Structs + * \{ */ #define ANIMATION_TIME 0.30 #define ANIMATION_INTERVAL 0.02 @@ -76,15 +78,11 @@ #define PNL_NEW_ADDED 16 #define PNL_FIRST 32 -/* only show pin header button for pinned panels */ -#define USE_PIN_HIDDEN - /* the state of the mouse position relative to the panel */ typedef enum uiPanelMouseState { - PANEL_MOUSE_OUTSIDE, /* mouse is not in the panel */ - PANEL_MOUSE_INSIDE_CONTENT, /* mouse is in the actual panel content */ - PANEL_MOUSE_INSIDE_HEADER, /* mouse is in the panel header */ - PANEL_MOUSE_INSIDE_SCALE, /* mouse is inside panel scale widget */ + PANEL_MOUSE_OUTSIDE, /** Mouse is not in the panel. */ + PANEL_MOUSE_INSIDE_CONTENT, /** Mouse is in the actual panel content. */ + PANEL_MOUSE_INSIDE_HEADER, /** Mouse is in the panel header. */ } uiPanelMouseState; typedef enum uiHandlePanelState { @@ -121,6 +119,12 @@ static bool panel_type_context_poll(ARegion *region, const PanelType *panel_type, const char *context); +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Local Functions + * \{ */ + static void panel_title_color_get(bool show_background, uchar color[4]) { if (show_background) { @@ -134,44 +138,9 @@ static void panel_title_color_get(bool show_background, uchar color[4]) } } -/*********************** space specific code ************************/ -/* temporary code to remove all sbuts stuff from panel code */ - -/* SpaceProperties.align */ -typedef enum eSpaceButtons_Align { - BUT_HORIZONTAL = 0, - BUT_VERTICAL = 1, - BUT_AUTO = 2, -} eSpaceButtons_Align; - -static int panel_aligned(const ScrArea *area, const ARegion *region) -{ - if (area->spacetype == SPACE_PROPERTIES && region->regiontype == RGN_TYPE_WINDOW) { - return BUT_VERTICAL; - } - if (area->spacetype == SPACE_USERPREF && region->regiontype == RGN_TYPE_WINDOW) { - return BUT_VERTICAL; - } - if (area->spacetype == SPACE_FILE && region->regiontype == RGN_TYPE_CHANNELS) { - return BUT_VERTICAL; - } - if (area->spacetype == SPACE_IMAGE && region->regiontype == RGN_TYPE_PREVIEW) { - return BUT_VERTICAL; - } - if (ELEM(region->regiontype, - RGN_TYPE_UI, - RGN_TYPE_TOOLS, - RGN_TYPE_TOOL_PROPS, - RGN_TYPE_HUD, - RGN_TYPE_NAV_BAR, - RGN_TYPE_EXECUTE)) { - return BUT_VERTICAL; - } - - return 0; -} - -static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, bool *no_animation) +static bool panel_active_animation_changed(ListBase *lb, + Panel **r_panel_animation, + bool *r_no_animation) { LISTBASE_FOREACH (Panel *, panel, lb) { /* Detect panel active flag changes. */ @@ -185,7 +154,7 @@ static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, b } if ((panel->runtime_flag & PNL_ACTIVE) && !(panel->flag & PNL_CLOSED)) { - if (panel_active_animation_changed(&panel->children, pa_animation, no_animation)) { + if (panel_active_animation_changed(&panel->children, r_panel_animation, r_no_animation)) { return true; } } @@ -194,15 +163,15 @@ static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, b if (panel->activedata) { uiHandlePanelData *data = panel->activedata; if (data->state == PANEL_STATE_ANIMATION) { - *pa_animation = panel; + *r_panel_animation = panel; } else { /* Don't animate while handling other interaction. */ - *no_animation = true; + *r_no_animation = true; } } - if ((panel->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) { - *pa_animation = panel; + if ((panel->runtime_flag & PNL_ANIM_ALIGN) && !(*r_panel_animation)) { + *r_panel_animation = panel; } } @@ -245,10 +214,13 @@ static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_ return false; } -/********* Functions for instanced panels. ***********/ +/** \} */ -static Panel *UI_panel_add_instanced_ex(ScrArea *area, - ARegion *region, +/* -------------------------------------------------------------------- */ +/** \name Functions for Instanced Panels + * \{ */ + +static Panel *UI_panel_add_instanced_ex(ARegion *region, ListBase *panels, PanelType *panel_type, int list_index, @@ -265,7 +237,7 @@ static Panel *UI_panel_add_instanced_ex(ScrArea *area, * function to create them, as UI_panel_begin does other things we don't need to do. */ LISTBASE_FOREACH (LinkData *, child, &panel_type->children) { PanelType *child_type = child->data; - UI_panel_add_instanced_ex(area, region, &panel->children, child_type, list_index, custom_data); + UI_panel_add_instanced_ex(region, &panel->children, child_type, list_index, custom_data); } /* Make sure the panel is added to the end of the display-order as well. This is needed for @@ -288,14 +260,10 @@ static Panel *UI_panel_add_instanced_ex(ScrArea *area, /** * Called in situations where panels need to be added dynamically rather than having only one panel - * corresponding to each PanelType. + * corresponding to each #PanelType. */ -Panel *UI_panel_add_instanced(ScrArea *area, - ARegion *region, - ListBase *panels, - char *panel_idname, - int list_index, - PointerRNA *custom_data) +Panel *UI_panel_add_instanced( + ARegion *region, ListBase *panels, char *panel_idname, int list_index, PointerRNA *custom_data) { ARegionType *region_type = region->type; @@ -307,12 +275,12 @@ Panel *UI_panel_add_instanced(ScrArea *area, return NULL; } - return UI_panel_add_instanced_ex(area, region, panels, panel_type, list_index, custom_data); + return UI_panel_add_instanced_ex(region, panels, panel_type, list_index, custom_data); } /** - * Find a unique key to append to the idname for the lookup to the panel's #uiBlock. Needed for - * instanced panels, where there can be multiple with the same type and idname. + * Find a unique key to append to the #PanelTyype.idname for the lookup to the panel's #uiBlock. + * Needed for instanced panels, where there can be multiple with the same type and identifier. */ void UI_list_panel_unique_str(Panel *panel, char *r_name) { @@ -399,7 +367,7 @@ void UI_panels_free_instanced(const bContext *C, ARegion *region) * don't match in any way. * * \param data: The list of data to check against the instanced panels. - * \param panel_idname_func: Function to find the panel type idname for each item in the data list. + * \param panel_idname_func: Function to find the #PanelType.idname for each item in the data list. * For a readability and generality, this lookup happens separately for each type of panel list. */ bool UI_panel_list_matches_data(ARegion *region, @@ -529,14 +497,10 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr */ static bool panel_set_expand_from_list_data_recursive(Panel *panel, short flag, short *flag_index) { - bool open = (flag & (1 << *flag_index)); - bool changed = (open == (bool)(panel->flag & PNL_CLOSEDY)); - if (open) { - panel->flag &= ~PNL_CLOSEDY; - } - else { - panel->flag |= PNL_CLOSEDY; - } + const bool open = (flag & (1 << *flag_index)); + bool changed = (open == (bool)(panel->flag & PNL_CLOSED)); + SET_FLAG_FROM_TEST(panel->flag, !open, PNL_CLOSED); + LISTBASE_FOREACH (Panel *, child, &panel->children) { *flag_index = *flag_index + 1; changed |= panel_set_expand_from_list_data_recursive(child, flag, flag_index); @@ -558,7 +522,7 @@ void UI_panel_set_expand_from_list_data(const bContext *C, Panel *panel) return; } - short expand_flag = panel->type->get_list_data_expand_flag(C, panel); + const short expand_flag = panel->type->get_list_data_expand_flag(C, panel); short flag_index = 0; /* Start panel animation if the open state was changed. */ @@ -572,13 +536,9 @@ void UI_panel_set_expand_from_list_data(const bContext *C, Panel *panel) */ static void get_panel_expand_flag(Panel *panel, short *flag, short *flag_index) { - bool open = !(panel->flag & PNL_CLOSEDY); - if (open) { - *flag |= (1 << *flag_index); - } - else { - *flag &= ~(1 << *flag_index); - } + const bool open = !(panel->flag & PNL_CLOSED); + SET_FLAG_FROM_TEST(*flag, open, (1 << *flag_index)); + LISTBASE_FOREACH (Panel *, child, &panel->children) { *flag_index = *flag_index + 1; get_panel_expand_flag(child, flag, flag_index); @@ -586,14 +546,14 @@ static void get_panel_expand_flag(Panel *panel, short *flag, short *flag_index) } /** - * Call the callback to store the panel and subpanel expansion settings in the list item that + * Call the callback to store the panel and sub-panel expansion settings in the list item that * corresponds to this panel. * * \note This needs to iterate through all of the regions panels because the panel with changed - * expansion could have been the subpanel of a instanced panel, meaning it might not know + * expansion could have been the sub-panel of a instanced panel, meaning it might not know * which list item it corresponds to. */ -static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region) +static void set_panels_list_data_expand_flag(const bContext *C, const ARegion *region) { LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { PanelType *panel_type = panel->type; @@ -613,7 +573,11 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region) } } -/****************************** panels ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Panels + * \{ */ /** * Set flag state for a panel and its sub-panels. @@ -622,7 +586,7 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region) */ static bool panel_set_flag_recursive(Panel *panel, int flag, bool value) { - short flag_original = panel->flag; + const short flag_original = panel->flag; SET_FLAG_FROM_TEST(panel->flag, value, flag); @@ -635,14 +599,10 @@ static bool panel_set_flag_recursive(Panel *panel, int flag, bool value) return changed; } -static void panels_collapse_all(const bContext *C, - ScrArea *area, - ARegion *region, - const Panel *from_panel) +static void panels_collapse_all(ARegion *region, const Panel *from_panel) { const bool has_category_tabs = UI_panel_category_is_visible(region); const char *category = has_category_tabs ? UI_panel_category_active_get(region, false) : NULL; - const int flag = ((panel_aligned(area, region) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY); const PanelType *from_pt = from_panel->type; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { @@ -653,13 +613,11 @@ static void panels_collapse_all(const bContext *C, if (!pt->context[0] || !from_pt->context[0] || STREQ(pt->context, from_pt->context)) { if ((panel->flag & PNL_PIN) || !category || !pt->category[0] || STREQ(pt->category, category)) { - panel->flag &= ~PNL_CLOSED; - panel->flag |= flag; + panel->flag |= PNL_CLOSED; } } } } - set_panels_list_data_expand_flag(C, region); } static bool panel_type_context_poll(ARegion *region, @@ -692,19 +650,13 @@ Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt) /** * \note \a panel should be return value from #UI_panel_find_by_type and can be NULL. */ -Panel *UI_panel_begin(ScrArea *area, - ARegion *region, - ListBase *lb, - uiBlock *block, - PanelType *pt, - Panel *panel, - bool *r_open) +Panel *UI_panel_begin( + ARegion *region, ListBase *lb, uiBlock *block, PanelType *pt, Panel *panel, bool *r_open) { Panel *panel_last; const char *drawname = CTX_IFACE_(pt->translation_context, pt->label); const char *idname = pt->idname; const bool newpanel = (panel == NULL); - int align = panel_aligned(area, region); if (!newpanel) { panel->type = pt; @@ -716,12 +668,7 @@ Panel *UI_panel_begin(ScrArea *area, BLI_strncpy(panel->panelname, idname, sizeof(panel->panelname)); if (pt->flag & PNL_DEFAULT_CLOSED) { - if (align == BUT_VERTICAL) { - panel->flag |= PNL_CLOSEDY; - } - else { - panel->flag |= PNL_CLOSEDX; - } + panel->flag |= PNL_CLOSED; } panel->ofsx = 0; @@ -790,11 +737,10 @@ Panel *UI_panel_begin(ScrArea *area, return panel; } -static float panel_region_offset_x_get(const ARegion *region, int align) +static float panel_region_offset_x_get(const ARegion *region) { if (UI_panel_category_is_visible(region)) { - if (align == BUT_VERTICAL && - (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) != RGN_ALIGN_RIGHT)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) != RGN_ALIGN_RIGHT) { return UI_PANEL_CATEGORY_MARGIN_WIDTH; } } @@ -802,8 +748,7 @@ static float panel_region_offset_x_get(const ARegion *region, int align) return 0; } -void UI_panel_end( - const ScrArea *area, const ARegion *region, uiBlock *block, int width, int height, bool open) +void UI_panel_end(const ARegion *region, uiBlock *block, int width, int height, bool open) { Panel *panel = block->panel; @@ -826,8 +771,8 @@ void UI_panel_end( panel->sizey = height; } else { - int old_sizex = panel->sizex, old_sizey = panel->sizey; - int old_region_ofsx = panel->runtime.region_ofsx; + const int old_sizex = panel->sizex, old_sizey = panel->sizey; + const int old_region_ofsx = panel->runtime.region_ofsx; /* update width/height if non-zero */ if (width != 0) { @@ -843,8 +788,7 @@ void UI_panel_end( panel->ofsy += old_sizey - panel->sizey; } - int align = panel_aligned(area, region); - panel->runtime.region_ofsx = panel_region_offset_x_get(region, align); + panel->runtime.region_ofsx = panel_region_offset_x_get(region); if (old_region_ofsx != panel->runtime.region_ofsx) { panel->runtime_flag |= PNL_ANIM_ALIGN; } @@ -858,7 +802,7 @@ static void ui_offset_panel_block(uiBlock *block) /* compute bounds and offset */ ui_block_bounds_calc(block); - int ofsy = block->panel->sizey - style->panelspace; + const int ofsy = block->panel->sizey - style->panelspace; LISTBASE_FOREACH (uiBut *, but, &block->buttons) { but->rect.ymin += ofsy; @@ -870,14 +814,18 @@ static void ui_offset_panel_block(uiBlock *block) block->rect.xmin = block->rect.ymin = 0.0; } -/**************************** drawing *******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Drawing + * \{ */ /* triangle 'icon' for panel header */ void UI_draw_icon_tri(float x, float y, char dir, const float color[4]) { - float f3 = 0.05 * U.widget_unit; - float f5 = 0.15 * U.widget_unit; - float f7 = 0.25 * U.widget_unit; + const float f3 = 0.05 * U.widget_unit; + const float f5 = 0.15 * U.widget_unit; + const float f7 = 0.25 * U.widget_unit; if (dir == 'h') { UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color); @@ -906,57 +854,46 @@ void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y) } } -static void ui_draw_aligned_panel_header( - uiStyle *style, uiBlock *block, const rcti *rect, char dir, const bool show_background) +static void ui_draw_aligned_panel_header(const uiStyle *style, + const uiBlock *block, + const rcti *rect, + const bool show_background) { - Panel *panel = block->panel; - rcti hrect; - int pnl_icons; - const char *activename = panel->drawname; + const Panel *panel = block->panel; const bool is_subpanel = (panel->type && panel->type->parent); - uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle; - uchar col_title[4]; + const uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle; /* + 0.001f to avoid flirting with float inaccuracy */ - pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f; + const int pnl_icons = (panel->labelofs + (1.1f * PNL_ICON)) / block->aspect + 0.001f; /* draw text label */ + uchar col_title[4]; panel_title_color_get(show_background, col_title); col_title[3] = 255; - hrect = *rect; - if (dir == 'h') { - hrect.xmin = rect->xmin + pnl_icons; - hrect.ymin -= 2.0f / block->aspect; - UI_fontstyle_draw(fontstyle, - &hrect, - activename, - col_title, - &(struct uiFontStyleDraw_Params){ - .align = UI_STYLE_TEXT_LEFT, - }); - } - else { - /* ignore 'pnl_icons', otherwise the text gets offset horizontally - * + 0.001f to avoid flirting with float inaccuracy - */ - hrect.xmin = rect->xmin + (PNL_ICON + 5) / block->aspect + 0.001f; - UI_fontstyle_draw_rotated(fontstyle, &hrect, activename, col_title); - } + rcti hrect = *rect; + hrect.xmin = rect->xmin + pnl_icons; + hrect.ymin -= 2.0f / block->aspect; + UI_fontstyle_draw(fontstyle, + &hrect, + panel->drawname, + col_title, + &(struct uiFontStyleDraw_Params){ + .align = UI_STYLE_TEXT_LEFT, + }); } -/* panel integrated in buttonswindow, tool/property lists etc */ -void ui_draw_aligned_panel(uiStyle *style, - uiBlock *block, +/** + * Panel integrated in buttons-window, tool/property lists etc + */ +void ui_draw_aligned_panel(const uiStyle *style, + const uiBlock *block, const rcti *rect, const bool show_pin, const bool show_background) { - Panel *panel = block->panel; - rctf itemrect; + const Panel *panel = block->panel; float color[4]; - const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false; - const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false; const bool is_subpanel = (panel->type && panel->type->parent); const bool show_drag = (!is_subpanel && /* FIXME(campbell): currently no background means floating panel which @@ -972,7 +909,8 @@ void ui_draw_aligned_panel(uiStyle *style, box_wcol = &btheme->tui.wcol_box; } - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (panel->type && (panel->type->flag & PNL_NO_HEADER)) { if (show_background) { @@ -984,7 +922,7 @@ void ui_draw_aligned_panel(uiStyle *style, return; } - /* Calculate header rect with + 0.001f to prevent flicker due to float inaccuracy */ + /* Calculate header rectangle with + 0.001f to prevent flicker due to float inaccuracy. */ rcti headrect = { rect->xmin, rect->xmax, rect->ymax, rect->ymax + floor(PNL_HEADER / block->aspect + 0.001f)}; @@ -993,14 +931,14 @@ void ui_draw_aligned_panel(uiStyle *style, /* Expand the top a tiny bit to give header buttons equal size above and below. */ rcti box_rect = {rect->xmin, rect->xmax, - (is_closed_x || is_closed_y) ? headrect.ymin : rect->ymin, + (panel->flag & PNL_CLOSED) ? headrect.ymin : rect->ymin, headrect.ymax + U.pixelsize}; ui_draw_box_opaque(&box_rect, UI_CNR_ALL); - /* Mimick the border between aligned box widgets for the bottom of the header. */ - if (!(is_closed_x || is_closed_y)) { + /* Mimic the border between aligned box widgets for the bottom of the header. */ + if (!(panel->flag & PNL_CLOSED)) { immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ubv(box_wcol->outline); immRectf(pos, rect->xmin, headrect.ymin - U.pixelsize, rect->xmax, headrect.ymin); @@ -1013,49 +951,43 @@ void ui_draw_aligned_panel(uiStyle *style, rect->xmax, headrect.ymin - U.pixelsize - 1); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } } /* Draw the header backdrop. */ if (show_background && !is_subpanel && !draw_box_style) { - float minx = rect->xmin; - float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax; - float y = headrect.ymax; + const float minx = rect->xmin; + const float y = headrect.ymax; immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* draw with background color */ immUniformThemeColor(TH_PANEL_HEADER); - immRectf(pos, minx, headrect.ymin, maxx, y); + immRectf(pos, minx, headrect.ymin, rect->xmax, y); immBegin(GPU_PRIM_LINES, 4); immVertex2f(pos, minx, y); - immVertex2f(pos, maxx, y); + immVertex2f(pos, rect->xmax, y); immVertex2f(pos, minx, y); - immVertex2f(pos, maxx, y); + immVertex2f(pos, rect->xmax, y); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } -/* draw optional pin icon */ -#ifdef USE_PIN_HIDDEN - if (show_pin && (block->panel->flag & PNL_PIN)) -#else - if (show_pin) -#endif - { + /* draw optional pin icon */ + if (show_pin && (block->panel->flag & PNL_PIN)) { uchar col_title[4]; panel_title_color_get(show_background, col_title); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw_ex(headrect.xmax - ((PNL_ICON * 2.2f) / block->aspect), headrect.ymin + (5.0f / block->aspect), (panel->flag & PNL_PIN) ? ICON_PINNED : ICON_UNPINNED, @@ -1064,7 +996,7 @@ void ui_draw_aligned_panel(uiStyle *style, 0.0f, col_title, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* horizontal title */ @@ -1072,45 +1004,35 @@ void ui_draw_aligned_panel(uiStyle *style, if (is_subpanel) { titlerect.xmin += (0.7f * UI_UNIT_X) / block->aspect + 0.001f; } - if (is_closed_x == false) { - ui_draw_aligned_panel_header(style, block, &titlerect, 'h', show_background); + ui_draw_aligned_panel_header(style, block, &titlerect, show_background); - if (show_drag) { - /* itemrect smaller */ - const float scale = 0.7; - itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X); - itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect); - itemrect.ymin = headrect.ymin; - itemrect.ymax = headrect.ymax; - BLI_rctf_scale(&itemrect, scale); + if (show_drag) { + /* Make `itemrect` smaller. */ + const float scale = 0.7; + rctf itemrect; + itemrect.xmax = headrect.xmax - (0.2f * UI_UNIT_X); + itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect); + itemrect.ymin = headrect.ymin; + itemrect.ymax = headrect.ymax; + BLI_rctf_scale(&itemrect, scale); - GPU_matrix_push(); - GPU_matrix_translate_2f(itemrect.xmin, itemrect.ymin); + GPU_matrix_push(); + GPU_matrix_translate_2f(itemrect.xmin, itemrect.ymin); - const int col_tint = 84; - float col_high[4], col_dark[4]; - UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high); - UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark); + const int col_tint = 84; + float col_high[4], col_dark[4]; + UI_GetThemeColorShade4fv(TH_PANEL_HEADER, col_tint, col_high); + UI_GetThemeColorShade4fv(TH_PANEL_BACK, -col_tint, col_dark); - GPUBatch *batch = GPU_batch_preset_panel_drag_widget( - U.pixelsize, col_high, col_dark, BLI_rcti_size_y(&headrect) * scale); - GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_FLAT_COLOR); - GPU_batch_draw(batch); - GPU_matrix_pop(); - } + GPUBatch *batch = GPU_batch_preset_panel_drag_widget( + U.pixelsize, col_high, col_dark, BLI_rcti_size_y(&headrect) * scale); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_FLAT_COLOR); + GPU_batch_draw(batch); + GPU_matrix_pop(); } /* Draw panel backdrop. */ - if (is_closed_y) { - /* skip */ - } - else if (is_closed_x) { - /* draw vertical title */ - ui_draw_aligned_panel_header(style, block, &headrect, 'v', show_background); - pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - } - /* an open panel */ - else { + if (!(panel->flag & PNL_CLOSED)) { /* in some occasions, draw a border */ if (panel->flag & PNL_SELECT && !is_subpanel) { float radius; @@ -1134,7 +1056,7 @@ void ui_draw_aligned_panel(uiStyle *style, } immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Draw panel backdrop if it wasn't already been drawn by the single opaque round box earlier. * Note: Sub-panels blend with panels, so they can't be opaque. */ @@ -1168,28 +1090,21 @@ void ui_draw_aligned_panel(uiStyle *style, immUnbindProgram(); } - uchar col_title[4]; - panel_title_color_get(show_background, col_title); - /* draw collapse icon */ - - /* itemrect smaller */ - itemrect.xmin = titlerect.xmin; - itemrect.xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect); - itemrect.ymin = titlerect.ymin; - itemrect.ymax = titlerect.ymax; - - BLI_rctf_scale(&itemrect, 0.25f); - { + rctf itemrect = {.xmin = titlerect.xmin, + .xmax = itemrect.xmin + BLI_rcti_size_y(&titlerect), + .ymin = titlerect.ymin, + .ymax = titlerect.ymax}; + BLI_rctf_scale(&itemrect, 0.25f); + + uchar col_title[4]; + panel_title_color_get(show_background, col_title); float tria_color[4]; rgb_uchar_to_float(tria_color, col_title); tria_color[3] = 1.0f; - if (is_closed_y) { - ui_draw_anti_tria_rect(&itemrect, 'h', tria_color); - } - else if (is_closed_x) { + if (panel->flag & PNL_CLOSED) { ui_draw_anti_tria_rect(&itemrect, 'h', tria_color); } else { @@ -1198,17 +1113,434 @@ void ui_draw_aligned_panel(uiStyle *style, } } -/************************** panel alignment *************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Category Drawing (Tabs) + * \{ */ -static int get_panel_header(const Panel *panel) +static void imm_buf_append( + float vbuf[][2], uchar cbuf[][3], float x, float y, const uchar col[3], int *index) { - if (panel->type && (panel->type->flag & PNL_NO_HEADER)) { - return 0; + ARRAY_SET_ITEMS(vbuf[*index], x, y); + ARRAY_SET_ITEMS(cbuf[*index], UNPACK3(col)); + (*index)++; +} + +/* based on UI_draw_roundbox, check on making a version which allows us to skip some sides */ +static void ui_panel_category_draw_tab(bool filled, + float minx, + float miny, + float maxx, + float maxy, + float rad, + const int roundboxtype, + const bool use_highlight, + const bool use_shadow, + const bool use_flip_x, + const uchar highlight_fade[3], + const uchar col[3]) +{ + float vec[4][2] = {{0.195, 0.02}, {0.55, 0.169}, {0.831, 0.45}, {0.98, 0.805}}; + + /* Multiply `vec` by radius. */ + for (int a = 0; a < 4; a++) { + mul_v2_fl(vec[a], rad); + } + + uint vert_len = 0; + if (use_highlight) { + vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 6 : 1; + vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 6 : 1; + } + if (use_highlight && !use_shadow) { + vert_len++; + } + else { + vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 6 : 1; + vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 6 : 1; + } + /* Maximum size. */ + float vbuf[24][2]; + uchar cbuf[24][3]; + int buf_index = 0; + + /* start with corner right-top */ + if (use_highlight) { + if (roundboxtype & UI_CNR_TOP_RIGHT) { + imm_buf_append(vbuf, cbuf, maxx, maxy - rad, col, &buf_index); + for (int a = 0; a < 4; a++) { + imm_buf_append(vbuf, cbuf, maxx - vec[a][1], maxy - rad + vec[a][0], col, &buf_index); + } + imm_buf_append(vbuf, cbuf, maxx - rad, maxy, col, &buf_index); + } + else { + imm_buf_append(vbuf, cbuf, maxx, maxy, col, &buf_index); + } + + /* corner left-top */ + if (roundboxtype & UI_CNR_TOP_LEFT) { + imm_buf_append(vbuf, cbuf, minx + rad, maxy, col, &buf_index); + for (int a = 0; a < 4; a++) { + imm_buf_append(vbuf, cbuf, minx + rad - vec[a][0], maxy - vec[a][1], col, &buf_index); + } + imm_buf_append(vbuf, cbuf, minx, maxy - rad, col, &buf_index); + } + else { + imm_buf_append(vbuf, cbuf, minx, maxy, col, &buf_index); + } + } + + if (use_highlight && !use_shadow) { + imm_buf_append( + vbuf, cbuf, minx, miny + rad, highlight_fade ? col : highlight_fade, &buf_index); + } + else { + /* corner left-bottom */ + if (roundboxtype & UI_CNR_BOTTOM_LEFT) { + imm_buf_append(vbuf, cbuf, minx, miny + rad, col, &buf_index); + for (int a = 0; a < 4; a++) { + imm_buf_append(vbuf, cbuf, minx + vec[a][1], miny + rad - vec[a][0], col, &buf_index); + } + imm_buf_append(vbuf, cbuf, minx + rad, miny, col, &buf_index); + } + else { + imm_buf_append(vbuf, cbuf, minx, miny, col, &buf_index); + } + + /* corner right-bottom */ + if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { + imm_buf_append(vbuf, cbuf, maxx - rad, miny, col, &buf_index); + for (int a = 0; a < 4; a++) { + imm_buf_append(vbuf, cbuf, maxx - rad + vec[a][0], miny + vec[a][1], col, &buf_index); + } + imm_buf_append(vbuf, cbuf, maxx, miny + rad, col, &buf_index); + } + else { + imm_buf_append(vbuf, cbuf, maxx, miny, col, &buf_index); + } + } + + if (use_flip_x) { + const float midx = (minx + maxx) / 2.0f; + for (int i = 0; i < buf_index; i++) { + vbuf[i][0] = midx - (vbuf[i][0] - midx); + } + } + + GPUVertFormat *format = immVertexFormat(); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + uint color = GPU_vertformat_attr_add( + format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len); + for (int i = 0; i < buf_index; i++) { + immAttr3ubv(color, cbuf[i]); + immVertex2fv(pos, vbuf[i]); + } + immEnd(); + immUnbindProgram(); +} + +/** + * Draw vertical tabs on the left side of the region, + * one tab per category. + */ +void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) +{ + /* no tab outlines for */ + // #define USE_FLAT_INACTIVE + const bool is_left = RGN_ALIGN_ENUM_FROM_MASK(region->alignment != RGN_ALIGN_RIGHT); + View2D *v2d = ®ion->v2d; + const uiStyle *style = UI_style_get(); + const uiFontStyle *fstyle = &style->widget; + const int fontid = fstyle->uifont_id; + short fstyle_points = fstyle->points; + const float aspect = ((uiBlock *)region->uiblocks.first)->aspect; + const float zoom = 1.0f / aspect; + const int px = max_ii(1, round_fl_to_int(U.pixelsize)); + const int px_x_sign = is_left ? px : -px; + const int category_tabs_width = round_fl_to_int(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom); + const float dpi_fac = UI_DPI_FAC; + /* padding of tabs around text */ + const int tab_v_pad_text = round_fl_to_int((2 + ((px * 3) * dpi_fac)) * zoom); + /* padding between tabs */ + const int tab_v_pad = round_fl_to_int((4 + (2 * px * dpi_fac)) * zoom); + const float tab_curve_radius = ((px * 3) * dpi_fac) * zoom; + /* We flip the tab drawing, so always use these flags. */ + const int roundboxtype = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; + bool is_alpha; + bool do_scaletabs = false; +#ifdef USE_FLAT_INACTIVE + bool is_active_prev = false; +#endif + float scaletabs = 1.0f; + /* same for all tabs */ + /* intentionally don't scale by 'px' */ + const int rct_xmin = is_left ? v2d->mask.xmin + 3 : (v2d->mask.xmax - category_tabs_width); + const int rct_xmax = is_left ? v2d->mask.xmin + category_tabs_width : (v2d->mask.xmax - 3); + const int text_v_ofs = (rct_xmax - rct_xmin) * 0.3f; + + int y_ofs = tab_v_pad; + + /* Primary theme colors */ + uchar theme_col_back[4]; + uchar theme_col_text[3]; + uchar theme_col_text_hi[3]; + + /* Tab colors */ + uchar theme_col_tab_bg[4]; + uchar theme_col_tab_active[3]; + uchar theme_col_tab_inactive[3]; + + /* Secondary theme colors */ + uchar theme_col_tab_outline[3]; + uchar theme_col_tab_divider[3]; /* line that divides tabs from the main region */ + uchar theme_col_tab_highlight[3]; + uchar theme_col_tab_highlight_inactive[3]; + + UI_GetThemeColor4ubv(TH_BACK, theme_col_back); + UI_GetThemeColor3ubv(TH_TEXT, theme_col_text); + UI_GetThemeColor3ubv(TH_TEXT_HI, theme_col_text_hi); + + UI_GetThemeColor4ubv(TH_TAB_BACK, theme_col_tab_bg); + UI_GetThemeColor3ubv(TH_TAB_ACTIVE, theme_col_tab_active); + UI_GetThemeColor3ubv(TH_TAB_INACTIVE, theme_col_tab_inactive); + UI_GetThemeColor3ubv(TH_TAB_OUTLINE, theme_col_tab_outline); + + interp_v3_v3v3_uchar(theme_col_tab_divider, theme_col_back, theme_col_tab_outline, 0.3f); + interp_v3_v3v3_uchar(theme_col_tab_highlight, theme_col_back, theme_col_text_hi, 0.2f); + interp_v3_v3v3_uchar( + theme_col_tab_highlight_inactive, theme_col_tab_inactive, theme_col_text_hi, 0.12f); + + is_alpha = (region->overlap && (theme_col_back[3] != 255)); + + if (fstyle->kerning == 1) { + BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); + } + + BLF_enable(fontid, BLF_ROTATION); + BLF_rotation(fontid, M_PI_2); + // UI_fontstyle_set(&style->widget); + ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f)); + BLF_size(fontid, fstyle_points, U.dpi); + + /* Check the region type supports categories to avoid an assert + * for showing 3D view panels in the properties space. */ + if ((1 << region->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) { + BLI_assert(UI_panel_category_is_visible(region)); + } + + /* Calculate tab rectangle and check if we need to scale down. */ + LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { + + rcti *rct = &pc_dyn->rect; + const char *category_id = pc_dyn->idname; + const char *category_id_draw = IFACE_(category_id); + const int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX); + + rct->xmin = rct_xmin; + rct->xmax = rct_xmax; + + rct->ymin = v2d->mask.ymax - (y_ofs + category_width + (tab_v_pad_text * 2)); + rct->ymax = v2d->mask.ymax - (y_ofs); + + y_ofs += category_width + tab_v_pad + (tab_v_pad_text * 2); + } + + if (y_ofs > BLI_rcti_size_y(&v2d->mask)) { + scaletabs = (float)BLI_rcti_size_y(&v2d->mask) / (float)y_ofs; + + LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { + rcti *rct = &pc_dyn->rect; + rct->ymin = ((rct->ymin - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax; + rct->ymax = ((rct->ymax - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax; + } + + do_scaletabs = true; + } + + /* begin drawing */ + GPU_line_smooth(true); + + uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + /* draw the background */ + if (is_alpha) { + GPU_blend(GPU_BLEND_ALPHA); + immUniformColor4ubv(theme_col_tab_bg); } + else { + immUniformColor3ubv(theme_col_tab_bg); + } + + if (is_left) { + immRecti( + pos, v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax); + } + else { + immRecti( + pos, v2d->mask.xmax - category_tabs_width, v2d->mask.ymin, v2d->mask.xmax, v2d->mask.ymax); + } + + if (is_alpha) { + GPU_blend(GPU_BLEND_NONE); + } + + immUnbindProgram(); + + const int divider_xmin = is_left ? (v2d->mask.xmin + (category_tabs_width - px)) : + (v2d->mask.xmax - category_tabs_width) + px; + const int divider_xmax = is_left ? (v2d->mask.xmin + category_tabs_width) : + (v2d->mask.xmax - (category_tabs_width + px)) + px; + + LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { + const rcti *rct = &pc_dyn->rect; + const char *category_id = pc_dyn->idname; + const char *category_id_draw = IFACE_(category_id); + const int category_width = BLI_rcti_size_y(rct) - (tab_v_pad_text * 2); + size_t category_draw_len = BLF_DRAW_STR_DUMMY_MAX; +#if 0 + int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX); +#endif + + const bool is_active = STREQ(category_id, category_id_active); + + GPU_blend(GPU_BLEND_ALPHA); + +#ifdef USE_FLAT_INACTIVE + if (is_active) +#endif + { + const bool use_flip_x = !is_left; + ui_panel_category_draw_tab(true, + rct->xmin, + rct->ymin, + rct->xmax, + rct->ymax, + tab_curve_radius - px, + roundboxtype, + true, + true, + use_flip_x, + NULL, + is_active ? theme_col_tab_active : theme_col_tab_inactive); + + /* Tab outline */ + ui_panel_category_draw_tab(false, + rct->xmin - px_x_sign, + rct->ymin - px, + rct->xmax - px_x_sign, + rct->ymax + px, + tab_curve_radius, + roundboxtype, + true, + true, + use_flip_x, + NULL, + theme_col_tab_outline); + + /* Tab highlight (3d look) */ + ui_panel_category_draw_tab(false, + rct->xmin, + rct->ymin, + rct->xmax, + rct->ymax, + tab_curve_radius, + roundboxtype, + true, + false, + use_flip_x, + is_active ? theme_col_back : theme_col_tab_inactive, + is_active ? theme_col_tab_highlight : + theme_col_tab_highlight_inactive); + } - return PNL_HEADER; + /* Tab black-line. */ + if (!is_active) { + pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + immUniformColor3ubv(theme_col_tab_divider); + immRecti(pos, divider_xmin, rct->ymin - tab_v_pad, divider_xmax, rct->ymax + tab_v_pad); + immUnbindProgram(); + } + + if (do_scaletabs) { + category_draw_len = BLF_width_to_strlen( + fontid, category_id_draw, category_draw_len, category_width, NULL); + } + + BLF_position(fontid, rct->xmax - text_v_ofs, rct->ymin + tab_v_pad_text, 0.0f); + + /* Tab titles. */ + + /* Draw white shadow to give text more depth. */ + BLF_color3ubv(fontid, theme_col_text); + + /* Main tab title. */ + BLF_draw(fontid, category_id_draw, category_draw_len); + + GPU_blend(GPU_BLEND_NONE); + + /* Tab black-line remaining (last tab). */ + pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + if (pc_dyn->prev == NULL) { + immUniformColor3ubv(theme_col_tab_divider); + immRecti(pos, divider_xmin, rct->ymax + px, divider_xmax, v2d->mask.ymax); + } + if (pc_dyn->next == NULL) { + immUniformColor3ubv(theme_col_tab_divider); + immRecti(pos, divider_xmin, 0, divider_xmax, rct->ymin); + } + +#ifdef USE_FLAT_INACTIVE + /* Draw line between inactive tabs. */ + if (is_active == false && is_active_prev == false && pc_dyn->prev) { + immUniformColor3ubv(theme_col_tab_divider); + immRecti(pos, + v2d->mask.xmin + (category_tabs_width / 5), + rct->ymax + px, + (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5), + rct->ymax + (px * 3)); + } + + is_active_prev = is_active; +#endif + immUnbindProgram(); + + /* not essential, but allows events to be handled right up until the region edge [#38171] */ + if (is_left) { + pc_dyn->rect.xmin = v2d->mask.xmin; + } + else { + pc_dyn->rect.xmax = v2d->mask.xmax; + } + } + + GPU_line_smooth(false); + + BLF_disable(fontid, BLF_ROTATION); + + if (fstyle->kerning == 1) { + BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); + } + +#undef USE_FLAT_INACTIVE } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Panel Alignment + * \{ */ + static int get_panel_size_y(const Panel *panel) { if (panel->type && (panel->type->flag & PNL_NO_HEADER)) { @@ -1220,7 +1552,7 @@ static int get_panel_size_y(const Panel *panel) static int get_panel_real_size_y(const Panel *panel) { - int sizey = (panel->flag & PNL_CLOSED) ? 0 : panel->sizey; + const int sizey = (panel->flag & PNL_CLOSED) ? 0 : panel->sizey; if (panel->type && (panel->type->flag & PNL_NO_HEADER)) { return sizey; @@ -1234,24 +1566,18 @@ int UI_panel_size_y(const Panel *panel) return get_panel_real_size_y(panel); } -/* this function is needed because uiBlock and Panel itself don't - * change sizey or location when closed */ +/** + * This function is needed because #uiBlock and Panel itself don't + * change #Panel.sizey or location when closed. + */ static int get_panel_real_ofsy(Panel *panel) { - if (panel->flag & PNL_CLOSEDY) { + if (panel->flag & PNL_CLOSED) { return panel->ofsy + panel->sizey; } return panel->ofsy; } -static int get_panel_real_ofsx(Panel *panel) -{ - if (panel->flag & PNL_CLOSEDX) { - return panel->ofsx + get_panel_header(panel); - } - return panel->ofsx + panel->sizex; -} - bool UI_panel_is_dragging(const struct Panel *panel) { uiHandlePanelData *data = panel->activedata; @@ -1264,32 +1590,12 @@ bool UI_panel_is_dragging(const struct Panel *panel) /** * \note about sorting; - * the sortorder has a lower value for new panels being added. + * the #Panel.sortorder has a lower value for new panels being added. * however, that only works to insert a single panel, when more new panels get * added the coordinates of existing panels and the previously stored to-be-inserted * panels do not match for sorting */ -static int find_leftmost_panel(const void *a1, const void *a2) -{ - const PanelSort *ps1 = a1, *ps2 = a2; - - if (ps1->panel->ofsx > ps2->panel->ofsx) { - return 1; - } - if (ps1->panel->ofsx < ps2->panel->ofsx) { - return -1; - } - if (ps1->panel->sortorder > ps2->panel->sortorder) { - return 1; - } - if (ps1->panel->sortorder < ps2->panel->sortorder) { - return -1; - } - - return 0; -} - static int find_highest_panel(const void *a1, const void *a2) { const PanelSort *ps1 = a1, *ps2 = a2; @@ -1297,7 +1603,7 @@ static int find_highest_panel(const void *a1, const void *a2) /* stick uppermost header-less panels to the top of the region - * prevent them from being sorted (multiple header-less panels have to be sorted though) */ if (ps1->panel->type->flag & PNL_NO_HEADER && ps2->panel->type->flag & PNL_NO_HEADER) { - /* skip and check for ofs and sortorder below */ + /* Skip and check for `ofsy` and #Panel.sortorder below. */ } if (ps1->panel->type->flag & PNL_NO_HEADER) { return -1; @@ -1356,14 +1662,12 @@ static void align_sub_panels(Panel *panel) /* this doesn't draw */ /* returns 1 when it did something */ -static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, const bool drag) +static bool uiAlignPanelStep(ARegion *region, const float fac, const bool drag) { - PanelSort *ps, *panelsort, *psnext; - int a, tot = 0; - bool done; - int align = panel_aligned(area, region); + int i; /* count active, not tabbed panels */ + int tot = 0; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PNL_ACTIVE) { tot++; @@ -1374,22 +1678,10 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co return 0; } - /* extra; change close direction? */ - LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { - if (panel->runtime_flag & PNL_ACTIVE) { - if ((panel->flag & PNL_CLOSEDX) && (align == BUT_VERTICAL)) { - panel->flag ^= PNL_CLOSED; - } - else if ((panel->flag & PNL_CLOSEDY) && (align == BUT_HORIZONTAL)) { - panel->flag ^= PNL_CLOSED; - } - } - } - /* sort panels */ - panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort"); + PanelSort *panelsort = MEM_callocN(tot * sizeof(PanelSort), "panelsort"); - ps = panelsort; + PanelSort *ps = panelsort; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PNL_ACTIVE) { ps->panel = MEM_dupallocN(panel); @@ -1399,49 +1691,37 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co } if (drag) { - /* while we are dragging, we sort on location and update sortorder */ - if (align == BUT_VERTICAL) { - qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel); - } - else { - qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel); - } + /* While we are dragging, we sort on location and update #Panel.sortorder. */ + qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel); - for (ps = panelsort, a = 0; a < tot; a++, ps++) { - ps->orig->sortorder = a; + for (ps = panelsort, i = 0; i < tot; i++, ps++) { + ps->orig->sortorder = i; } } else { - /* otherwise use sortorder */ + /* Otherwise use #Panel.sortorder. */ qsort(panelsort, tot, sizeof(PanelSort), compare_panel); } - /* no smart other default start loc! this keeps switching f5/f6/etc compatible */ + /* No smart other default start location! This keeps switching f5/f6/etc compatible. */ ps = panelsort; - ps->panel->runtime.region_ofsx = panel_region_offset_x_get(region, align); + ps->panel->runtime.region_ofsx = panel_region_offset_x_get(region); ps->panel->ofsx = 0; ps->panel->ofsy = -get_panel_size_y(ps->panel); ps->panel->ofsx += ps->panel->runtime.region_ofsx; - for (a = 0; a < tot - 1; a++, ps++) { - psnext = ps + 1; + for (i = 0; i < tot - 1; i++, ps++) { + PanelSort *psnext = ps + 1; - if (align == BUT_VERTICAL) { - bool use_box = ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX; - bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX; - psnext->panel->ofsx = ps->panel->ofsx; - psnext->panel->ofsy = get_panel_real_ofsy(ps->panel) - get_panel_size_y(psnext->panel); + const bool use_box = ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX; + const bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX; + psnext->panel->ofsx = ps->panel->ofsx; + psnext->panel->ofsy = get_panel_real_ofsy(ps->panel) - get_panel_size_y(psnext->panel); - /* Extra margin for box style panels. */ - ps->panel->ofsx += (use_box) ? UI_PANEL_BOX_STYLE_MARGIN : 0.0f; - if (use_box || use_box_next) { - psnext->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN; - } - } - else { - psnext->panel->ofsx = get_panel_real_ofsx(ps->panel); - psnext->panel->ofsy = ps->panel->ofsy + get_panel_size_y(ps->panel) - - get_panel_size_y(psnext->panel); + /* Extra margin for box style panels. */ + ps->panel->ofsx += (use_box) ? UI_PANEL_BOX_STYLE_MARGIN : 0.0f; + if (use_box || use_box_next) { + psnext->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN; } } /* Extra margin for the last panel if it's a box-style panel. */ @@ -1450,16 +1730,16 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co } /* we interpolate */ - done = false; + bool changed = false; ps = panelsort; - for (a = 0; a < tot; a++, ps++) { + for (i = 0; i < tot; i++, ps++) { if ((ps->panel->flag & PNL_SELECT) == 0) { if ((ps->orig->ofsx != ps->panel->ofsx) || (ps->orig->ofsy != ps->panel->ofsy)) { ps->orig->ofsx = round_fl_to_int(fac * (float)ps->panel->ofsx + (1.0f - fac) * (float)ps->orig->ofsx); ps->orig->ofsy = round_fl_to_int(fac * (float)ps->panel->ofsy + (1.0f - fac) * (float)ps->orig->ofsy); - done = true; + changed = true; } } } @@ -1473,34 +1753,25 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co } } - /* free panelsort array */ - for (ps = panelsort, a = 0; a < tot; a++, ps++) { + /* Free `panelsort` array. */ + for (ps = panelsort, i = 0; i < tot; i++, ps++) { MEM_freeN(ps->panel); } MEM_freeN(panelsort); - return done; + return changed; } -static void ui_panels_size(ScrArea *area, ARegion *region, int *r_x, int *r_y) +static void ui_panels_size(ARegion *region, int *r_x, int *r_y) { - int align = panel_aligned(area, region); int sizex = 0; int sizey = 0; /* compute size taken up by panels, for setting in view2d */ LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PNL_ACTIVE) { - int pa_sizex, pa_sizey; - - if (align == BUT_VERTICAL) { - pa_sizex = panel->ofsx + panel->sizex; - pa_sizey = get_panel_real_ofsy(panel); - } - else { - pa_sizex = get_panel_real_ofsx(panel) + panel->sizex; - pa_sizey = panel->ofsy + get_panel_size_y(panel); - } + const int pa_sizex = panel->ofsx + panel->sizex; + const int pa_sizey = get_panel_real_ofsy(panel); sizex = max_ii(sizex, pa_sizex); sizey = min_ii(sizey, pa_sizey); @@ -1521,15 +1792,13 @@ static void ui_panels_size(ScrArea *area, ARegion *region, int *r_x, int *r_y) static void ui_do_animate(bContext *C, Panel *panel) { uiHandlePanelData *data = panel->activedata; - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - float fac; - fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME; + float fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME; fac = min_ff(sqrtf(fac), 1.0f); /* for max 1 second, interpolate positions */ - if (uiAlignPanelStep(area, region, fac, false)) { + if (uiAlignPanelStep(region, fac, false)) { ED_region_tag_redraw(region); } else { @@ -1542,8 +1811,8 @@ static void ui_do_animate(bContext *C, Panel *panel) panel_activate_state(C, panel, PANEL_STATE_EXIT); if (is_drag_drop) { - /* Note: doing this in #panel_activate_state would require removing const for context in many - * other places. */ + /* Note: doing this in #panel_activate_state would require removing `const` for context in + * many other places. */ reorder_instanced_panel_list(C, region, panel); } return; @@ -1575,7 +1844,6 @@ void UI_panels_begin(const bContext *UNUSED(C), ARegion *region) void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) { ScrArea *area = CTX_wm_area(C); - Panel *panel, *panel_first; /* offset contents */ LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { @@ -1585,17 +1853,18 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) } /* re-align, possibly with animation */ + Panel *panel; if (panels_need_realign(area, region, &panel)) { if (panel) { panel_activate_state(C, panel, PANEL_STATE_ANIMATION); } else { - uiAlignPanelStep(area, region, 1.0, false); + uiAlignPanelStep(region, 1.0, false); } } /* tag first panel */ - panel_first = NULL; + Panel *panel_first = NULL; LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { if (block->active && block->panel) { if (!panel_first || block->panel->sortorder < panel_first->sortorder) { @@ -1609,15 +1878,11 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) } /* compute size taken up by panel */ - ui_panels_size(area, region, r_x, r_y); + ui_panels_size(region, r_x, r_y); } void UI_panels_draw(const bContext *C, ARegion *region) { - if (region->alignment != RGN_ALIGN_FLOAT) { - UI_ThemeClearColor(TH_BACK); - } - /* Draw panels, selected on top. Also in reverse order, because * UI blocks are added in reverse order and we need child panels * to draw on top. */ @@ -1638,7 +1903,7 @@ void UI_panels_scale(ARegion *region, float new_width) { LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { if (block->panel) { - float fac = new_width / (float)block->panel->sizex; + const float fac = new_width / (float)block->panel->sizex; block->panel->sizex = new_width; LISTBASE_FOREACH (uiBut *, but, &block->buttons) { @@ -1649,26 +1914,28 @@ void UI_panels_scale(ARegion *region, float new_width) } } -/************************ panel dragging ****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Panel Dragging + * \{ */ #define DRAG_REGION_PAD (PNL_HEADER * 0.5) static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel) { uiHandlePanelData *data = panel->activedata; - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - short align = panel_aligned(area, region); /* Keep the drag position in the region with a small pad to keep the panel visible. */ - int x = clamp_i(event->x, region->winrct.xmin, region->winrct.xmax + DRAG_REGION_PAD); - int y = clamp_i(event->y, region->winrct.ymin, region->winrct.ymax + DRAG_REGION_PAD); + const int x = clamp_i(event->x, region->winrct.xmin, region->winrct.xmax + DRAG_REGION_PAD); + const int y = clamp_i(event->y, region->winrct.ymin, region->winrct.ymax + DRAG_REGION_PAD); float dx = (float)(x - data->startx); float dy = (float)(y - data->starty); /* Adjust for region zoom. */ - dx *= (float)BLI_rctf_size_x(®ion->v2d.cur) / (float)BLI_rcti_size_x(®ion->winrct); - dy *= (float)BLI_rctf_size_y(®ion->v2d.cur) / (float)BLI_rcti_size_y(®ion->winrct); + dx *= BLI_rctf_size_x(®ion->v2d.cur) / (float)BLI_rcti_size_x(®ion->winrct); + dy *= BLI_rctf_size_y(®ion->v2d.cur) / (float)BLI_rcti_size_y(®ion->winrct); if (data->state == PANEL_STATE_DRAG_SCALE) { panel->sizex = MAX2(data->startsizex + dx, UI_PANEL_MINX); @@ -1690,43 +1957,38 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel) panel->ofsx = data->startofsx + round_fl_to_int(dx); panel->ofsy = data->startofsy + round_fl_to_int(dy); - if (align) { - uiAlignPanelStep(area, region, 0.2f, true); - } + uiAlignPanelStep(region, 0.2f, true); } ED_region_tag_redraw(region); } #undef DRAG_REGION_PAD -/******************* region level panel interaction *****************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Region Level Panel Interaction + * \{ */ static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block, const Panel *panel, const int mx, const int my) { - /* open panel */ - if (panel->flag & PNL_CLOSEDX) { - if ((block->rect.xmin <= mx) && (block->rect.xmin + PNL_HEADER >= mx)) { - return PANEL_MOUSE_INSIDE_HEADER; - } - } - /* outside left/right side */ - else if ((block->rect.xmin > mx) || (block->rect.xmax < mx)) { - /* pass */ + if (!IN_RANGE((float)mx, block->rect.xmin, block->rect.xmax)) { + return PANEL_MOUSE_OUTSIDE; } - else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { + + if (IN_RANGE((float)my, block->rect.ymax, block->rect.ymax + PNL_HEADER)) { return PANEL_MOUSE_INSIDE_HEADER; } - /* open panel */ - else if (!(panel->flag & PNL_CLOSEDY)) { - if ((block->rect.xmin <= mx) && (block->rect.xmax >= mx)) { - if ((block->rect.ymin <= my) && (block->rect.ymax + PNL_HEADER >= my)) { - return PANEL_MOUSE_INSIDE_CONTENT; - } + + if (!(panel->flag & PNL_CLOSED)) { + if (IN_RANGE((float)my, block->rect.ymin, block->rect.ymax + PNL_HEADER)) { + return PANEL_MOUSE_INSIDE_CONTENT; } } + return PANEL_MOUSE_OUTSIDE; } @@ -1741,55 +2003,38 @@ static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *use MEM_freeN(dragcol_data); } -static void ui_panel_drag_collapse(bContext *C, - uiPanelDragCollapseHandle *dragcol_data, +static void ui_panel_drag_collapse(const bContext *C, + const uiPanelDragCollapseHandle *dragcol_data, const int xy_dst[2]) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - Panel *panel; LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)}; float xy_b_block[2] = {UNPACK2(xy_dst)}; - rctf rect = block->rect; - int oldflag; - const bool is_horizontal = (panel_aligned(area, region) == BUT_HORIZONTAL); + Panel *panel = block->panel; - if ((panel = block->panel) == 0 || (panel->type && (panel->type->flag & PNL_NO_HEADER))) { + if (panel == NULL || (panel->type && (panel->type->flag & PNL_NO_HEADER))) { continue; } - oldflag = panel->flag; + const int oldflag = panel->flag; - /* lock one axis */ - if (is_horizontal) { - xy_b_block[1] = dragcol_data->xy_init[1]; - } - else { - xy_b_block[0] = dragcol_data->xy_init[0]; - } + /* lock axis */ + xy_b_block[0] = dragcol_data->xy_init[0]; /* use cursor coords in block space */ ui_window_to_block_fl(region, block, &xy_a_block[0], &xy_a_block[1]); ui_window_to_block_fl(region, block, &xy_b_block[0], &xy_b_block[1]); - /* set up rect to match header size */ + /* Set up `rect` to match header size. */ + rctf rect = block->rect; rect.ymin = rect.ymax; rect.ymax = rect.ymin + PNL_HEADER; - if (panel->flag & PNL_CLOSEDX) { - rect.xmax = rect.xmin + PNL_HEADER; - } /* touch all panels between last mouse coord and the current one */ if (BLI_rctf_isect_segment(&rect, xy_a_block, xy_b_block)) { - /* force panel to close */ - if (dragcol_data->was_first_open == true) { - panel->flag |= (is_horizontal ? PNL_CLOSEDX : PNL_CLOSEDY); - } - /* force panel to open */ - else { - panel->flag &= ~PNL_CLOSED; - } + /* Force panel to open or close. */ + SET_FLAG_FROM_TEST(panel->flag, dragcol_data->was_first_open, PNL_CLOSED); /* if panel->flag has changed this means a panel was opened/closed here */ if (panel->flag != oldflag) { @@ -1853,145 +2098,112 @@ static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was 0); } -/* this function is supposed to call general window drawing too */ -/* also it supposes a block has panel, and isn't a menu */ -static void ui_handle_panel_header( - const bContext *C, uiBlock *block, int mx, int my, int event, short ctrl, short shift) +/** + * Supposing the block has a panel and isn't a menu, handle opening, closing, pinning, etc. + * Code currently assumes layout style for location of widgets + * + * \param mx The mouse x coordinate, in panel space. + */ +static void ui_handle_panel_header(const bContext *C, + uiBlock *block, + const int mx, + short int event_type, + const short ctrl, + const short shift) { - ScrArea *area = CTX_wm_area(C); + Panel *panel = block->panel; ARegion *region = CTX_wm_region(C); -#ifdef USE_PIN_HIDDEN - const bool show_pin = UI_panel_category_is_visible(region) && - (block->panel->type->parent == NULL) && (block->panel->flag & PNL_PIN); -#else - const bool show_pin = UI_panel_category_is_visible(region) && - (block->panel->type->parent == NULL); -#endif - const bool is_subpanel = (block->panel->type && block->panel->type->parent); - const bool show_drag = !is_subpanel; - int align = panel_aligned(area, region), button = 0; + BLI_assert(panel->type != NULL); + BLI_assert(!(panel->type->flag & PNL_NO_HEADER)); - rctf rect_drag, rect_pin; - float rect_leftmost; + const bool is_subpanel = (panel->type->parent != NULL); + const bool use_pin = UI_panel_category_is_visible(region) && !is_subpanel; + const bool show_pin = use_pin && (panel->flag & PNL_PIN); + const bool show_drag = !is_subpanel; - /* drag and pin rect's */ - rect_drag = block->rect; - rect_drag.xmin = block->rect.xmax - (PNL_ICON * 1.5f); - rect_pin = rect_drag; - if (show_pin) { - BLI_rctf_translate(&rect_pin, -PNL_ICON, 0.0f); + /* Handle panel pinning. */ + if (use_pin && ELEM(event_type, EVT_RETKEY, EVT_PADENTER, LEFTMOUSE) && shift) { + panel->flag ^= PNL_PIN; + ED_region_tag_redraw(region); + return; } - rect_leftmost = rect_pin.xmin; - /* mouse coordinates in panel space! */ - - /* XXX weak code, currently it assumes layout style for location of widgets */ - - /* check open/collapsed button */ - if (event == EVT_RETKEY) { - button = 1; - } - else if (event == EVT_AKEY) { - button = 1; - } - else if (ELEM(event, 0, EVT_RETKEY, LEFTMOUSE) && shift) { - if (block->panel->type->parent == NULL) { - block->panel->flag ^= PNL_PIN; - button = 2; - } - } - else if (block->panel->flag & PNL_CLOSEDX) { - if (my >= block->rect.ymax) { - button = 1; - } + float expansion_area_xmax = block->rect.xmax; + if (show_drag) { + expansion_area_xmax -= (PNL_ICON * 1.5f); } - else if (mx < rect_leftmost) { - button = 1; + if (show_pin) { + expansion_area_xmax -= PNL_ICON; } - if (button) { - if (button == 2) { /* close */ - ED_region_tag_redraw(region); - } - else { - /* Collapse and expand panels. */ - - if (ctrl) { - /* For parent panels, collapse all other panels or toggle children. */ - if (block->panel->type != NULL && block->panel->type->parent == NULL) { - if (block->panel->flag & PNL_CLOSED || BLI_listbase_is_empty(&block->panel->children)) { - panels_collapse_all(C, area, region, block->panel); + /* Collapse and expand panels. */ + if (ELEM(event_type, EVT_RETKEY, EVT_PADENTER, EVT_AKEY) || mx < expansion_area_xmax) { + if (ctrl && !is_subpanel) { + /* For parent panels, collapse all other panels or toggle children. */ + if (panel->flag & PNL_CLOSED || BLI_listbase_is_empty(&panel->children)) { + panels_collapse_all(region, panel); - /* Reset the view - we don't want to display a view without content. */ - UI_view2d_offset(®ion->v2d, 0.0f, 1.0f); - } - else { - const int closed_flag = (align == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY; - /* If a panel has sub-panels and it's open, toggle the expansion - * of the sub-panels (based on the expansion of the first subpanel). */ - Panel *first_child = block->panel->children.first; - BLI_assert(first_child != NULL); - panel_set_flag_recursive( - block->panel, closed_flag, (first_child->flag & PNL_CLOSED) == 0); - block->panel->flag |= closed_flag; - } - } + /* Reset the view - we don't want to display a view without content. */ + UI_view2d_offset(®ion->v2d, 0.0f, 1.0f); } - - if (block->panel->flag & PNL_CLOSED) { - block->panel->flag &= ~PNL_CLOSED; - /* snap back up so full panel aligns with screen edge */ - if (block->panel->snap & PNL_SNAP_BOTTOM) { - block->panel->ofsy = 0; - } - - if (event == LEFTMOUSE) { - ui_panel_drag_collapse_handler_add(C, false); - } + else { + /* If a panel has sub-panels and it's open, toggle the expansion + * of the sub-panels (based on the expansion of the first sub-panel). */ + Panel *first_child = panel->children.first; + BLI_assert(first_child != NULL); + panel_set_flag_recursive(panel, PNL_CLOSED, !(first_child->flag & PNL_CLOSED)); + panel->flag |= PNL_CLOSED; } - else if (align == BUT_HORIZONTAL) { - block->panel->flag |= PNL_CLOSEDX; + } - if (event == LEFTMOUSE) { - ui_panel_drag_collapse_handler_add(C, true); - } + if (panel->flag & PNL_CLOSED) { + panel->flag &= ~PNL_CLOSED; + /* Snap back up so full panel aligns with screen edge. */ + if (panel->snap & PNL_SNAP_BOTTOM) { + panel->ofsy = 0; } - else { - /* snap down to bottom screen edge */ - block->panel->flag |= PNL_CLOSEDY; - if (block->panel->snap & PNL_SNAP_BOTTOM) { - block->panel->ofsy = -block->panel->sizey; - } - if (event == LEFTMOUSE) { - ui_panel_drag_collapse_handler_add(C, true); - } + if (event_type == LEFTMOUSE) { + ui_panel_drag_collapse_handler_add(C, false); } - - set_panels_list_data_expand_flag(C, region); - } - - if (align) { - panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION); } else { - /* FIXME: this doesn't update the panel drawing, assert to avoid debugging why this is. - * We could fix this in the future if it's ever needed. */ - BLI_assert(0); - ED_region_tag_redraw(region); + /* Snap down to bottom screen edge. */ + panel->flag |= PNL_CLOSED; + if (panel->snap & PNL_SNAP_BOTTOM) { + panel->ofsy = -panel->sizey; + } + + if (event_type == LEFTMOUSE) { + ui_panel_drag_collapse_handler_add(C, true); + } } + + set_panels_list_data_expand_flag(C, region); + panel_activate_state(C, panel, PANEL_STATE_ANIMATION); + return; } - else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) { - /* XXX, for now don't allow dragging in floating windows yet. */ - if (region->alignment == RGN_ALIGN_FLOAT) { + + /* Handle panel dragging. For now don't allow dragging in floating regions. */ + if (show_drag && !(region->alignment == RGN_ALIGN_FLOAT)) { + const float drag_area_xmin = block->rect.xmax - (PNL_ICON * 1.5f); + const float drag_area_xmax = block->rect.xmax; + if (IN_RANGE(mx, drag_area_xmin, drag_area_xmax)) { + panel_activate_state(C, panel, PANEL_STATE_DRAG); return; } - panel_activate_state(C, block->panel, PANEL_STATE_DRAG); } - else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) { - block->panel->flag ^= PNL_PIN; - ED_region_tag_redraw(region); + + /* Handle panel unpinning. */ + if (show_pin) { + const float pin_area_xmin = expansion_area_xmax; + const float pin_area_xmax = pin_area_xmin + PNL_ICON; + if (IN_RANGE(mx, pin_area_xmin, pin_area_xmax)) { + panel->flag ^= PNL_PIN; + ED_region_tag_redraw(region); + return; + } } } @@ -2027,16 +2239,16 @@ static void ui_panel_category_active_set(ARegion *region, const char *idname, bo } if (fallback) { - /* For fallbacks, add at the end so explicitly chosen categories have priority. */ + /* For fall-backs, 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, + /* Validate all active panels, we could do this on load, * they are harmless - but we should remove somewhere. - * (addons could define own and gather cruft over time) */ + * (add-ons could define own and gather cruft over time). */ { PanelCategoryStack *pc_act_next; /* intentionally skip first */ @@ -2114,421 +2326,6 @@ void UI_panel_category_clear_all(ARegion *region) BLI_freelistN(®ion->panels_category); } -static void imm_buf_append( - float vbuf[][2], uchar cbuf[][3], float x, float y, const uchar col[3], int *index) -{ - ARRAY_SET_ITEMS(vbuf[*index], x, y); - ARRAY_SET_ITEMS(cbuf[*index], UNPACK3(col)); - (*index)++; -} - -/* based on UI_draw_roundbox, check on making a version which allows us to skip some sides */ -static void ui_panel_category_draw_tab(bool filled, - float minx, - float miny, - float maxx, - float maxy, - float rad, - const int roundboxtype, - const bool use_highlight, - const bool use_shadow, - const bool use_flip_x, - const uchar highlight_fade[3], - const uchar col[3]) -{ - float vec[4][2] = {{0.195, 0.02}, {0.55, 0.169}, {0.831, 0.45}, {0.98, 0.805}}; - int a; - - /* mult */ - for (a = 0; a < 4; a++) { - mul_v2_fl(vec[a], rad); - } - - uint vert_len = 0; - if (use_highlight) { - vert_len += (roundboxtype & UI_CNR_TOP_RIGHT) ? 6 : 1; - vert_len += (roundboxtype & UI_CNR_TOP_LEFT) ? 6 : 1; - } - if (use_highlight && !use_shadow) { - vert_len++; - } - else { - vert_len += (roundboxtype & UI_CNR_BOTTOM_RIGHT) ? 6 : 1; - vert_len += (roundboxtype & UI_CNR_BOTTOM_LEFT) ? 6 : 1; - } - /* Maximum size. */ - float vbuf[24][2]; - uchar cbuf[24][3]; - int buf_index = 0; - - /* start with corner right-top */ - if (use_highlight) { - if (roundboxtype & UI_CNR_TOP_RIGHT) { - imm_buf_append(vbuf, cbuf, maxx, maxy - rad, col, &buf_index); - for (a = 0; a < 4; a++) { - imm_buf_append(vbuf, cbuf, maxx - vec[a][1], maxy - rad + vec[a][0], col, &buf_index); - } - imm_buf_append(vbuf, cbuf, maxx - rad, maxy, col, &buf_index); - } - else { - imm_buf_append(vbuf, cbuf, maxx, maxy, col, &buf_index); - } - - /* corner left-top */ - if (roundboxtype & UI_CNR_TOP_LEFT) { - imm_buf_append(vbuf, cbuf, minx + rad, maxy, col, &buf_index); - for (a = 0; a < 4; a++) { - imm_buf_append(vbuf, cbuf, minx + rad - vec[a][0], maxy - vec[a][1], col, &buf_index); - } - imm_buf_append(vbuf, cbuf, minx, maxy - rad, col, &buf_index); - } - else { - imm_buf_append(vbuf, cbuf, minx, maxy, col, &buf_index); - } - } - - if (use_highlight && !use_shadow) { - imm_buf_append( - vbuf, cbuf, minx, miny + rad, highlight_fade ? col : highlight_fade, &buf_index); - } - else { - /* corner left-bottom */ - if (roundboxtype & UI_CNR_BOTTOM_LEFT) { - imm_buf_append(vbuf, cbuf, minx, miny + rad, col, &buf_index); - for (a = 0; a < 4; a++) { - imm_buf_append(vbuf, cbuf, minx + vec[a][1], miny + rad - vec[a][0], col, &buf_index); - } - imm_buf_append(vbuf, cbuf, minx + rad, miny, col, &buf_index); - } - else { - imm_buf_append(vbuf, cbuf, minx, miny, col, &buf_index); - } - - /* corner right-bottom */ - if (roundboxtype & UI_CNR_BOTTOM_RIGHT) { - imm_buf_append(vbuf, cbuf, maxx - rad, miny, col, &buf_index); - for (a = 0; a < 4; a++) { - imm_buf_append(vbuf, cbuf, maxx - rad + vec[a][0], miny + vec[a][1], col, &buf_index); - } - imm_buf_append(vbuf, cbuf, maxx, miny + rad, col, &buf_index); - } - else { - imm_buf_append(vbuf, cbuf, maxx, miny, col, &buf_index); - } - } - - if (use_flip_x) { - float midx = (minx + maxx) / 2.0f; - for (int i = 0; i < buf_index; i++) { - vbuf[i][0] = midx - (vbuf[i][0] - midx); - } - } - - GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add( - format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - - immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); - immBegin(filled ? GPU_PRIM_TRI_FAN : GPU_PRIM_LINE_STRIP, vert_len); - for (int i = 0; i < buf_index; i++) { - immAttr3ubv(color, cbuf[i]); - immVertex2fv(pos, vbuf[i]); - } - immEnd(); - immUnbindProgram(); -} - -/** - * Draw vertical tabs on the left side of the region, - * one tab per category. - */ -void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) -{ - /* no tab outlines for */ - // #define USE_FLAT_INACTIVE - const bool is_left = RGN_ALIGN_ENUM_FROM_MASK(region->alignment != RGN_ALIGN_RIGHT); - View2D *v2d = ®ion->v2d; - const uiStyle *style = UI_style_get(); - const uiFontStyle *fstyle = &style->widget; - const int fontid = fstyle->uifont_id; - short fstyle_points = fstyle->points; - const float aspect = ((uiBlock *)region->uiblocks.first)->aspect; - const float zoom = 1.0f / aspect; - const int px = max_ii(1, round_fl_to_int(U.pixelsize)); - const int px_x_sign = is_left ? px : -px; - const int category_tabs_width = round_fl_to_int(UI_PANEL_CATEGORY_MARGIN_WIDTH * zoom); - const float dpi_fac = UI_DPI_FAC; - /* padding of tabs around text */ - const int tab_v_pad_text = round_fl_to_int((2 + ((px * 3) * dpi_fac)) * zoom); - /* padding between tabs */ - const int tab_v_pad = round_fl_to_int((4 + (2 * px * dpi_fac)) * zoom); - const float tab_curve_radius = ((px * 3) * dpi_fac) * zoom; - /* We flip the tab drawing, so always use these flags. */ - const int roundboxtype = UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT; - bool is_alpha; - bool do_scaletabs = false; -#ifdef USE_FLAT_INACTIVE - bool is_active_prev = false; -#endif - float scaletabs = 1.0f; - /* same for all tabs */ - /* intentionally dont scale by 'px' */ - const int rct_xmin = is_left ? v2d->mask.xmin + 3 : (v2d->mask.xmax - category_tabs_width); - const int rct_xmax = is_left ? v2d->mask.xmin + category_tabs_width : (v2d->mask.xmax - 3); - const int text_v_ofs = (rct_xmax - rct_xmin) * 0.3f; - - int y_ofs = tab_v_pad; - - /* Primary theme colors */ - uchar theme_col_back[4]; - uchar theme_col_text[3]; - uchar theme_col_text_hi[3]; - - /* Tab colors */ - uchar theme_col_tab_bg[4]; - uchar theme_col_tab_active[3]; - uchar theme_col_tab_inactive[3]; - - /* Secondary theme colors */ - uchar theme_col_tab_outline[3]; - uchar theme_col_tab_divider[3]; /* line that divides tabs from the main region */ - uchar theme_col_tab_highlight[3]; - uchar theme_col_tab_highlight_inactive[3]; - - UI_GetThemeColor4ubv(TH_BACK, theme_col_back); - UI_GetThemeColor3ubv(TH_TEXT, theme_col_text); - UI_GetThemeColor3ubv(TH_TEXT_HI, theme_col_text_hi); - - UI_GetThemeColor4ubv(TH_TAB_BACK, theme_col_tab_bg); - UI_GetThemeColor3ubv(TH_TAB_ACTIVE, theme_col_tab_active); - UI_GetThemeColor3ubv(TH_TAB_INACTIVE, theme_col_tab_inactive); - UI_GetThemeColor3ubv(TH_TAB_OUTLINE, theme_col_tab_outline); - - interp_v3_v3v3_uchar(theme_col_tab_divider, theme_col_back, theme_col_tab_outline, 0.3f); - interp_v3_v3v3_uchar(theme_col_tab_highlight, theme_col_back, theme_col_text_hi, 0.2f); - interp_v3_v3v3_uchar( - theme_col_tab_highlight_inactive, theme_col_tab_inactive, theme_col_text_hi, 0.12f); - - is_alpha = (region->overlap && (theme_col_back[3] != 255)); - - if (fstyle->kerning == 1) { - BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - } - - BLF_enable(fontid, BLF_ROTATION); - BLF_rotation(fontid, M_PI_2); - // UI_fontstyle_set(&style->widget); - ui_fontscale(&fstyle_points, aspect / (U.pixelsize * 1.1f)); - BLF_size(fontid, fstyle_points, U.dpi); - - /* Check the region type supports categories to avoid an assert - * for showing 3D view panels in the properties space. */ - if ((1 << region->regiontype) & RGN_TYPE_HAS_CATEGORY_MASK) { - BLI_assert(UI_panel_category_is_visible(region)); - } - - /* calculate tab rect's and check if we need to scale down */ - LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { - - rcti *rct = &pc_dyn->rect; - const char *category_id = pc_dyn->idname; - const char *category_id_draw = IFACE_(category_id); - const int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX); - - rct->xmin = rct_xmin; - rct->xmax = rct_xmax; - - rct->ymin = v2d->mask.ymax - (y_ofs + category_width + (tab_v_pad_text * 2)); - rct->ymax = v2d->mask.ymax - (y_ofs); - - y_ofs += category_width + tab_v_pad + (tab_v_pad_text * 2); - } - - if (y_ofs > BLI_rcti_size_y(&v2d->mask)) { - scaletabs = (float)BLI_rcti_size_y(&v2d->mask) / (float)y_ofs; - - LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { - rcti *rct = &pc_dyn->rect; - rct->ymin = ((rct->ymin - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax; - rct->ymax = ((rct->ymax - v2d->mask.ymax) * scaletabs) + v2d->mask.ymax; - } - - do_scaletabs = true; - } - - /* begin drawing */ - GPU_line_smooth(true); - - uint pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - /* draw the background */ - if (is_alpha) { - GPU_blend(true); - immUniformColor4ubv(theme_col_tab_bg); - } - else { - immUniformColor3ubv(theme_col_tab_bg); - } - - if (is_left) { - immRecti( - pos, v2d->mask.xmin, v2d->mask.ymin, v2d->mask.xmin + category_tabs_width, v2d->mask.ymax); - } - else { - immRecti( - pos, v2d->mask.xmax - category_tabs_width, v2d->mask.ymin, v2d->mask.xmax, v2d->mask.ymax); - } - - if (is_alpha) { - GPU_blend(false); - } - - immUnbindProgram(); - - const int divider_xmin = is_left ? (v2d->mask.xmin + (category_tabs_width - px)) : - (v2d->mask.xmax - category_tabs_width) + px; - const int divider_xmax = is_left ? (v2d->mask.xmin + category_tabs_width) : - (v2d->mask.xmax - (category_tabs_width + px)) + px; - - LISTBASE_FOREACH (PanelCategoryDyn *, pc_dyn, ®ion->panels_category) { - const rcti *rct = &pc_dyn->rect; - const char *category_id = pc_dyn->idname; - const char *category_id_draw = IFACE_(category_id); - int category_width = BLI_rcti_size_y(rct) - (tab_v_pad_text * 2); - size_t category_draw_len = BLF_DRAW_STR_DUMMY_MAX; - // int category_width = BLF_width(fontid, category_id_draw, BLF_DRAW_STR_DUMMY_MAX); - - const bool is_active = STREQ(category_id, category_id_active); - - GPU_blend(true); - -#ifdef USE_FLAT_INACTIVE - if (is_active) -#endif - { - const bool use_flip_x = !is_left; - ui_panel_category_draw_tab(true, - rct->xmin, - rct->ymin, - rct->xmax, - rct->ymax, - tab_curve_radius - px, - roundboxtype, - true, - true, - use_flip_x, - NULL, - is_active ? theme_col_tab_active : theme_col_tab_inactive); - - /* tab outline */ - ui_panel_category_draw_tab(false, - rct->xmin - px_x_sign, - rct->ymin - px, - rct->xmax - px_x_sign, - rct->ymax + px, - tab_curve_radius, - roundboxtype, - true, - true, - use_flip_x, - NULL, - theme_col_tab_outline); - - /* tab highlight (3d look) */ - ui_panel_category_draw_tab(false, - rct->xmin, - rct->ymin, - rct->xmax, - rct->ymax, - tab_curve_radius, - roundboxtype, - true, - false, - use_flip_x, - is_active ? theme_col_back : theme_col_tab_inactive, - is_active ? theme_col_tab_highlight : - theme_col_tab_highlight_inactive); - } - - /* tab blackline */ - if (!is_active) { - pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - - immUniformColor3ubv(theme_col_tab_divider); - immRecti(pos, divider_xmin, rct->ymin - tab_v_pad, divider_xmax, rct->ymax + tab_v_pad); - immUnbindProgram(); - } - - if (do_scaletabs) { - category_draw_len = BLF_width_to_strlen( - fontid, category_id_draw, category_draw_len, category_width, NULL); - } - - BLF_position(fontid, rct->xmax - text_v_ofs, rct->ymin + tab_v_pad_text, 0.0f); - - /* tab titles */ - - /* draw white shadow to give text more depth */ - BLF_color3ubv(fontid, theme_col_text); - - /* main tab title */ - BLF_draw(fontid, category_id_draw, category_draw_len); - - GPU_blend(false); - - /* tab blackline remaining (last tab) */ - pos = GPU_vertformat_attr_add( - immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - if (pc_dyn->prev == NULL) { - immUniformColor3ubv(theme_col_tab_divider); - immRecti(pos, divider_xmin, rct->ymax + px, divider_xmax, v2d->mask.ymax); - } - if (pc_dyn->next == NULL) { - immUniformColor3ubv(theme_col_tab_divider); - immRecti(pos, divider_xmin, 0, divider_xmax, rct->ymin); - } - -#ifdef USE_FLAT_INACTIVE - /* draw line between inactive tabs */ - if (is_active == false && is_active_prev == false && pc_dyn->prev) { - immUniformColor3ubv(theme_col_tab_divider); - immRecti(pos, - v2d->mask.xmin + (category_tabs_width / 5), - rct->ymax + px, - (v2d->mask.xmin + category_tabs_width) - (category_tabs_width / 5), - rct->ymax + (px * 3)); - } - - is_active_prev = is_active; -#endif - immUnbindProgram(); - - /* not essential, but allows events to be handled right up until the region edge [#38171] */ - if (is_left) { - pc_dyn->rect.xmin = v2d->mask.xmin; - } - else { - pc_dyn->rect.xmax = v2d->mask.xmax; - } - } - - GPU_line_smooth(false); - - BLF_disable(fontid, BLF_ROTATION); - - if (fstyle->kerning == 1) { - BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - } - -#undef USE_FLAT_INACTIVE -} - static int ui_handle_panel_category_cycling(const wmEvent *event, ARegion *region, const uiBut *active_but) @@ -2581,132 +2378,108 @@ static int ui_handle_panel_category_cycling(const wmEvent *event, return WM_UI_HANDLER_CONTINUE; } -/* XXX should become modal keymap */ -/* AKey is opening/closing panels, independent of button state now */ - +/** + * Handle region panel events like opening and closing panels, changing categories, etc. + * + * \note Could become a modal key-map. + */ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *region, const uiBut *active_but) { - Panel *panel; - int retval, mx, my; - bool has_category_tabs = UI_panel_category_is_visible(region); + /* Mouse-move events are handled by separate handlers for dragging and drag collapsing. */ + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + return WM_UI_HANDLER_CONTINUE; + } - retval = WM_UI_HANDLER_CONTINUE; + /* We only use KM_PRESS events in this function, so it's simpler to return early. */ + if (event->val != KM_PRESS) { + return WM_UI_HANDLER_CONTINUE; + } - /* Scrollbars can overlap panels now, they have handling priority. */ + /* Scroll-bars can overlap panels now, they have handling priority. */ if (UI_view2d_mouse_in_scrollers(region, ®ion->v2d, event->x, event->y)) { - return retval; + return WM_UI_HANDLER_CONTINUE; } - /* handle category tabs */ - if (has_category_tabs) { - if (event->val == KM_PRESS) { - if (event->type == LEFTMOUSE) { - PanelCategoryDyn *pc_dyn = UI_panel_category_find_mouse_over(region, event); - if (pc_dyn) { - UI_panel_category_active_set(region, pc_dyn->idname); - ED_region_tag_redraw(region); + int retval = WM_UI_HANDLER_CONTINUE; + + /* Handle category tabs. */ + if (UI_panel_category_is_visible(region)) { + if (event->type == LEFTMOUSE) { + PanelCategoryDyn *pc_dyn = UI_panel_category_find_mouse_over(region, event); + if (pc_dyn) { + UI_panel_category_active_set(region, pc_dyn->idname); + ED_region_tag_redraw(region); - /* reset scroll to the top [#38348] */ - UI_view2d_offset(®ion->v2d, -1.0f, 1.0f); + /* Reset scroll to the top (T38348). */ + UI_view2d_offset(®ion->v2d, -1.0f, 1.0f); - retval = WM_UI_HANDLER_BREAK; - } - } - else if ((event->type == EVT_TABKEY && event->ctrl) || - ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) { - /* cycle tabs */ - retval = ui_handle_panel_category_cycling(event, region, active_but); + retval = WM_UI_HANDLER_BREAK; } } + else if ((event->type == EVT_TABKEY && event->ctrl) || + ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) { + /* Cycle tabs. */ + retval = ui_handle_panel_category_cycling(event, region, active_but); + } } if (retval == WM_UI_HANDLER_BREAK) { return retval; } - LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { - uiPanelMouseState mouse_state; - - mx = event->x; - my = event->y; - ui_window_to_block(region, block, &mx, &my); - - /* checks for mouse position inside */ - panel = block->panel; + const bool region_has_active_button = (ui_region_find_active_but(region) != NULL); - if (!panel) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { + Panel *panel = block->panel; + if (panel == NULL || panel->type == NULL) { continue; } - /* XXX - accessed freed panels when scripts reload, need to fix. */ - if (panel->type && panel->type->flag & PNL_NO_HEADER) { + /* We can't expand or collapse panels without headers, they would disappear. */ + if (panel->type->flag & PNL_NO_HEADER) { continue; } - mouse_state = ui_panel_mouse_state_get(block, panel, mx, my); - - /* XXX hardcoded key warning */ - if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER) && - event->val == KM_PRESS) { - if (event->type == EVT_AKEY && - ((event->ctrl + event->oskey + event->shift + event->alt) == 0)) { + int mx = event->x; + int my = event->y; + ui_window_to_block(region, block, &mx, &my); - if (panel->flag & PNL_CLOSEDY) { - if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { - ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift); - } - } - else { - ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift); - } + const uiPanelMouseState mouse_state = ui_panel_mouse_state_get(block, panel, mx, my); + /* The panel collapse / expand key "A" is special as it takes priority over + * active button handling. */ + if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) { + if (event->type == EVT_AKEY && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) { retval = WM_UI_HANDLER_BREAK; - continue; + ui_handle_panel_header(C, block, mx, event->type, event->ctrl, event->shift); + break; } } - /* on active button, do not handle panels */ - if (ui_region_find_active_but(region) != NULL) { + /* Don't do any other panel handling with an active button. */ + if (region_has_active_button) { continue; } - if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) { - - if (event->val == KM_PRESS) { + /* All mouse clicks inside panels should return in break, but continue handling + * in case there is a sub-panel header at the mouse location. */ + if (event->type == LEFTMOUSE && + ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) { + retval = WM_UI_HANDLER_BREAK; + } - /* open close on header */ - if (ELEM(event->type, EVT_RETKEY, EVT_PADENTER)) { - if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) { - ui_handle_panel_header(C, block, mx, my, EVT_RETKEY, event->ctrl, event->shift); - retval = WM_UI_HANDLER_BREAK; - break; - } - } - else if (event->type == LEFTMOUSE) { - /* all inside clicks should return in break - overlapping/float panels */ - retval = WM_UI_HANDLER_BREAK; - - if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) { - ui_handle_panel_header(C, block, mx, my, event->type, event->ctrl, event->shift); - retval = WM_UI_HANDLER_BREAK; - break; - } - if ((mouse_state == PANEL_MOUSE_INSIDE_SCALE) && !(panel->flag & PNL_CLOSED)) { - panel_activate_state(C, panel, PANEL_STATE_DRAG_SCALE); - retval = WM_UI_HANDLER_BREAK; - break; - } - } - else if (event->type == RIGHTMOUSE) { - if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) { - ui_popup_context_menu_for_panel(C, region, block->panel); - retval = WM_UI_HANDLER_BREAK; - break; - } - } + if (mouse_state == PANEL_MOUSE_INSIDE_HEADER) { + if (ELEM(event->type, EVT_RETKEY, EVT_PADENTER, LEFTMOUSE)) { + retval = WM_UI_HANDLER_BREAK; + ui_handle_panel_header(C, block, mx, event->type, event->ctrl, event->shift); } + else if (event->type == RIGHTMOUSE) { + retval = WM_UI_HANDLER_BREAK; + ui_popup_context_menu_for_panel(C, region, block->panel); + } + break; } } @@ -2748,7 +2521,7 @@ PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wm int mx = event->x; int my = event->y; ui_window_to_block(region, block, &mx, &my); - int mouse_state = ui_panel_mouse_state_get(block, panel, mx, my); + const int mouse_state = ui_panel_mouse_state_get(block, panel, mx, my); if (ELEM(mouse_state, PANEL_MOUSE_INSIDE_CONTENT, PANEL_MOUSE_INSIDE_HEADER)) { break; } @@ -2763,7 +2536,11 @@ PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wm return customdata; } -/**************** window level modal panel interaction **************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Window Level Modal Panel Interaction + * \{ */ /* note, this is modal handler and should not swallow events for animation */ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata) @@ -2773,16 +2550,7 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata) /* verify if we can stop */ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { - ScrArea *area = CTX_wm_area(C); - ARegion *region = CTX_wm_region(C); - int align = panel_aligned(area, region); - - if (align) { - panel_activate_state(C, panel, PANEL_STATE_ANIMATION); - } - else { - panel_activate_state(C, panel, PANEL_STATE_EXIT); - } + panel_activate_state(C, panel, PANEL_STATE_ANIMATION); } else if (event->type == MOUSEMOVE) { if (data->state == PANEL_STATE_DRAG) { @@ -2823,7 +2591,7 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS return; } - bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG); + const bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG); /* Set selection state for the panel and its sub-panels, which need to know they are selected * too so they can be drawn above their parent when it's dragged. */ @@ -2897,3 +2665,5 @@ PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname) } return NULL; } + +/** \} */ diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c index edb5d51a392..9dcfe8c872b 100644 --- a/source/blender/editors/interface/interface_query.c +++ b/source/blender/editors/interface/interface_query.c @@ -256,7 +256,7 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } else { - int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect); + const int delta = BLI_rcti_size_x(&rect) - BLI_rcti_size_y(&rect); rect.xmin += delta / 2; rect.xmax -= delta / 2; } @@ -276,7 +276,7 @@ uiBut *ui_but_find_mouse_over_ex(ARegion *region, const int x, const int y, cons float mx = x, my = y; ui_window_to_block_fl(region, block, &mx, &my); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (ui_but_is_interactive(but, labeledit)) { if (but->pie_dir != UI_RADIAL_NONE) { if (ui_but_isect_pie_seg(block, but)) { @@ -315,7 +315,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) } /* Currently no need to expose this at the moment. */ - bool labeledit = true; + const bool labeledit = true; rctf rect_px_fl; BLI_rctf_rcti_copy(&rect_px_fl, rect_px); uiBut *butover = NULL; @@ -324,7 +324,7 @@ uiBut *ui_but_find_rect_over(const struct ARegion *region, const rcti *rect_px) rctf rect_block; ui_window_to_block_rctf(region, block, &rect_block, &rect_px_fl); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (ui_but_is_interactive(but, labeledit)) { /* No pie menu support. */ BLI_assert(but->pie_dir == UI_RADIAL_NONE); @@ -354,7 +354,7 @@ uiBut *ui_list_find_mouse_over_ex(ARegion *region, int x, int y) LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { float mx = x, my = y; ui_window_to_block_fl(region, block, &mx, &my); - for (uiBut *but = block->buttons.last; but; but = but->prev) { + LISTBASE_FOREACH_BACKWARD (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_LISTBOX && ui_but_contains_pt(but, mx, my)) { return but; } @@ -399,14 +399,10 @@ uiBut *ui_but_next(uiBut *but) uiBut *ui_but_first(uiBlock *block) { - uiBut *but; - - but = block->buttons.first; - while (but) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (ui_but_is_editable(but)) { return but; } - but = but->next; } return NULL; } diff --git a/source/blender/editors/interface/interface_region_color_picker.c b/source/blender/editors/interface/interface_region_color_picker.c index 0d1b483716e..de80d6270bf 100644 --- a/source/blender/editors/interface/interface_region_color_picker.c +++ b/source/blender/editors/interface/interface_region_color_picker.c @@ -183,7 +183,6 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, ColorPicker *cpicker, const float rgb[3]) { - uiBut *bt; float *hsv = cpicker->color_data; /* Convert from RGB to HSV in perceptually linear space. */ @@ -196,7 +195,7 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but, /* this updates button strings, * is hackish... but button pointers are on stack of caller function */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->custom_data != cpicker) { continue; } @@ -352,7 +351,7 @@ static void ui_colorpicker_hide_reveal(uiBlock *block, enum ePickerType colormod static void ui_colorpicker_create_mode_cb(bContext *UNUSED(C), void *bt1, void *UNUSED(arg)) { uiBut *bt = bt1; - short colormode = ui_but_value_get(bt); + const short colormode = ui_but_value_get(bt); ui_colorpicker_hide_reveal(bt->block, colormode); } @@ -849,9 +848,7 @@ static int ui_colorpicker_small_wheel_cb(const bContext *UNUSED(C), } if (add != 0.0f) { - uiBut *but; - - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { if (but->type == UI_BTYPE_HSVCUBE && but->active == NULL) { uiPopupBlockHandle *popup = block->handle; float rgb[3]; diff --git a/source/blender/editors/interface/interface_region_hud.c b/source/blender/editors/interface/interface_region_hud.c index 1773a7b3057..cecfe6941fc 100644 --- a/source/blender/editors/interface/interface_region_hud.c +++ b/source/blender/editors/interface/interface_region_hud.c @@ -178,7 +178,7 @@ static void hud_region_layout(const bContext *C, ARegion *region) } ScrArea *area = CTX_wm_area(C); - int size_y = region->sizey; + const int size_y = region->sizey; ED_region_panels_layout(C, region); @@ -201,7 +201,7 @@ static void hud_region_layout(const bContext *C, ARegion *region) region->winrct.xmax = (region->winrct.xmin + region->winx) - 1; region->winrct.ymax = (region->winrct.ymin + region->winy) - 1; - UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_PANELS_UI, region->winx, region->winy); + UI_view2d_region_reinit(v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy); /* Weak, but needed to avoid glitches, especially with hi-dpi * (where resizing the view glitches often). @@ -217,8 +217,7 @@ static void hud_region_draw(const bContext *C, ARegion *region) { UI_view2d_view_ortho(®ion->v2d); wmOrtho2_region_pixelspace(region); - GPU_clear_color(0, 0, 0, 0.0f); - GPU_clear(GPU_COLOR_BIT); + GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); if ((region->flag & RGN_FLAG_HIDDEN) == 0) { ui_draw_menu_back(NULL, @@ -317,7 +316,7 @@ void ED_area_type_hud_ensure(bContext *C, ScrArea *area) } bool init = false; - bool was_hidden = region == NULL || region->visible == false; + const bool was_hidden = region == NULL || region->visible == false; ARegion *region_op = CTX_wm_region(C); BLI_assert((region_op == NULL) || (region_op->regiontype != RGN_TYPE_HUD)); if (!last_redo_poll(C, region_op ? region_op->regiontype : -1)) { diff --git a/source/blender/editors/interface/interface_region_menu_pie.c b/source/blender/editors/interface/interface_region_menu_pie.c index 1371c7524ae..631f395390f 100644 --- a/source/blender/editors/interface/interface_region_menu_pie.c +++ b/source/blender/editors/interface/interface_region_menu_pie.c @@ -387,7 +387,7 @@ void ui_pie_menu_level_create(uiBlock *block, { const int totitem_parent = PIE_MAX_ITEMS - 1; const int totitem_remain = totitem - totitem_parent; - size_t array_size = sizeof(EnumPropertyItem) * totitem_remain; + const size_t array_size = sizeof(EnumPropertyItem) * totitem_remain; /* used as but->func_argN so freeing is handled elsewhere */ EnumPropertyItem *remaining = MEM_mallocN(array_size + sizeof(EnumPropertyItem), diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c index 077e8888d53..881ba58174b 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.c +++ b/source/blender/editors/interface/interface_region_menu_popup.c @@ -130,9 +130,10 @@ static uiBut *ui_popup_menu_memory__internal(uiBlock *block, uiBut *but) } /* get */ - for (but = block->buttons.first; but; but = but->next) { - if (mem[hash_mod] == ui_popup_string_hash(but->str, but->flag & UI_BUT_HAS_SEP_CHAR)) { - return but; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if (mem[hash_mod] == + ui_popup_string_hash(but_iter->str, but_iter->flag & UI_BUT_HAS_SEP_CHAR)) { + return but_iter; } } @@ -232,7 +233,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi UI_block_flag_enable(block, UI_BLOCK_MOVEMOUSE_QUIT); if (pup->popup) { - uiBut *bt; int offset[2]; uiBut *but_activate = NULL; @@ -241,6 +241,7 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi UI_block_direction_set(block, direction); /* offset the mouse position, possibly based on earlier selection */ + uiBut *bt; if ((block->flag & UI_BLOCK_POPUP_MEMORY) && (bt = ui_popup_menu_memory_get(block))) { /* position mouse on last clicked item, at 0.8*width of the * button, so it doesn't overlap the text too much, also note @@ -257,15 +258,16 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi /* position mouse at 0.8*width of the button and below the tile * on the first item */ offset[0] = 0; - for (bt = block->buttons.first; bt; bt = bt->next) { - offset[0] = min_ii(offset[0], -(bt->rect.xmin + 0.8f * BLI_rctf_size_x(&bt->rect))); + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + offset[0] = min_ii(offset[0], + -(but_iter->rect.xmin + 0.8f * BLI_rctf_size_x(&but_iter->rect))); } offset[1] = 2.1 * UI_UNIT_Y; - for (bt = block->buttons.first; bt; bt = bt->next) { - if (ui_but_is_editable(bt)) { - but_activate = bt; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if (ui_but_is_editable(but_iter)) { + but_activate = but_iter; break; } } @@ -284,17 +286,10 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi else { /* for a header menu we set the direction automatic */ if (!pup->slideout && flip) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP); - UI_block_order_flip(block); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP); UI_block_order_flip(block); } @@ -506,8 +501,6 @@ uiLayout *UI_popup_menu_layout(uiPopupMenu *pup) void UI_popup_menu_reports(bContext *C, ReportList *reports) { - Report *report; - uiPopupMenu *pup = NULL; uiLayout *layout; @@ -515,7 +508,7 @@ void UI_popup_menu_reports(bContext *C, ReportList *reports) return; } - for (report = reports->list.first; report; report = report->next) { + LISTBASE_FOREACH (Report *, report, &reports->list) { int icon; const char *msg, *msg_next; diff --git a/source/blender/editors/interface/interface_region_popover.c b/source/blender/editors/interface/interface_region_popover.c index 0ad7e570e80..9ef68e9e187 100644 --- a/source/blender/editors/interface/interface_region_popover.c +++ b/source/blender/editors/interface/interface_region_popover.c @@ -151,7 +151,7 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v UI_block_bounds_set_normal(block, block_margin); /* If menu slides out of other menu, override direction. */ - bool slideout = ui_block_is_menu(pup->but->block); + const bool slideout = ui_block_is_menu(pup->but->block); if (slideout) { UI_block_direction_set(block, UI_DIR_RIGHT); } @@ -171,7 +171,6 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v } if (!slideout) { - ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); if (region && region->panels.first) { @@ -180,14 +179,9 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } /* Prefer popover from header to be positioned into the editor. */ - else if (area && region) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_header_alignment(area)) == RGN_ALIGN_BOTTOM) { - UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); - } - } - if (region->regiontype == RGN_TYPE_FOOTER) { - if (RGN_ALIGN_ENUM_FROM_MASK(ED_area_footer_alignment(area)) == RGN_ALIGN_BOTTOM) { + else if (region) { + if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) { + if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) { UI_block_direction_set(block, UI_DIR_UP | UI_DIR_CENTER_X); } } @@ -209,11 +203,12 @@ static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, v if (!handle->refresh) { uiBut *but = NULL; uiBut *but_first = NULL; - for (but = block->buttons.first; but; but = but->next) { - if ((but_first == NULL) && ui_but_is_editable(but)) { - but_first = but; + LISTBASE_FOREACH (uiBut *, but_iter, &block->buttons) { + if ((but_first == NULL) && ui_but_is_editable(but_iter)) { + but_first = but_iter; } - if (but->flag & (UI_SELECT | UI_SELECT_DRAW)) { + if (but_iter->flag & (UI_SELECT | UI_SELECT_DRAW)) { + but = but_iter; break; } } @@ -259,7 +254,7 @@ uiPopupBlockHandle *ui_popover_panel_create( /* FIXME: maybe one day we want non panel popovers? */ { - int ui_units_x = ((PanelType *)arg)->ui_units_x; + const int ui_units_x = ((PanelType *)arg)->ui_units_x; pup->ui_size_x = U.widget_unit * (ui_units_x ? ui_units_x : UI_POPOVER_WIDTH_UNITS); } diff --git a/source/blender/editors/interface/interface_region_popup.c b/source/blender/editors/interface/interface_region_popup.c index 13c85952f52..5445b098e5b 100644 --- a/source/blender/editors/interface/interface_region_popup.c +++ b/source/blender/editors/interface/interface_region_popup.c @@ -59,8 +59,6 @@ */ void ui_popup_translate(ARegion *region, const int mdiff[2]) { - uiBlock *block; - BLI_rcti_translate(®ion->winrct, UNPACK2(mdiff)); ED_region_update_rect(region); @@ -68,13 +66,12 @@ void ui_popup_translate(ARegion *region, const int mdiff[2]) ED_region_tag_redraw(region); /* update blocks */ - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { uiPopupBlockHandle *handle = block->handle; /* Make empty, will be initialized on next use, see T60608. */ BLI_rctf_init(&handle->prev_block_rect, 0, 0, 0, 0); - uiSafetyRct *saferct; - for (saferct = block->saferct.first; saferct; saferct = saferct->next) { + LISTBASE_FOREACH (uiSafetyRct *, saferct, &block->saferct) { BLI_rctf_translate(&saferct->parent, UNPACK2(mdiff)); BLI_rctf_translate(&saferct->safety, UNPACK2(mdiff)); } @@ -373,16 +370,13 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region) { ScrArea *ctx_area = CTX_wm_area(C); ARegion *ctx_region = CTX_wm_region(C); - uiBlock *block; if (region->do_draw & RGN_REFRESH_UI) { ScrArea *handle_ctx_area; ARegion *handle_ctx_region; - uiBlock *block_next; region->do_draw &= ~RGN_REFRESH_UI; - for (block = region->uiblocks.first; block; block = block_next) { - block_next = block->next; + LISTBASE_FOREACH_MUTABLE (uiBlock *, block, ®ion->uiblocks) { uiPopupBlockHandle *handle = block->handle; if (handle->can_refresh) { @@ -409,9 +403,7 @@ static void ui_block_region_refresh(const bContext *C, ARegion *region) static void ui_block_region_draw(const bContext *C, ARegion *region) { - uiBlock *block; - - for (block = region->uiblocks.first; block; block = block->next) { + LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { UI_block_draw(C, block); } } @@ -441,7 +433,6 @@ static void ui_block_region_popup_window_listener(wmWindow *UNUSED(win), static void ui_popup_block_clip(wmWindow *window, uiBlock *block) { - uiBut *bt; const float xmin_orig = block->rect.xmin; const int margin = UI_SCREEN_MARGIN; int winx, winy; @@ -475,7 +466,7 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) /* ensure menu items draw inside left/right boundary */ const float xofs = block->rect.xmin - xmin_orig; - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { bt->rect.xmin += xofs; bt->rect.xmax += xofs; } @@ -483,11 +474,9 @@ static void ui_popup_block_clip(wmWindow *window, uiBlock *block) void ui_popup_block_scrolltest(uiBlock *block) { - uiBut *bt; - block->flag &= ~(UI_BLOCK_CLIPBOTTOM | UI_BLOCK_CLIPTOP); - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { bt->flag &= ~UI_SCROLLED; } @@ -496,7 +485,7 @@ void ui_popup_block_scrolltest(uiBlock *block) } /* mark buttons that are outside boundary */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (bt->rect.ymin < block->rect.ymin) { bt->flag |= UI_SCROLLED; block->flag |= UI_BLOCK_CLIPBOTTOM; @@ -508,7 +497,7 @@ void ui_popup_block_scrolltest(uiBlock *block) } /* mark buttons overlapping arrows, if we have them */ - for (bt = block->buttons.first; bt; bt = bt->next) { + LISTBASE_FOREACH (uiBut *, bt, &block->buttons) { if (block->flag & UI_BLOCK_CLIPBOTTOM) { if (bt->rect.ymin < block->rect.ymin + UI_MENU_SCROLL_ARROW) { bt->flag |= UI_SCROLLED; @@ -535,9 +524,10 @@ static void ui_popup_block_remove(bContext *C, uiPopupBlockHandle *handle) /* There may actually be a different window active than the one showing the popup, so lookup real * one. */ if (BLI_findindex(&screen->regionbase, handle->region) == -1) { - for (win = wm->windows.first; win; win = win->next) { - screen = WM_window_get_active_screen(win); + LISTBASE_FOREACH (wmWindow *, win_iter, &wm->windows) { + screen = WM_window_get_active_screen(win_iter); if (BLI_findindex(&screen->regionbase, handle->region) != -1) { + win = win_iter; break; } } @@ -575,8 +565,8 @@ uiBlock *ui_popup_block_refresh(bContext *C, wmWindow *window = CTX_wm_window(C); ARegion *region = handle->region; - uiBlockCreateFunc create_func = handle->popup_create_vars.create_func; - uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func; + const uiBlockCreateFunc create_func = handle->popup_create_vars.create_func; + const uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func; void *arg = handle->popup_create_vars.arg; uiBlock *block_old = region->uiblocks.first; @@ -648,7 +638,7 @@ uiBlock *ui_popup_block_refresh(bContext *C, } if (block->flag & UI_BLOCK_RADIAL) { - int win_width = UI_SCREEN_MARGIN; + const int win_width = UI_SCREEN_MARGIN; int winx, winy; int x_offset = 0, y_offset = 0; @@ -722,7 +712,7 @@ uiBlock *ui_popup_block_refresh(bContext *C, * the same height. */ if (handle->refresh && handle->prev_block_rect.ymax > block->rect.ymax) { if (block->bounds_type != UI_BLOCK_BOUNDS_POPUP_CENTER) { - float offset = handle->prev_block_rect.ymax - block->rect.ymax; + const float offset = handle->prev_block_rect.ymax - block->rect.ymax; UI_block_translate(block, 0, offset); block->rect.ymin = handle->prev_block_rect.ymin; } diff --git a/source/blender/editors/interface/interface_region_search.c b/source/blender/editors/interface/interface_region_search.c index 2010d89165e..0711d953ebd 100644 --- a/source/blender/editors/interface/interface_region_search.c +++ b/source/blender/editors/interface/interface_region_search.c @@ -256,8 +256,8 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr { /* thumbnail preview */ if (data->preview) { - int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols; - int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows; + const int butw = (BLI_rcti_size_x(&data->bbox) - 2 * MENU_BORDER) / data->prv_cols; + const int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_BORDER) / data->prv_rows; int row, col; *r_rect = data->bbox; @@ -273,7 +273,7 @@ static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr } /* list view */ else { - int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS; + const int buth = (BLI_rcti_size_y(&data->bbox) - 2 * UI_POPUP_MENU_TOP) / SEARCH_ITEMS; *r_rect = data->bbox; r_rect->xmin = data->bbox.xmin + 3.0f; @@ -592,15 +592,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region) /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw(rect.xmax - 18, rect.ymin - 7, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw(rect.xmin, rect.ymax - 9, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } else { @@ -657,15 +657,15 @@ static void ui_searchbox_region_draw_cb(const bContext *C, ARegion *region) /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -701,7 +701,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiButSearc static ARegionType type; ARegion *region; uiSearchboxData *data; - float aspect = but->block->aspect; + const float aspect = but->block->aspect; rctf rect_fl; rcti rect_i; const int margin = UI_POPUP_MARGIN; @@ -953,15 +953,15 @@ static void ui_searchbox_region_draw_cb__operator(const bContext *UNUSED(C), ARe /* indicate more */ if (data->items.more) { ui_searchbox_butrect(&rect, data, data->items.maxitem - 1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymin - 9, ICON_TRIA_DOWN); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (data->items.offset) { ui_searchbox_butrect(&rect, data, 0); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw((BLI_rcti_size_x(&rect)) / 2, rect.ymax - 7, ICON_TRIA_UP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.c index 41b41cb3d75..b3a65e024f3 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.c @@ -63,7 +63,7 @@ #include "BLT_translation.h" #ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "ED_screen.h" @@ -221,8 +221,8 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region /* offset to the end of the last line */ if (field->text_suffix) { - float xofs = field->geom.x_pos; - float yofs = data->lineh * (field->geom.lines - 1); + const float xofs = field->geom.x_pos; + const float yofs = data->lineh * (field->geom.lines - 1); bbox.xmin += xofs; bbox.ymax -= yofs; @@ -433,7 +433,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { + else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { if (STREQ(expr_result, "")) { MEM_freeN(expr_result); expr_result = NULL; @@ -490,7 +490,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { + else if (BPY_run_string_as_string(C, expr_imports, expr, __func__, &expr_result)) { if (STREQ(expr_result, ".")) { MEM_freeN(expr_result); expr_result = NULL; @@ -541,7 +541,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is } if (shortcut == NULL) { - ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); + const ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); const char *tool_attr = BKE_paint_get_tool_prop_id_from_paintmode(paint_mode); if (tool_attr != NULL) { const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode); @@ -594,7 +594,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { shortcut = BLI_strdup(has_valid_context_error); } - else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { + else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { if (expr_result != 0) { wmKeyMap *keymap = (wmKeyMap *)expr_result; LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { @@ -658,7 +658,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { /* pass */ } - else if (BPY_execute_string_as_string_and_size( + else if (BPY_run_string_as_string_and_size( C, expr_imports, expr, __func__, &expr_result, &expr_result_len)) { /* pass. */ } @@ -736,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { /* pass */ } - else if (BPY_execute_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { + else if (BPY_run_string_as_intptr(C, expr_imports, expr, __func__, &expr_result)) { if (expr_result != 0) { { uiTooltipField *field = text_field_add(data, @@ -884,7 +884,7 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but) } if (but->rnaprop) { - int unit_type = UI_but_unit_type_get(but); + const int unit_type = UI_but_unit_type_get(but); if (unit_type == PROP_UNIT_ROTATION) { if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 5310ff0e3ec..b38ad9f6adb 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -184,7 +184,7 @@ void UI_fontstyle_draw_ex(const uiFontStyle *fs, } else { /* draw from boundbox center */ - float height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id); + const float height = BLF_ascender(fs->uifont_id) + BLF_descender(fs->uifont_id); yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height)); } @@ -426,7 +426,6 @@ int UI_fontstyle_height_max(const uiFontStyle *fs) /* reading without uifont will create one */ void uiStyleInit(void) { - uiFont *font; uiStyle *style = U.uistyles.first; /* recover from uninitialized dpi */ @@ -435,7 +434,7 @@ void uiStyleInit(void) } CLAMP(U.dpi, 48, 144); - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { BLF_unload_id(font->blf_id); } @@ -449,24 +448,24 @@ void uiStyleInit(void) blf_mono_font_render = -1; } - font = U.uifonts.first; + uiFont *font_first = U.uifonts.first; /* default builtin */ - if (font == NULL) { - font = MEM_callocN(sizeof(uiFont), "ui font"); - BLI_addtail(&U.uifonts, font); + if (font_first == NULL) { + font_first = MEM_callocN(sizeof(uiFont), "ui font"); + BLI_addtail(&U.uifonts, font_first); } if (U.font_path_ui[0]) { - BLI_strncpy(font->filename, U.font_path_ui, sizeof(font->filename)); - font->uifont_id = UIFONT_CUSTOM1; + BLI_strncpy(font_first->filename, U.font_path_ui, sizeof(font_first->filename)); + font_first->uifont_id = UIFONT_CUSTOM1; } else { - BLI_strncpy(font->filename, "default", sizeof(font->filename)); - font->uifont_id = UIFONT_DEFAULT; + BLI_strncpy(font_first->filename, "default", sizeof(font_first->filename)); + font_first->uifont_id = UIFONT_DEFAULT; } - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { const bool unique = false; if (font->uifont_id == UIFONT_DEFAULT) { @@ -518,7 +517,8 @@ void uiStyleInit(void) /* Set default flags based on UI preferences (not render fonts) */ { - int flag_disable = (BLF_MONOCHROME | BLF_HINTING_NONE | BLF_HINTING_SLIGHT | BLF_HINTING_FULL); + const int flag_disable = (BLF_MONOCHROME | BLF_HINTING_NONE | BLF_HINTING_SLIGHT | + BLF_HINTING_FULL); int flag_enable = 0; if (U.text_render & USER_TEXT_HINTING_NONE) { @@ -535,7 +535,7 @@ void uiStyleInit(void) flag_enable |= BLF_MONOCHROME; } - for (font = U.uifonts.first; font; font = font->next) { + LISTBASE_FOREACH (uiFont *, font, &U.uifonts) { if (font->blf_id != -1) { BLF_disable(font->blf_id, flag_disable); BLF_enable(font->blf_id, flag_enable); diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 0708714c659..d148ff70751 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -535,7 +535,7 @@ static struct MenuSearch_Data *menu_items_from_ui_create( RNA_pointer_create(&screen->id, &RNA_Area, area, &ptr); const int space_type_ui = RNA_property_enum_get(&ptr, prop_ui_type); - int space_type_ui_index = RNA_enum_from_value(space_type_ui_items, space_type_ui); + const int space_type_ui_index = RNA_enum_from_value(space_type_ui_items, space_type_ui); if (space_type_ui_index == -1) { continue; } @@ -952,7 +952,7 @@ static void menu_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2) case MENU_SEARCH_TYPE_RNA: { PointerRNA *ptr = &item->rna.ptr; PropertyRNA *prop = item->rna.prop; - int index = item->rna.index; + const int index = item->rna.index; const int prop_type = RNA_property_type(prop); bool changed = false; @@ -1131,7 +1131,7 @@ void UI_but_func_menu_search(uiBut *but) ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); /* When run from top-bar scan all areas in the current window. */ - bool include_all_areas = (area && (area->spacetype == SPACE_TOPBAR)); + const bool include_all_areas = (area && (area->spacetype == SPACE_TOPBAR)); struct MenuSearch_Data *data = menu_items_from_ui_create( C, win, area, region, include_all_areas); UI_but_func_search_set(but, diff --git a/source/blender/editors/interface/interface_template_search_operator.c b/source/blender/editors/interface/interface_template_search_operator.c index b8070ccbb25..76a6abe22cb 100644 --- a/source/blender/editors/interface/interface_template_search_operator.c +++ b/source/blender/editors/interface/interface_template_search_operator.c @@ -91,7 +91,7 @@ static void operator_search_update_fn(const bContext *C, if (index == words_len) { if (WM_operator_poll((bContext *)C, ot)) { char name[256]; - int len = strlen(ot_ui_name); + const int len = strlen(ot_ui_name); /* display name for menu, can hold hotkey */ BLI_strncpy(name, ot_ui_name, sizeof(name)); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 56807621358..8962755ea90 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -139,7 +139,7 @@ static void template_add_button_search_menu(const bContext *C, const bool editable, const bool live_icon) { - PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop); + const PointerRNA active_ptr = RNA_property_pointer_get(ptr, prop); ID *id = (active_ptr.data && RNA_struct_is_ID(active_ptr.type)) ? active_ptr.data : NULL; const ID *idfrom = ptr->owner_id; const StructRNA *type = active_ptr.type ? active_ptr.type : RNA_property_pointer_type(ptr, prop); @@ -164,7 +164,7 @@ static void template_add_button_search_menu(const bContext *C, but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, width, height, tip); if (use_preview_icon) { - int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type); + const int icon = id ? ui_id_icon_get(C, id, use_big_size) : RNA_struct_ui_icon(type); ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); } else { @@ -183,7 +183,7 @@ static void template_add_button_search_menu(const bContext *C, but = uiDefBlockButN(block, block_func, block_argN, "", 0, 0, UI_UNIT_X * 1.6, UI_UNIT_Y, tip); if (live_icon) { - int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type); + const int icon = id ? ui_id_icon_get(C, id, false) : RNA_struct_ui_icon(type); ui_def_but_icon(but, icon, UI_HAS_ICON | UI_BUT_ICON_PREVIEW); } else { @@ -395,11 +395,10 @@ static void id_search_cb(const bContext *C, { TemplateID *template_ui = (TemplateID *)arg_template; ListBase *lb = template_ui->idlb; - ID *id; - int flag = RNA_property_flag(template_ui->prop); + const int flag = RNA_property_flag(template_ui->prop); /* ID listbase */ - for (id = lb->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lb) { if (!id_search_add(C, template_ui, flag, str, items, id)) { break; } @@ -416,11 +415,10 @@ static void id_search_cb_tagged(const bContext *C, { TemplateID *template_ui = (TemplateID *)arg_template; ListBase *lb = template_ui->idlb; - ID *id; - int flag = RNA_property_flag(template_ui->prop); + const int flag = RNA_property_flag(template_ui->prop); /* ID listbase */ - for (id = lb->first; id; id = id->next) { + LISTBASE_FOREACH (ID *, id, lb) { if (id->tag & LIB_TAG_DOIT) { if (!id_search_add(C, template_ui, flag, str, items, id)) { break; @@ -522,7 +520,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) TemplateID *template_ui = (TemplateID *)arg_litem; PointerRNA idptr = RNA_property_pointer_get(&template_ui->ptr, template_ui->prop); ID *id = idptr.data; - int event = POINTER_AS_INT(arg_event); + const int event = POINTER_AS_INT(arg_event); const char *undo_push_label = NULL; switch (event) { @@ -572,6 +570,15 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) if (override_id != NULL) { BKE_main_id_clear_newpoins(bmain); + if (GS(override_id->name) == ID_OB) { + Scene *scene = CTX_data_scene(C); + if (!BKE_collection_has_object_recursive(scene->master_collection, + (Object *)override_id)) { + BKE_collection_object_add_from( + bmain, scene, (Object *)id, (Object *)override_id); + } + } + /* Assign new pointer, takes care of updates/notifiers */ RNA_id_pointer_create(override_id, &idptr); } @@ -1051,7 +1058,7 @@ static void template_ID(const bContext *C, RNA_int_set(but->opptr, "id_type", GS(id->name)); } else if (flag & UI_ID_OPEN) { - int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6; + const int w = id ? UI_UNIT_X : (flag & UI_ID_ADD_NEW) ? UI_UNIT_X * 3 : UI_UNIT_X * 6; if (openop) { but = uiDefIconTextButO(block, @@ -1852,13 +1859,12 @@ static void modifier_panel_id(void *md_link, char *r_name) void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C) { - ScrArea *sa = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); Object *ob = ED_object_active_context(C); ListBase *modifiers = &ob->modifiers; - bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id); + const bool panels_match = UI_panel_list_matches_data(region, modifiers, modifier_panel_id); if (!panels_match) { UI_panels_free_instanced(C, region); @@ -1876,8 +1882,7 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C) PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); RNA_pointer_create(&ob->id, &RNA_Modifier, md, md_ptr); - Panel *new_panel = UI_panel_add_instanced( - sa, region, ®ion->panels, panel_idname, i, md_ptr); + Panel *new_panel = UI_panel_add_instanced(region, ®ion->panels, panel_idname, i, md_ptr); if (new_panel != NULL) { UI_panel_set_expand_from_list_data(C, new_panel); @@ -1962,7 +1967,7 @@ static ListBase *get_constraints(const bContext *C, bool use_bone_constraints) */ static void constraint_reorder(bContext *C, Panel *panel, int new_index) { - bool constraint_from_bone = constraint_panel_is_bone(panel); + const bool constraint_from_bone = constraint_panel_is_bone(panel); ListBase *lb = get_constraints(C, constraint_from_bone); bConstraint *con = BLI_findlink(lb, panel->runtime.list_index); @@ -1982,7 +1987,7 @@ static void constraint_reorder(bContext *C, Panel *panel, int new_index) */ static short get_constraint_expand_flag(const bContext *C, Panel *panel) { - bool constraint_from_bone = constraint_panel_is_bone(panel); + const bool constraint_from_bone = constraint_panel_is_bone(panel); ListBase *lb = get_constraints(C, constraint_from_bone); bConstraint *con = BLI_findlink(lb, panel->runtime.list_index); @@ -1994,7 +1999,7 @@ static short get_constraint_expand_flag(const bContext *C, Panel *panel) */ static void set_constraint_expand_flag(const bContext *C, Panel *panel, short expand_flag) { - bool constraint_from_bone = constraint_panel_is_bone(panel); + const bool constraint_from_bone = constraint_panel_is_bone(panel); ListBase *lb = get_constraints(C, constraint_from_bone); bConstraint *con = BLI_findlink(lb, panel->runtime.list_index); @@ -2030,7 +2035,6 @@ static void bone_constraint_panel_id(void *md_link, char *r_name) */ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_constraints) { - ScrArea *sa = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); Object *ob = ED_object_active_context(C); @@ -2040,7 +2044,7 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_ uiListPanelIDFromDataFunc panel_id_func = use_bone_constraints ? bone_constraint_panel_id : object_constraint_panel_id; - bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func); + const bool panels_match = UI_panel_list_matches_data(region, constraints, panel_id_func); if (!panels_match) { UI_panels_free_instanced(C, region); @@ -2053,8 +2057,7 @@ void uiTemplateConstraints(uiLayout *UNUSED(layout), bContext *C, bool use_bone_ PointerRNA *con_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); RNA_pointer_create(&ob->id, &RNA_Constraint, con, con_ptr); - Panel *new_panel = UI_panel_add_instanced( - sa, region, ®ion->panels, panel_idname, i, con_ptr); + Panel *new_panel = UI_panel_add_instanced(region, ®ion->panels, panel_idname, i, con_ptr); if (new_panel) { /* Set the list panel functionality function pointers since we don't do it with python. */ @@ -2112,12 +2115,12 @@ static void gpencil_modifier_panel_id(void *md_link, char *r_name) void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C) { - ScrArea *sa = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); Object *ob = ED_object_active_context(C); ListBase *modifiers = &ob->greasepencil_modifiers; - bool panels_match = UI_panel_list_matches_data(region, modifiers, gpencil_modifier_panel_id); + const bool panels_match = UI_panel_list_matches_data( + region, modifiers, gpencil_modifier_panel_id); if (!panels_match) { UI_panels_free_instanced(C, region); @@ -2135,8 +2138,7 @@ void uiTemplateGpencilModifiers(uiLayout *UNUSED(layout), bContext *C) PointerRNA *md_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); RNA_pointer_create(&ob->id, &RNA_GpencilModifier, md, md_ptr); - Panel *new_panel = UI_panel_add_instanced( - sa, region, ®ion->panels, panel_idname, i, md_ptr); + Panel *new_panel = UI_panel_add_instanced(region, ®ion->panels, panel_idname, i, md_ptr); if (new_panel != NULL) { UI_panel_set_expand_from_list_data(C, new_panel); @@ -2201,12 +2203,11 @@ static void shaderfx_panel_id(void *fx_v, char *r_idname) */ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C) { - ScrArea *sa = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); Object *ob = ED_object_active_context(C); ListBase *shaderfx = &ob->shader_fx; - bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id); + const bool panels_match = UI_panel_list_matches_data(region, shaderfx, shaderfx_panel_id); if (!panels_match) { UI_panels_free_instanced(C, region); @@ -2219,8 +2220,7 @@ void uiTemplateShaderFx(uiLayout *UNUSED(layout), bContext *C) PointerRNA *fx_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata"); RNA_pointer_create(&ob->id, &RNA_ShaderFx, fx, fx_ptr); - Panel *new_panel = UI_panel_add_instanced( - sa, region, ®ion->panels, panel_idname, i, fx_ptr); + Panel *new_panel = UI_panel_add_instanced(region, ®ion->panels, panel_idname, i, fx_ptr); if (new_panel != NULL) { UI_panel_set_expand_from_list_data(C, new_panel); @@ -2303,7 +2303,7 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( eAutoPropButsReturn return_info = 0; if (!op->properties) { - IDPropertyTemplate val = {0}; + const IDPropertyTemplate val = {0}; op->properties = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } @@ -2411,9 +2411,8 @@ static eAutoPropButsReturn template_operator_property_buts_draw_single( /* Only do this if we're not refreshing an existing UI. */ if (block->oldblock == NULL) { const bool is_popup = (block->flag & UI_BLOCK_KEEP_OPEN) != 0; - uiBut *but; - for (but = block->buttons.first; but; but = but->next) { + LISTBASE_FOREACH (uiBut *, but, &block->buttons) { /* no undo for buttons for operator redo panels */ UI_but_flag_disable(but, UI_BUT_UNDO); @@ -3029,8 +3028,8 @@ static void colorband_distribute_cb(bContext *C, ColorBand *coba, bool evenly) { if (coba->tot > 1) { int a; - int tot = evenly ? coba->tot - 1 : coba->tot; - float gap = 1.0f / tot; + const int tot = evenly ? coba->tot - 1 : coba->tot; + const float gap = 1.0f / tot; float pos = 0.0f; for (a = 0; a < coba->tot; a++) { coba->data[a].pos = pos; @@ -3212,9 +3211,9 @@ static void colorband_buttons_layout(uiLayout *layout, { uiLayout *row, *split, *subsplit; uiBut *bt; - float unit = BLI_rctf_size_x(butr) / 14.0f; - float xs = butr->xmin; - float ys = butr->ymin; + const float unit = BLI_rctf_size_x(butr) / 14.0f; + const float xs = butr->xmin; + const float ys = butr->ymin; PointerRNA ptr; RNA_pointer_create(cb->ptr.owner_id, &RNA_ColorRamp, coba, &ptr); @@ -3887,7 +3886,7 @@ static uiBlock *curvemap_clipping_func(bContext *C, ARegion *region, void *cumap CurveMapping *cumap = cumap_v; uiBlock *block; uiBut *bt; - float width = 8 * UI_UNIT_X; + const float width = 8 * UI_UNIT_X; block = UI_block_begin(C, region, __func__, UI_EMBOSS); UI_block_flag_enable(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_MOVEMOUSE_QUIT); @@ -4229,7 +4228,7 @@ static void curvemap_buttons_layout(uiLayout *layout, uiLayout *row, *sub, *split; uiBlock *block; uiBut *bt; - float dx = UI_UNIT_X; + const float dx = UI_UNIT_X; int icon, size; int bg = -1, i; @@ -4702,7 +4701,7 @@ static uiBlock *CurveProfile_tools_func(bContext *C, ARegion *region, CurveProfi { uiBlock *block; short yco = 0; - short menuwidth = 10 * UI_UNIT_X; + const short menuwidth = 10 * UI_UNIT_X; block = UI_block_begin(C, region, __func__, UI_EMBOSS); UI_block_func_butmenu_set(block, CurveProfile_tools_dofunc, profile); @@ -5406,13 +5405,12 @@ void uiTemplatePalette(uiLayout *layout, PropertyRNA *prop = RNA_struct_find_property(ptr, propname); PointerRNA cptr; Palette *palette; - PaletteColor *color; uiBlock *block; uiLayout *col; uiBut *but = NULL; int row_cols = 0, col_id = 0; - int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1); + const int cols_per_row = MAX2(uiLayoutGetWidth(layout) / UI_UNIT_X, 1); if (!prop) { RNA_warning("property not found: %s.%s", RNA_struct_identifier(ptr->type), propname); @@ -5428,8 +5426,6 @@ void uiTemplatePalette(uiLayout *layout, palette = cptr.data; - color = palette->colors.first; - col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); uiDefIconButO(block, @@ -5452,7 +5448,7 @@ void uiTemplatePalette(uiLayout *layout, UI_UNIT_X, UI_UNIT_Y, NULL); - if (color) { + if (palette->colors.first != NULL) { but = uiDefIconButO(block, UI_BTYPE_BUT, "PALETTE_OT_color_move", @@ -5487,7 +5483,7 @@ void uiTemplatePalette(uiLayout *layout, col = uiLayoutColumn(layout, true); uiLayoutRow(col, true); - for (; color; color = color->next) { + LISTBASE_FOREACH (PaletteColor *, color, &palette->colors) { PointerRNA color_ptr; if (row_cols >= cols_per_row) { @@ -5561,7 +5557,7 @@ void uiTemplateCryptoPicker(uiLayout *layout, PointerRNA *ptr, const char *propn static void handle_layer_buttons(bContext *C, void *arg1, void *arg2) { uiBut *but = arg1; - int cur = POINTER_AS_INT(arg2); + const int cur = POINTER_AS_INT(arg2); wmWindow *win = CTX_wm_window(C); int i, tot, shift = win->eventstate->shift; @@ -5596,7 +5592,7 @@ void uiTemplateLayers(uiLayout *layout, PropertyRNA *prop, *used_prop = NULL; int groups, cols, layers; int group, col, layer, row; - int cols_per_group = 5; + const int cols_per_group = 5; prop = RNA_struct_find_property(ptr, propname); if (!prop) { @@ -5644,7 +5640,7 @@ void uiTemplateLayers(uiLayout *layout, /* add layers as toggle buts */ for (col = 0; (col < cols_per_group) && (layer < layers); col++, layer++) { int icon = 0; - int butlay = 1 << layer; + const int butlay = 1 << layer; if (active_layer & butlay) { icon = ICON_LAYER_ACTIVE; @@ -5759,7 +5755,7 @@ static void uilist_filter_items_default(struct uiList *ui_list, const bool filter_exclude = (ui_list->filter_flag & UILST_FLT_EXCLUDE) != 0; const bool order_by_name = (ui_list->filter_sort_flag & UILST_FLT_SORT_MASK) == UILST_FLT_SORT_ALPHA; - int len = RNA_property_collection_length(dataptr, prop); + const int len = RNA_property_collection_length(dataptr, prop); dyn_data->items_shown = dyn_data->items_len = len; @@ -5771,7 +5767,7 @@ static void uilist_filter_items_default(struct uiList *ui_list, names = MEM_callocN(sizeof(StringCmp) * len, "StringCmp"); } if (filter_raw[0]) { - size_t slen = strlen(filter_raw); + const size_t slen = strlen(filter_raw); dyn_data->items_filter_flags = MEM_callocN(sizeof(int) * len, "items_filter_flags"); dyn_data->items_shown = 0; @@ -6209,8 +6205,8 @@ void uiTemplateList(uiLayout *layout, for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { PointerRNA *itemptr = &items_ptr[i].item; void *dyntip_data; - int org_i = items_ptr[i].org_idx; - int flt_flag = items_ptr[i].flt_flag; + const int org_i = items_ptr[i].org_idx; + const int flt_flag = items_ptr[i].flt_flag; subblock = uiLayoutGetBlock(col); overlap = uiLayoutOverlap(col); @@ -6296,7 +6292,7 @@ void uiTemplateList(uiLayout *layout, if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && (activei >= 0) && (activei < dyn_data->items_shown)) { PointerRNA *itemptr = &items_ptr[activei].item; - int org_i = items_ptr[activei].org_idx; + const int org_i = items_ptr[activei].org_idx; icon = UI_rnaptr_icon_get(C, itemptr, rnaicon, false); if (icon == ICON_DOT) { @@ -6346,8 +6342,8 @@ void uiTemplateList(uiLayout *layout, /* create list items */ for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { PointerRNA *itemptr = &items_ptr[i].item; - int org_i = items_ptr[i].org_idx; - int flt_flag = items_ptr[i].flt_flag; + const int org_i = items_ptr[i].org_idx; + const int flt_flag = items_ptr[i].flt_flag; /* create button */ if (!(i % columns)) { @@ -6641,9 +6637,8 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) UI_block_func_handle_set(block, do_running_jobs, NULL); - Scene *scene; /* another scene can be rendering too, for example via compositor */ - for (scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) { handle_event = B_STOPOTHER; icon = ICON_NONE; @@ -6736,7 +6731,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) if (owner) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; - bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner)); + const bool active = !(G.is_break || WM_jobs_is_stopped(wm, owner)); uiLayout *row = uiLayoutRow(layout, false); block = uiLayoutGetBlock(row); @@ -7084,7 +7079,7 @@ bool uiTemplateEventFromKeymapItem(struct uiLayout *layout, #ifdef WITH_HEADLESS int icon = 0; #else - int icon = UI_icon_from_keymap_item(kmi, icon_mod); + const int icon = UI_icon_from_keymap_item(kmi, icon_mod); #endif if (icon != 0) { for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) { @@ -7357,10 +7352,12 @@ void uiTemplateCacheFile(uiLayout *layout, int uiTemplateRecentFiles(uiLayout *layout, int rows) { - const RecentFile *recent; int i; + LISTBASE_FOREACH_INDEX (RecentFile *, recent, &G.recent_files, i) { + if (i >= rows) { + break; + } - for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) { const char *filename = BLI_path_basename(recent->filepath); PointerRNA ptr; uiItemFullO(layout, diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 4a1c7be918e..c413cac6023 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -249,7 +249,7 @@ uiBut *uiDefAutoButR(uiBlock *block, break; case PROP_POINTER: { if (icon == 0) { - PointerRNA pptr = RNA_property_pointer_get(ptr, prop); + const PointerRNA pptr = RNA_property_pointer_get(ptr, prop); icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop)); } if (icon == ICON_DOT) { @@ -436,7 +436,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C, int name_prefix_offset = 0; int iconid = ICON_NONE; bool has_sep_char = false; - bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type); + const bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type); if (is_id) { iconid = ui_id_icon_get(C, itemptr.data, false); @@ -489,7 +489,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C, /* If no item has an own icon to display, libraries can use the library icons rather than the * name prefix for showing the library status. */ int name_prefix_offset = cis->name_prefix_offset; - if (!has_id_icon && cis->is_id) { + if (!has_id_icon && cis->is_id && !requires_exact_data_name) { cis->iconid = UI_library_icon_get(cis->data); /* No need to re-allocate, string should be shorter than before (lib status prefix is * removed). */ @@ -714,12 +714,8 @@ bool UI_butstore_is_valid(uiButStore *bs) bool UI_butstore_is_registered(uiBlock *block, uiBut *but) { - uiButStore *bs_handle; - - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p == but) { return true; } @@ -740,10 +736,7 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p) void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) { - uiButStoreElem *bs_elem, *bs_elem_next; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem_next) { - bs_elem_next = bs_elem->next; + LISTBASE_FOREACH_MUTABLE (uiButStoreElem *, bs_elem, &bs_handle->items) { if (bs_elem->but_p == but_p) { BLI_remlink(&bs_handle->items, bs_elem); MEM_freeN(bs_elem); @@ -758,12 +751,10 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p) */ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src) { - uiButStore *bs_handle; bool found = false; - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p == but_src) { *bs_elem->but_p = but_dst; found = true; @@ -779,14 +770,9 @@ bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *bu */ void UI_butstore_clear(uiBlock *block) { - uiButStore *bs_handle; - - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - uiButStoreElem *bs_elem; - + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { bs_handle->block = NULL; - - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { *bs_elem->but_p = NULL; } } @@ -797,8 +783,6 @@ void UI_butstore_clear(uiBlock *block) */ void UI_butstore_update(uiBlock *block) { - uiButStore *bs_handle; - /* move this list to the new block */ if (block->oldblock) { if (block->oldblock->butstore.first) { @@ -812,17 +796,14 @@ void UI_butstore_update(uiBlock *block) /* warning, loop-in-loop, in practice we only store <10 buttons at a time, * so this isn't going to be a problem, if that changes old-new mapping can be cached first */ - for (bs_handle = block->butstore.first; bs_handle; bs_handle = bs_handle->next) { - + LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) || (block->oldblock && block->oldblock == bs_handle->block)); if (bs_handle->block == block->oldblock) { - uiButStoreElem *bs_elem; - bs_handle->block = block; - for (bs_elem = bs_handle->items.first; bs_elem; bs_elem = bs_elem->next) { + LISTBASE_FOREACH (uiButStoreElem *, bs_elem, &bs_handle->items) { if (*bs_elem->but_p) { uiBut *but_new = ui_but_find_new(block, *bs_elem->but_p); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c4de2730600..ab0f6d90caa 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -29,6 +29,7 @@ #include "DNA_brush_types.h" #include "DNA_userdef_types.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_string.h" @@ -474,7 +475,7 @@ GPUBatch *ui_batch_roundbox_shadow_get(void) uint32_t last_data; GPUVertBufRaw vflag_step; GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format()); - int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX; + const int vcount = (WIDGET_SIZE_MAX + 1) * 2 + 2 + WIDGET_SIZE_MAX; GPU_vertbuf_data_alloc(vbo, vcount); GPU_vertbuf_attr_get_raw_data(vbo, g_ui_batch_cache.vflag_id, &vflag_step); @@ -525,9 +526,10 @@ void UI_draw_anti_tria( /* Note: This won't give back the original color. */ draw_color[3] *= 1.0f / WIDGET_AA_JITTER; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(draw_color); @@ -544,19 +546,19 @@ void UI_draw_anti_tria( immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* triangle 'icon' inside rect */ void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]) { if (dir == 'h') { - float half = 0.5f * BLI_rctf_size_y(rect); + const float half = 0.5f * BLI_rctf_size_y(rect); UI_draw_anti_tria( rect->xmin, rect->ymin, rect->xmin, rect->ymax, rect->xmax, rect->ymin + half, color); } else { - float half = 0.5f * BLI_rctf_size_x(rect); + const float half = 0.5f * BLI_rctf_size_x(rect); UI_draw_anti_tria( rect->xmin, rect->ymax, rect->xmax, rect->ymax, rect->xmin + half, rect->ymin, color); } @@ -569,9 +571,10 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4]) copy_v4_v4(draw_color, color); draw_color[3] *= 2.0f / WIDGET_AA_JITTER; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(draw_color); @@ -593,7 +596,7 @@ void UI_draw_anti_fan(float tri_array[][2], uint length, const float color[4]) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void widget_init(uiWidgetBase *wtb) @@ -705,14 +708,14 @@ static void round_box__edges( uiWidgetBase *wt, int roundboxalign, const rcti *rect, float rad, float radi) { float vec[WIDGET_CURVE_RESOLU][2], veci[WIDGET_CURVE_RESOLU][2]; - float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax; - float minxi = minx + U.pixelsize; /* boundbox inner */ - float maxxi = maxx - U.pixelsize; - float minyi = miny + U.pixelsize; - float maxyi = maxy - U.pixelsize; + const float minx = rect->xmin, miny = rect->ymin, maxx = rect->xmax, maxy = rect->ymax; + const float minxi = minx + U.pixelsize; /* boundbox inner */ + const float maxxi = maxx - U.pixelsize; + const float minyi = miny + U.pixelsize; + const float maxyi = maxy - U.pixelsize; /* for uv, can divide by zero */ - float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; - float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f; + const float facxi = (maxxi != minxi) ? 1.0f / (maxxi - minxi) : 0.0f; + const float facyi = (maxyi != minyi) ? 1.0f / (maxyi - minyi) : 0.0f; int a, tot = 0, minsize; const int hnum = ((roundboxalign & (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT)) == (UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT) || @@ -1011,8 +1014,8 @@ static void widget_draw_vertex_buffer(uint pos, static void shape_preset_trias_from_rect_menu(uiWidgetTrias *tria, const rcti *rect) { - float width = BLI_rcti_size_x(rect); - float height = BLI_rcti_size_y(rect); + const float width = BLI_rcti_size_x(rect); + const float height = BLI_rcti_size_y(rect); float centx, centy, size; tria->type = ROUNDBOX_TRIA_MENU; @@ -1095,7 +1098,8 @@ static void widgetbase_outline(uiWidgetBase *wtb, uint pos) float triangle_strip[WIDGET_SIZE_MAX * 2 + 2][2]; /* + 2 because the last pair is wrapped */ widget_verts_to_triangle_strip(wtb, wtb->totvert, triangle_strip); - widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2); + widget_draw_vertex_buffer( + pos, 0, GPU_PRIM_TRI_STRIP, triangle_strip, NULL, wtb->totvert * 2 + 2); } static void widgetbase_set_uniform_alpha_discard(uiWidgetBase *wtb, @@ -1118,7 +1122,7 @@ static void widgetbase_set_uniform_alpha_check(uiWidgetBase *wtb, const bool alp static void widgetbase_set_uniform_discard_factor(uiWidgetBase *wtb, const float discard_factor) { - bool alpha_check = wtb->uniform_params.alpha_discard < 0.0f; + const bool alpha_check = wtb->uniform_params.alpha_discard < 0.0f; widgetbase_set_uniform_alpha_discard(wtb, alpha_check, discard_factor); } @@ -1170,7 +1174,7 @@ void UI_widgetbase_draw_cache_flush(void) /* draw single */ GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GPU_batch_uniform_4fv_array( - batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)g_widget_base_batch.params); + batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4])g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_batch_draw(batch); } @@ -1179,14 +1183,9 @@ void UI_widgetbase_draw_cache_flush(void) GPU_batch_uniform_4fv_array(batch, "parameters", MAX_WIDGET_PARAMETERS * MAX_WIDGET_BASE_BATCH, - (float *)g_widget_base_batch.params); + (float(*)[4])g_widget_base_batch.params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); - GPU_matrix_bind(batch->interface); - GPU_shader_set_srgb_uniform(batch->interface); - GPU_batch_bind(batch); - GPU_batch_draw_advanced(batch, 0, 0, 0, g_widget_base_batch.count); - - GPU_batch_program_use_end(batch); + GPU_batch_draw_instanced(batch, g_widget_base_batch.count); } g_widget_base_batch.count = 0; } @@ -1202,11 +1201,11 @@ void UI_widgetbase_draw_cache_end(void) BLI_assert(g_widget_base_batch.enabled == true); g_widget_base_batch.enabled = false; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Disable cached/instanced drawing and enforce single widget drawing pipeline. @@ -1252,7 +1251,7 @@ static void draw_widgetbase_batch(uiWidgetBase *wtb) GPUBatch *batch = ui_batch_roundbox_widget_get(); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_WIDGET_BASE); GPU_batch_uniform_4fv_array( - batch, "parameters", MAX_WIDGET_PARAMETERS, (float *)&wtb->uniform_params); + batch, "parameters", MAX_WIDGET_PARAMETERS, (float(*)[4]) & wtb->uniform_params); GPU_batch_uniform_3fv(batch, "checkerColorAndSize", checker_params); GPU_batch_draw(batch); } @@ -1312,9 +1311,9 @@ static void widgetbase_draw_ex(uiWidgetBase *wtb, widgetbase_set_uniform_colors_ubv( wtb, inner_col1, inner_col2, outline_col, emboss_col, tria_col, show_alpha_checkers); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); draw_widgetbase_batch(wtb); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1347,8 +1346,8 @@ static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect) size -= PREVIEW_PAD * 2; /* padding */ if (size > 0) { - int x = rect->xmin + w / 2 - size / 2; - int y = rect->ymin + h / 2 - size / 2; + const int x = rect->xmin + w / 2 - size / 2; + const int y = rect->ymin + h / 2 - size / 2; UI_icon_draw_preview(x, y, icon, 1.0f, alpha, size); } @@ -1368,9 +1367,9 @@ static void widget_draw_icon( float aspect, height; if (but->flag & UI_BUT_ICON_PREVIEW) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(icon, alpha, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); return; } @@ -1406,10 +1405,10 @@ static void widget_draw_icon( } } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (icon && icon != ICON_BLANK1) { - float ofs = 1.0f / aspect; + const float ofs = 1.0f / aspect; if (but->drawflag & UI_BUT_ICON_LEFT) { /* special case - icon_only pie buttons */ @@ -1437,7 +1436,7 @@ static void widget_draw_icon( /* Get theme color. */ uchar color[4] = {mono_color[0], mono_color[1], mono_color[2], mono_color[3]}; - bool has_theme = UI_icon_get_theme_color(icon, color); + const bool has_theme = UI_icon_get_theme_color(icon, color); /* to indicate draggable */ if (but->dragpoin && (but->flag & UI_ACTIVE)) { @@ -1459,7 +1458,7 @@ static void widget_draw_icon( } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void widget_draw_submenu_tria(const uiBut *but, @@ -1480,16 +1479,16 @@ static void widget_draw_submenu_tria(const uiBut *but, BLI_rctf_init(&tria_rect, xs, xs + tria_width, ys, ys + tria_height); BLI_rctf_scale(&tria_rect, 0.4f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); ui_draw_anti_tria_rect(&tria_rect, 'h', col); } static void ui_text_clip_give_prev_off(uiBut *but, const char *str) { const char *prev_utf8 = BLI_str_find_prev_char_utf8(str, str + but->ofs); - int bytes = str + but->ofs - prev_utf8; + const int bytes = str + but->ofs - prev_utf8; but->ofs -= bytes; } @@ -1497,7 +1496,7 @@ static void ui_text_clip_give_prev_off(uiBut *but, const char *str) static void ui_text_clip_give_next_off(uiBut *but, const char *str) { const char *next_utf8 = BLI_str_find_next_char_utf8(str + but->ofs, NULL); - int bytes = next_utf8 - (str + but->ofs); + const int bytes = next_utf8 - (str + but->ofs); but->ofs += bytes; } @@ -1826,7 +1825,7 @@ static void ui_text_clip_right_label(const uiFontStyle *fstyle, uiBut *but, cons /* chop off the leading text, starting from the right */ while (but->strwidth > okwidth && cp2 > but->drawstr) { const char *prev_utf8 = BLI_str_find_prev_char_utf8(but->drawstr, cp2); - int bytes = cp2 - prev_utf8; + const int bytes = cp2 - prev_utf8; /* shift the text after and including cp2 back by 1 char, * +1 to include null terminator */ @@ -2027,9 +2026,9 @@ static void widget_draw_text(const uiFontStyle *fstyle, if (drawstr[0] != 0) { /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (but->selsta >= but->ofs) { selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs); @@ -2074,9 +2073,9 @@ static void widget_draw_text(const uiFontStyle *fstyle, t = 0; } /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -2247,7 +2246,7 @@ static void widget_draw_extra_icons(const uiWidgetColors *wcol, float alpha) { /* inverse order, from right to left. */ - for (uiButExtraOpIcon *op_icon = but->extra_op_icons.last; op_icon; op_icon = op_icon->prev) { + LISTBASE_FOREACH_BACKWARD (uiButExtraOpIcon *, op_icon, &but->extra_op_icons) { rcti temp = *rect; temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f); @@ -2271,9 +2270,9 @@ static void widget_draw_node_link_socket(const uiWidgetColors *wcol, rgba_uchar_to_float(col, but->col); col[3] *= alpha; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); ED_node_socket_draw(but->custom_data, rect, col, scale); } @@ -2289,7 +2288,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, rcti *rect) { const bool show_menu_icon = ui_but_draw_menu_icon(but); - float alpha = (float)wcol->text[3] / 255.0f; + const float alpha = (float)wcol->text[3] / 255.0f; char password_str[UI_MAX_DRAW_STR]; bool no_text_padding = but->drawflag & UI_BUT_NO_TEXT_PADDING; @@ -2332,9 +2331,9 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, /* draw icon in rect above the space reserved for the label */ rect->ymin += text_size; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(icon, alpha, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* offset rect to draw label in */ rect->ymin -= text_size; @@ -2357,7 +2356,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, #endif const BIFIconID icon = ui_but_icon(but); - int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT; + const int icon_size_init = is_tool ? ICON_DEFAULT_HEIGHT_TOOLBAR : ICON_DEFAULT_HEIGHT; const float icon_size = icon_size_init / (but->block->aspect * U.inv_dpi_fac); const float icon_padding = 2 * UI_DPI_FAC; @@ -2402,7 +2401,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, rect->xmin += text_padding; } else if (but->flag & UI_BUT_DRAG_MULTI) { - bool text_is_edited = ui_but_drag_multi_edit_get(but) != NULL; + const bool text_is_edited = ui_but_drag_multi_edit_get(but) != NULL; if (text_is_edited || (but->drawflag & UI_BUT_TEXT_LEFT)) { rect->xmin += text_padding; } @@ -2490,7 +2489,7 @@ static void ui_widget_color_disabled(uiWidgetType *wt) static void widget_active_color(uiWidgetColors *wcol) { - bool dark = (rgb_to_grayscale_byte(wcol->text) > rgb_to_grayscale_byte(wcol->inner)); + const bool dark = (rgb_to_grayscale_byte(wcol->text) > rgb_to_grayscale_byte(wcol->inner)); color_mul_hsl_v3(wcol->inner, 1.0f, 1.15f, dark ? 1.2f : 1.1f); color_mul_hsl_v3(wcol->outline, 1.0f, 1.15f, 1.15f); color_mul_hsl_v3(wcol->text, 1.0f, 1.15f, dark ? 1.25f : 0.8f); @@ -2749,12 +2748,13 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r /* we draw a number of increasing size alpha quad strips */ alphastep = 3.0f * btheme->tui.menu_shadow_fac / radout; - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); for (step = 1; step <= (int)radout; step++) { - float expfac = sqrtf(step / radout); + const float expfac = sqrtf(step / radout); round_box_shadow_edges(wtb.outer_v, &rect1, radin, UI_CNR_ALL, (float)step); @@ -2762,7 +2762,7 @@ static void widget_softshadow(const rcti *rect, int roundboxalign, const float r widget_verts_to_triangle_strip(&wtb, totvert, triangle_strip); - widget_draw_vertex_buffer(pos, 0, GL_TRIANGLE_STRIP, triangle_strip, NULL, totvert * 2); + widget_draw_vertex_buffer(pos, 0, GPU_PRIM_TRI_STRIP, triangle_strip, NULL, totvert * 2); } immUnbindProgram(); @@ -2789,32 +2789,31 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir rect->ymax += 0.1f * U.widget_unit; } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_softshadow(rect, roundboxalign, wcol->roundness * U.widget_unit); round_box_edges(&wtb, roundboxalign, rect, wcol->roundness * U.widget_unit); wtb.draw_emboss = false; widgetbase_draw(&wtb, wcol); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void ui_hsv_cursor(float x, float y) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(1.0f, 1.0f, 1.0f); imm_draw_circle_fill_2d(pos, x, y, 3.0f * U.pixelsize, 8); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); immUniformColor3f(0.0f, 0.0f, 0.0f); imm_draw_circle_wire_2d(pos, x, y, 3.0f * U.pixelsize, 12); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -2866,11 +2865,11 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const const float radstep = 2.0f * (float)M_PI / (float)tot; const float centx = BLI_rcti_cent_x_fl(rect); const float centy = BLI_rcti_cent_y_fl(rect); - float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; ColorPicker *cpicker = but->custom_data; float rgb[3], hsv[3], rgb_center[3]; - bool is_color_gamma = ui_but_is_color_gamma(but); + const bool is_color_gamma = ui_but_is_color_gamma(but); /* Initialize for compatibility. */ copy_v3_v3(hsv, cpicker->color_data); @@ -2904,7 +2903,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + const uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); @@ -2914,8 +2913,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const float ang = 0.0f; for (int a = 0; a <= tot; a++, ang += radstep) { - float si = sinf(ang); - float co = cosf(ang); + const float si = sinf(ang); + const float co = cosf(ang); float hsv_ang[3]; float rgb_ang[3]; @@ -2942,7 +2941,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); immUniformColor3ubv(wcol->outline); @@ -2950,7 +2949,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); /* cursor */ @@ -2980,7 +2979,7 @@ void ui_draw_gradient(const rcti *rect, const int steps = 48; const float color_step = 1.0f / steps; int a; - float h = hsv[0], s = hsv[1], v = hsv[2]; + const float h = hsv[0], s = hsv[1], v = hsv[2]; float dx, dy, sx1, sx2, sy; float col0[4][3]; /* left half, rect bottom to top */ float col1[4][3]; /* right half, rect bottom to top */ @@ -3035,8 +3034,8 @@ void ui_draw_gradient(const rcti *rect, /* old below */ GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); immBegin(GPU_PRIM_TRIS, steps * 3 * 6); @@ -3198,7 +3197,8 @@ static void ui_draw_but_HSVCUBE(uiBut *but, const rcti *rect) ui_hsv_cursor(x, y); /* outline */ - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3ub(0, 0, 0); imm_draw_box_wire_2d(pos, (rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax)); @@ -3229,7 +3229,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) /* map v from property range to [0,1] */ if (hsv_but->gradient_type == UI_GRAD_V_ALT) { - float min = but->softmin, max = but->softmax; + const float min = but->softmin, max = but->softmax; v = (v - min) / (max - min); } @@ -3249,9 +3249,9 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) })); /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* cursor */ x = rect->xmin + 0.5f * BLI_rcti_size_x(rect); @@ -3264,7 +3264,7 @@ static void ui_draw_but_HSV_v(uiBut *but, const rcti *rect) /** Separator for menus. */ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol) { - int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1; + const int y = rect->ymin + BLI_rcti_size_y(rect) / 2 - 1; const uchar col[4] = { wcol->text[0], wcol->text[1], @@ -3272,10 +3272,11 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol) 30, }; - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ubv(col); GPU_line_width(1.0f); @@ -3284,7 +3285,7 @@ static void ui_draw_separator(const rcti *rect, const uiWidgetColors *wcol) immVertex2f(pos, rect->xmax, y); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -3624,8 +3625,8 @@ static void widget_progressbar( widget_init(&wtb_bar); /* round corners */ - float value = but_progressbar->progress; - float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog); + const float value = but_progressbar->progress; + const float offs = wcol->roundness * BLI_rcti_size_y(&rect_prog); float w = value * BLI_rcti_size_x(&rect_prog); /* ensure minimium size */ @@ -3652,7 +3653,7 @@ static void widget_nodesocket( uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) { uiWidgetBase wtb; - int radi = 5; + const int radi = 5; uchar old_inner[3], old_outline[3]; widget_init(&wtb); @@ -3668,8 +3669,8 @@ static void widget_nodesocket( wcol->outline[2] = 0; wcol->outline[3] = 150; - int cent_x = BLI_rcti_cent_x(rect); - int cent_y = BLI_rcti_cent_y(rect); + const int cent_x = BLI_rcti_cent_x(rect); + const int cent_y = BLI_rcti_cent_y(rect); rect->xmin = cent_x - radi; rect->xmax = cent_x + radi; rect->ymin = cent_y - radi; @@ -3717,7 +3718,7 @@ static void widget_numslider( rect1 = *rect; float factor, factor_ui; float factor_discard = 1.0f; /* No discard. */ - float value = (float)ui_but_value_get(but); + const float value = (float)ui_but_value_get(but); if (but->rnaprop && (RNA_property_subtype(but->rnaprop) == PROP_PERCENTAGE)) { factor = value / but->softmax; @@ -3726,7 +3727,7 @@ static void widget_numslider( factor = (value - but->softmin) / (but->softmax - but->softmin); } - float width = (float)BLI_rcti_size_x(rect); + const float width = (float)BLI_rcti_size_x(rect); factor_ui = factor * width; if (factor_ui <= offs) { @@ -3834,19 +3835,20 @@ static void widget_swatch( widgetbase_draw_ex(&wtb, wcol, show_alpha_checkers); if (color_but->is_pallete_color && ((Palette *)but->rnapoin.owner_id)->active_color == color_but->palette_color_index) { - float width = rect->xmax - rect->xmin; - float height = rect->ymax - rect->ymin; + const float width = rect->xmax - rect->xmin; + const float height = rect->ymax - rect->ymin; /* find color luminance and change it slightly */ float bw = rgb_to_grayscale(col); bw += (bw < 0.5f) ? 0.5f : -0.5f; /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3f(bw, bw, bw); @@ -3974,7 +3976,7 @@ static void widget_menu_radial_itembut( { uiWidgetBase wtb; float rad; - float fac = but->block->pie_data.alphafac; + const float fac = but->block->pie_data.alphafac; widget_init(&wtb); @@ -4016,7 +4018,7 @@ static void widget_optionbut(uiWidgetColors *wcol, int state, int UNUSED(roundboxalign)) { - bool text_before_widget = (state & UI_STATE_TEXT_BEFORE_WIDGET); + const bool text_before_widget = (state & UI_STATE_TEXT_BEFORE_WIDGET); uiWidgetBase wtb; rcti recttemp = *rect; float rad; @@ -4206,9 +4208,9 @@ static void widget_tab(uiWidgetColors *wcol, rcti *rect, int state, int roundbox widgetbase_draw(&wtb, wcol); /* We are drawing on top of widget bases. Flush cache. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_widgetbase_draw_cache_flush(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); #ifdef USE_TAB_SHADED_HIGHLIGHT /* draw outline (3d look) */ @@ -4238,7 +4240,8 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType * but->block->drawextra( C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect); - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* make mask to draw over image */ @@ -4480,7 +4483,7 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) /* align with open menu */ if (but->active && (but->type != UI_BTYPE_POPOVER) && !ui_but_menu_draw_as_popover(but)) { - int direction = ui_but_menu_direction(but); + const int direction = ui_but_menu_direction(but); if (direction == UI_DIR_UP) { roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); @@ -4823,12 +4826,12 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu } if (disabled) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } wt->text(fstyle, &wt->wcol, but, rect); if (disabled) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -4911,7 +4914,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, rect->xmax - unit_size) : BLI_rcti_cent_x(rect); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Extracted from 'widget_menu_back', keep separate to avoid menu changes breaking popovers */ { @@ -4928,14 +4931,15 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, /* Draw popover arrow (top/bottom) */ if (ELEM(direction, UI_DIR_UP, UI_DIR_DOWN)) { - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add( + immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); const bool is_down = (direction == UI_DIR_DOWN); const int sign = is_down ? 1 : -1; float y = is_down ? rect->ymax : rect->ymin; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ub(UNPACK3(wcol->outline), 166); immVertex2f(pos, cent_x - unit_half, y); @@ -4945,7 +4949,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, y = y - sign * round(U.pixelsize * 1.41); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ub(0, 0, 0, 0); immVertex2f(pos, cent_x - unit_half, y); @@ -4953,7 +4957,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, immVertex2f(pos, cent_x, y + sign * unit_half); immEnd(); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBegin(GPU_PRIM_TRIS, 3); immUniformColor4ubv(wcol->inner); immVertex2f(pos, cent_x - unit_half, y); @@ -4964,7 +4968,7 @@ static void ui_draw_popover_back_impl(const uiWidgetColors *wcol, immUnbindProgram(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ui_draw_popover_back(struct ARegion *region, @@ -5049,23 +5053,23 @@ static void draw_disk_shaded(float start, void ui_draw_pie_center(uiBlock *block) { bTheme *btheme = UI_GetTheme(); - float cx = block->pie_data.pie_center_spawned[0]; - float cy = block->pie_data.pie_center_spawned[1]; + const float cx = block->pie_data.pie_center_spawned[0]; + const float cy = block->pie_data.pie_center_spawned[1]; float *pie_dir = block->pie_data.pie_dir; - float pie_radius_internal = U.dpi_fac * U.pie_menu_threshold; - float pie_radius_external = U.dpi_fac * (U.pie_menu_threshold + 7.0f); + const float pie_radius_internal = U.dpi_fac * U.pie_menu_threshold; + const float pie_radius_external = U.dpi_fac * (U.pie_menu_threshold + 7.0f); - int subd = 40; + const int subd = 40; - float angle = atan2f(pie_dir[1], pie_dir[0]); - float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4; + const float angle = atan2f(pie_dir[1], pie_dir[0]); + const float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? M_PI_2 : M_PI_4; GPU_matrix_push(); GPU_matrix_translate_2f(cx, cy); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (btheme->tui.wcol_pie_menu.shaded) { uchar col1[4], col2[4]; shadecolors4(col1, @@ -5123,7 +5127,7 @@ void ui_draw_pie_center(uiBlock *block) } GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4ubv(btheme->tui.wcol_pie_menu.outline); @@ -5134,8 +5138,9 @@ void ui_draw_pie_center(uiBlock *block) if (U.pie_menu_confirm > 0 && !(block->pie_data.flags & (UI_PIE_INVALID_DIR | UI_PIE_CLICK_STYLE))) { - float pie_confirm_radius = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm); - float pie_confirm_external = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm + 7.0f); + const float pie_confirm_radius = U.dpi_fac * (pie_radius_internal + U.pie_menu_confirm); + const float pie_confirm_external = U.dpi_fac * + (pie_radius_internal + U.pie_menu_confirm + 7.0f); const uchar col[4] = {UNPACK3(btheme->tui.wcol_pie_menu.text_sel), 64}; draw_disk_shaded(angle - range / 2.0f, @@ -5148,7 +5153,7 @@ void ui_draw_pie_center(uiBlock *block) false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } @@ -5169,11 +5174,9 @@ static void ui_draw_widget_back_color(uiWidgetTypeEnum type, uiWidgetType *wt = widget_type(type); if (use_shadow) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); widget_softshadow(rect, UI_CNR_ALL, 0.25f * U.widget_unit); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } rcti rect_copy = *rect; @@ -5220,7 +5223,7 @@ void ui_draw_menu_item(const uiFontStyle *fstyle, int *r_xmax) { uiWidgetType *wt = widget_type(UI_WTYPE_MENU_ITEM); - rcti _rect = *rect; + const rcti _rect = *rect; char *cpoin = NULL; wt->state(wt, state, 0); @@ -5290,16 +5293,16 @@ void ui_draw_menu_item(const uiFontStyle *fstyle, if (iconid) { float height, aspect; - int xs = rect->xmin + 0.2f * UI_UNIT_X; - int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect); + const int xs = rect->xmin + 0.2f * UI_UNIT_X; + const int ys = rect->ymin + 0.1f * BLI_rcti_size_y(rect); height = ICON_SIZE_FROM_BUTRECT(rect); aspect = ICON_DEFAULT_HEIGHT / height; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* XXX scale weak get from fstyle? */ UI_icon_draw_ex(xs, ys, iconid, aspect, 1.0f, 0.0f, wt->wcol.text, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* part text right aligned */ @@ -5335,9 +5338,9 @@ void ui_draw_preview_item( /* draw icon in rect above the space reserved for the label */ rect->ymin += text_size; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); widget_draw_preview(iconid, 1.0f, rect); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BLF_width_and_height( fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 10c31082b2c..4b72d17beb3 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -777,9 +777,6 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid) cp = ts->metadatatext; break; - case TH_UV_OTHERS: - cp = ts->uv_others; - break; case TH_UV_SHADOW: cp = ts->uv_shadow; break; @@ -1477,13 +1474,6 @@ void UI_ThemeClearColor(int colorid) GPU_clear_color(col[0], col[1], col[2], 1.0f); } -void UI_ThemeClearColorAlpha(int colorid, float alpha) -{ - float col[3]; - UI_GetThemeColor3fv(colorid, col); - GPU_clear_color(col[0], col[1], col[2], alpha); -} - int UI_ThemeMenuShadowWidth(void) { bTheme *btheme = UI_GetTheme(); diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 3efed43e08c..7651989c2df 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -351,7 +351,7 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) v2d->scroll |= (V2D_SCROLL_HORIZONTAL_HIDE | V2D_SCROLL_VERTICAL_HIDE); if (do_init) { - float panelzoom = (style) ? style->panelzoom : 1.0f; + const float panelzoom = (style) ? style->panelzoom : 1.0f; v2d->tot.xmin = 0.0f; v2d->tot.xmax = winx; @@ -566,7 +566,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize) * - width is not adjusted for changed ratios here. */ if (winx < v2d->oldwinx) { - float temp = v2d->oldwinx - winx; + const float temp = v2d->oldwinx - winx; cur->xmin -= temp; cur->xmax -= temp; @@ -588,7 +588,7 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, bool resize) */ if (winy < v2d->oldwiny) { - float temp = v2d->oldwiny - winy; + const float temp = v2d->oldwiny - winy; if (v2d->align & V2D_ALIGN_NO_NEG_Y) { cur->ymin -= temp; @@ -853,14 +853,23 @@ void UI_view2d_curRect_validate(View2D *v2d) ui_view2d_curRect_validate_resize(v2d, false); } +void UI_view2d_curRect_changed(const bContext *C, View2D *v2d) +{ + UI_view2d_curRect_validate(v2d); + + ARegion *region = CTX_wm_region(C); + + if (region->type->on_view2d_changed != NULL) { + region->type->on_view2d_changed(C, region); + } +} + /* ------------------ */ /* Called by menus to activate it, or by view2d operators * to make sure 'related' views stay in synchrony */ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) { - ARegion *region; - /* don't continue if no view syncing to be done */ if ((v2dcur->flag & (V2D_VIEWSYNC_SCREEN_TIME | V2D_VIEWSYNC_AREA_VERTICAL)) == 0) { return; @@ -868,7 +877,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) /* check if doing within area syncing (i.e. channels/vertical) */ if ((v2dcur->flag & V2D_VIEWSYNC_AREA_VERTICAL) && (area)) { - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { /* don't operate on self */ if (v2dcur != ®ion->v2d) { /* only if view has vertical locks enabled */ @@ -894,7 +903,7 @@ void UI_view2d_sync(bScreen *screen, ScrArea *area, View2D *v2dcur, int flag) /* check if doing whole screen syncing (i.e. time/horizontal) */ if ((v2dcur->flag & V2D_VIEWSYNC_SCREEN_TIME) && (screen)) { LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) { - for (region = area_iter->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) { /* don't operate on self */ if (v2dcur != ®ion->v2d) { /* only if view has horizontal locks enabled */ @@ -1112,14 +1121,14 @@ static void view2d_map_cur_using_mask(const View2D *v2d, rctf *r_curmasked) *r_curmasked = v2d->cur; if (view2d_scroll_mapped(v2d->scroll)) { - float sizex = BLI_rcti_size_x(&v2d->mask); - float sizey = BLI_rcti_size_y(&v2d->mask); + const float sizex = BLI_rcti_size_x(&v2d->mask); + const float sizey = BLI_rcti_size_y(&v2d->mask); /* prevent tiny or narrow regions to get * invalid coordinates - mask can get negative even... */ if (sizex > 0.0f && sizey > 0.0f) { - float dx = BLI_rctf_size_x(&v2d->cur) / (sizex + 1); - float dy = BLI_rctf_size_y(&v2d->cur) / (sizey + 1); + const float dx = BLI_rctf_size_x(&v2d->cur) / (sizex + 1); + const float dy = BLI_rctf_size_y(&v2d->cur) / (sizey + 1); if (v2d->mask.xmin != 0) { r_curmasked->xmin -= dx * (float)v2d->mask.xmin; @@ -1216,8 +1225,8 @@ void UI_view2d_view_orthoSpecial(ARegion *region, View2D *v2d, const bool xaxis) void UI_view2d_view_restore(const bContext *C) { ARegion *region = CTX_wm_region(C); - int width = BLI_rcti_size_x(®ion->winrct) + 1; - int height = BLI_rcti_size_y(®ion->winrct) + 1; + const int width = BLI_rcti_size_x(®ion->winrct) + 1; + const int height = BLI_rcti_size_y(®ion->winrct) + 1; wmOrtho2(0.0f, (float)width, 0.0f, (float)height); GPU_matrix_identity_set(); @@ -1269,8 +1278,8 @@ void UI_view2d_constant_grid_draw(const View2D *v2d, float step) if (count_x > 0 || count_y > 0) { GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint color = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); float theme_color[3]; UI_GetThemeColorShade3fv(TH_BACK, -10, theme_color); @@ -1322,7 +1331,7 @@ void UI_view2d_multi_grid_draw( vertex_count += 2 * ((int)((v2d->cur.ymax - v2d->cur.ymin) / lstep) + 1); GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint color = GPU_vertformat_attr_add( format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); @@ -1419,7 +1428,7 @@ void UI_view2d_scrollers_calc(View2D *v2d, { rcti vert, hor; float fac1, fac2, totsize, scrollsize; - int scroll = view2d_scroll_mapped(v2d->scroll); + const int scroll = view2d_scroll_mapped(v2d->scroll); int smaller; /* Always update before drawing (for dynamically sized scrollers). */ @@ -1901,7 +1910,7 @@ View2D *UI_view2d_fromcontext_rwin(const bContext *C) * disabled. */ void UI_view2d_scroller_size_get(const View2D *v2d, float *r_x, float *r_y) { - int scroll = view2d_scroll_mapped(v2d->scroll); + const int scroll = view2d_scroll_mapped(v2d->scroll); if (r_x) { if (scroll & V2D_SCROLL_VERTICAL) { @@ -2119,7 +2128,7 @@ void UI_view2d_text_cache_add( BLI_assert(str_len == strlen(str)); if (UI_view2d_view_to_region_clip(v2d, x, y, &mval[0], &mval[1])) { - int alloc_len = str_len + 1; + const int alloc_len = str_len + 1; View2DString *v2s; if (g_v2d_strings_arena == NULL) { @@ -2150,7 +2159,7 @@ void UI_view2d_text_cache_add_rectf( BLI_assert(str_len == strlen(str)); if (UI_view2d_view_to_region_rcti_clip(v2d, rect_view, &rect)) { - int alloc_len = str_len + 1; + const int alloc_len = str_len + 1; View2DString *v2s; if (g_v2d_strings_arena == NULL) { diff --git a/source/blender/editors/interface/view2d_draw.c b/source/blender/editors/interface/view2d_draw.c index 54b25939baf..5801b7cdbdb 100644 --- a/source/blender/editors/interface/view2d_draw.c +++ b/source/blender/editors/interface/view2d_draw.c @@ -67,10 +67,10 @@ static float select_major_distance(const float *possible_distances, return possible_distances[0]; } - float pixels_per_view_unit = pixel_width / view_width; + const float pixels_per_view_unit = pixel_width / view_width; for (uint i = 0; i < amount; i++) { - float distance = possible_distances[i]; + const float distance = possible_distances[i]; if (pixels_per_view_unit * distance >= MIN_MAJOR_LINE_DISTANCE) { return distance; } @@ -111,7 +111,7 @@ static float view2d_major_step_y__continuous(const View2D *v2d) static float view2d_major_step_x__time(const View2D *v2d, const Scene *scene) { - double fps = FPS; + const double fps = FPS; float *possible_distances = NULL; BLI_array_staticdeclare(possible_distances, 32); @@ -207,7 +207,7 @@ static void draw_parallel_lines(const ParallelLinesSet *lines, } GPUVertFormat *format = immVertexFormat(); - uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + const uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); if (U.pixelsize > 1.0f) { float viewport[4]; @@ -227,14 +227,14 @@ static void draw_parallel_lines(const ParallelLinesSet *lines, if (direction == 'v') { for (uint i = 0; i < steps; i++) { - float xpos = first + i * lines->distance; + const float xpos = first + i * lines->distance; immVertex2f(pos, xpos, rect->ymin); immVertex2f(pos, xpos, rect->ymax); } } else { for (uint i = 0; i < steps; i++) { - float ypos = first + i * lines->distance; + const float ypos = first + i * lines->distance; immVertex2f(pos, rect->xmin, ypos); immVertex2f(pos, rect->xmax, ypos); } @@ -322,16 +322,16 @@ static void draw_horizontal_scale_indicators(const ARegion *region, BLF_batch_draw_begin(); - float ypos = rect->ymin + 4 * UI_DPI_FAC; - float xmin = rect->xmin; - float xmax = rect->xmax; + const float ypos = rect->ymin + 4 * UI_DPI_FAC; + const float xmin = rect->xmin; + const float xmax = rect->xmax; for (uint i = 0; i < steps; i++) { - float xpos_view = start + i * distance; - float xpos_region = UI_view2d_view_to_region_x(v2d, xpos_view); + const float xpos_view = start + i * distance; + const float xpos_region = UI_view2d_view_to_region_x(v2d, xpos_view); char text[32]; to_string(to_string_data, xpos_view, distance, sizeof(text), text); - float text_width = BLF_width(font_id, text, strlen(text)); + const float text_width = BLF_width(font_id, text, strlen(text)); if (xpos_region - text_width / 2.0f >= xmin && xpos_region + text_width / 2.0f <= xmax) { BLF_draw_default_ascii(xpos_region - text_width / 2.0f, ypos, 0.0f, text, sizeof(text)); @@ -384,16 +384,16 @@ static void draw_vertical_scale_indicators(const ARegion *region, BLF_batch_draw_begin(); - float xpos = rect->xmax - 2.0f * UI_DPI_FAC; - float ymin = rect->ymin; - float ymax = rect->ymax; + const float xpos = rect->xmax - 2.0f * UI_DPI_FAC; + const float ymin = rect->ymin; + const float ymax = rect->ymax; for (uint i = 0; i < steps; i++) { - float ypos_view = start + i * distance; - float ypos_region = UI_view2d_view_to_region_y(v2d, ypos_view + display_offset); + const float ypos_view = start + i * distance; + const float ypos_region = UI_view2d_view_to_region_y(v2d, ypos_view + display_offset); char text[32]; to_string(to_string_data, ypos_view, distance, sizeof(text), text); - float text_width = BLF_width(font_id, text, strlen(text)); + const float text_width = BLF_width(font_id, text, strlen(text)); if (ypos_region - text_width / 2.0f >= ymin && ypos_region + text_width / 2.0f <= ymax) { BLF_draw_default_ascii(xpos, ypos_region - text_width / 2.0f, 0.0f, text, sizeof(text)); @@ -417,7 +417,7 @@ static void view_to_string__time( { const Scene *scene = (const Scene *)user_data; - int brevity_level = 0; + const int brevity_level = 0; BLI_timecode_string_from_time( r_str, max_len, brevity_level, v2d_pos / (float)FPS, FPS, U.timecode_style); } @@ -462,25 +462,25 @@ float UI_view2d_grid_resolution_y__values(const struct View2D *v2d) void UI_view2d_draw_lines_x__discrete_values(const View2D *v2d) { - uint major_line_distance = view2d_major_step_x__discrete(v2d); + const uint major_line_distance = view2d_major_step_x__discrete(v2d); view2d_draw_lines(v2d, major_line_distance, major_line_distance > 1, 'v'); } void UI_view2d_draw_lines_x__values(const View2D *v2d) { - float major_line_distance = view2d_major_step_x__continuous(v2d); + const float major_line_distance = view2d_major_step_x__continuous(v2d); view2d_draw_lines(v2d, major_line_distance, true, 'v'); } void UI_view2d_draw_lines_y__values(const View2D *v2d) { - float major_line_distance = view2d_major_step_y__continuous(v2d); + const float major_line_distance = view2d_major_step_y__continuous(v2d); view2d_draw_lines(v2d, major_line_distance, true, 'h'); } void UI_view2d_draw_lines_x__discrete_time(const View2D *v2d, const Scene *scene) { - float major_line_distance = view2d_major_step_x__time(v2d, scene); + const float major_line_distance = view2d_major_step_x__time(v2d, scene); view2d_draw_lines(v2d, major_line_distance, major_line_distance > 1, 'v'); } @@ -516,7 +516,7 @@ static void UI_view2d_draw_scale_x__discrete_values(const ARegion *region, const rcti *rect, int colorid) { - float number_step = view2d_major_step_x__discrete(v2d); + const float number_step = view2d_major_step_x__discrete(v2d); draw_horizontal_scale_indicators( region, v2d, number_step, rect, view_to_string__frame_number, NULL, colorid); } @@ -524,7 +524,7 @@ static void UI_view2d_draw_scale_x__discrete_values(const ARegion *region, static void UI_view2d_draw_scale_x__discrete_time( const ARegion *region, const View2D *v2d, const rcti *rect, const Scene *scene, int colorid) { - float step = view2d_major_step_x__time(v2d, scene); + const float step = view2d_major_step_x__time(v2d, scene); draw_horizontal_scale_indicators( region, v2d, step, rect, view_to_string__time, (void *)scene, colorid); } @@ -534,7 +534,7 @@ static void UI_view2d_draw_scale_x__values(const ARegion *region, const rcti *rect, int colorid) { - float step = view2d_major_step_x__continuous(v2d); + const float step = view2d_major_step_x__continuous(v2d); draw_horizontal_scale_indicators(region, v2d, step, rect, view_to_string__value, NULL, colorid); } @@ -543,7 +543,7 @@ void UI_view2d_draw_scale_y__values(const ARegion *region, const rcti *rect, int colorid) { - float step = view2d_major_step_y__continuous(v2d); + const float step = view2d_major_step_y__continuous(v2d); draw_vertical_scale_indicators( region, v2d, step, 0.0f, rect, view_to_string__value, NULL, colorid); } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index d62058699d9..7234e279da8 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -185,8 +185,8 @@ static void view_pan_apply_ex(bContext *C, v2dViewPanData *vpd, float dx, float v2d->cur.ymax += dy; } - /* validate that view is in valid configuration after this operation */ - UI_view2d_curRect_validate(v2d); + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); /* don't rebuild full tree in outliner, since we're just changing our view */ ED_region_tag_redraw_no_rebuild(vpd->region); @@ -436,8 +436,8 @@ static float edge_pan_speed(v2dViewPanData *vpd, ARegion *region = vpd->region; /* Find the distance from the start of the drag zone. */ - int min = (x_dir ? region->winrct.xmin : region->winrct.ymin) + EDGE_PAN_REGION_PAD; - int max = (x_dir ? region->winrct.xmax : region->winrct.ymax) - EDGE_PAN_REGION_PAD; + const int min = (x_dir ? region->winrct.xmin : region->winrct.ymin) + EDGE_PAN_REGION_PAD; + const int max = (x_dir ? region->winrct.xmax : region->winrct.ymax) - EDGE_PAN_REGION_PAD; int distance = 0.0; if (event_loc > max) { distance = event_loc - max; @@ -451,8 +451,8 @@ static float edge_pan_speed(v2dViewPanData *vpd, } /* Apply a fade in to the speed based on a start time delay. */ - double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y; - float delay_factor = smootherstep(EDGE_PAN_DELAY, (float)(current_time - start_time)); + const double start_time = x_dir ? vpd->edge_pan_start_time_x : vpd->edge_pan_start_time_y; + const float delay_factor = smootherstep(EDGE_PAN_DELAY, (float)(current_time - start_time)); return distance * EDGE_PAN_SPEED_PER_PIXEL * delay_factor; } @@ -475,7 +475,7 @@ static int view_edge_pan_modal(bContext *C, wmOperator *op, const wmEvent *event * On successful handling, always pass events on to other handlers. */ const int success_retval = OPERATOR_PASS_THROUGH; - int outside_padding = RNA_int_get(op->ptr, "outside_padding") * UI_UNIT_X; + const int outside_padding = RNA_int_get(op->ptr, "outside_padding") * UI_UNIT_X; rcti padding_rect; if (outside_padding != 0) { padding_rect = region->winrct; @@ -504,14 +504,14 @@ static int view_edge_pan_modal(bContext *C, wmOperator *op, const wmEvent *event edge_pan_manage_delay_timers(vpd, pan_dir_x, pan_dir_y, current_time); /* Calculate the delta since the last time the operator was called. */ - float dtime = (float)(current_time - vpd->edge_pan_last_time); + const float dtime = (float)(current_time - vpd->edge_pan_last_time); float dx = 0.0f, dy = 0.0f; if (pan_dir_x != 0) { - float speed = edge_pan_speed(vpd, event->x, true, current_time); + const float speed = edge_pan_speed(vpd, event->x, true, current_time); dx = dtime * speed * (float)pan_dir_x; } if (pan_dir_y != 0) { - float speed = edge_pan_speed(vpd, event->y, false, current_time); + const float speed = edge_pan_speed(vpd, event->y, false, current_time); dy = dtime * speed * (float)pan_dir_y; } vpd->edge_pan_last_time = current_time; @@ -911,9 +911,9 @@ static void view_zoomstep_apply_ex( /* only move view to mouse if zoom fac is inside minzoom/maxzoom */ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) || IN_RANGE_INCL(zoomx, v2d->minzoom, v2d->maxzoom)) { - float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old); - float mval_faci = 1.0f - mval_fac; - float ofs = (mval_fac * dx) - (mval_faci * dx); + const float mval_fac = (vzd->mx_2d - cur_old.xmin) / BLI_rctf_size_x(&cur_old); + const float mval_faci = 1.0f - mval_fac; + const float ofs = (mval_fac * dx) - (mval_faci * dx); v2d->cur.xmin += ofs; v2d->cur.xmax += ofs; @@ -946,9 +946,9 @@ static void view_zoomstep_apply_ex( /* only move view to mouse if zoom fac is inside minzoom/maxzoom */ if (((v2d->keepzoom & V2D_LIMITZOOM) == 0) || IN_RANGE_INCL(zoomy, v2d->minzoom, v2d->maxzoom)) { - float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old); - float mval_faci = 1.0f - mval_fac; - float ofs = (mval_fac * dy) - (mval_faci * dy); + const float mval_fac = (vzd->my_2d - cur_old.ymin) / BLI_rctf_size_y(&cur_old); + const float mval_faci = 1.0f - mval_fac; + const float ofs = (mval_fac * dy) - (mval_faci * dy); v2d->cur.ymin += ofs; v2d->cur.ymax += ofs; @@ -957,8 +957,8 @@ static void view_zoomstep_apply_ex( } } - /* validate that view is in valid configuration after this operation */ - UI_view2d_curRect_validate(v2d); + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); if (ED_region_snap_size_apply(region, snap_test)) { ScrArea *area = CTX_wm_area(C); @@ -1157,8 +1157,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) const bool zoom_to_pos = use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS); /* get amount to move view by */ - dx = RNA_float_get(op->ptr, "deltax") / U.pixelsize; - dy = RNA_float_get(op->ptr, "deltay") / U.pixelsize; + dx = RNA_float_get(op->ptr, "deltax") / U.dpi_fac; + dy = RNA_float_get(op->ptr, "deltay") / U.dpi_fac; if (U.uiflag & USER_ZOOM_INVERT) { dx *= -1; @@ -1167,8 +1167,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) /* continuous zoom shouldn't move that fast... */ if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop? - double time = PIL_check_seconds_timer(); - float time_step = (float)(time - vzd->timer_lastdraw); + const double time = PIL_check_seconds_timer(); + const float time_step = (float)(time - vzd->timer_lastdraw); dx *= time_step * 0.5f; dy *= time_step * 0.5f; @@ -1183,9 +1183,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) } else { if (zoom_to_pos) { - float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur); - float mval_faci = 1.0f - mval_fac; - float ofs = (mval_fac * dx) - (mval_faci * dx); + const float mval_fac = (vzd->mx_2d - v2d->cur.xmin) / BLI_rctf_size_x(&v2d->cur); + const float mval_faci = 1.0f - mval_fac; + const float ofs = (mval_fac * dx) - (mval_faci * dx); v2d->cur.xmin += ofs + dx; v2d->cur.xmax += ofs - dx; @@ -1202,9 +1202,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) } else { if (zoom_to_pos) { - float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur); - float mval_faci = 1.0f - mval_fac; - float ofs = (mval_fac * dy) - (mval_faci * dy); + const float mval_fac = (vzd->my_2d - v2d->cur.ymin) / BLI_rctf_size_y(&v2d->cur); + const float mval_faci = 1.0f - mval_fac; + const float ofs = (mval_fac * dy) - (mval_faci * dy); v2d->cur.ymin += ofs + dy; v2d->cur.ymax += ofs - dy; @@ -1216,8 +1216,8 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) } } - /* validate that view is in valid configuration after this operation */ - UI_view2d_curRect_validate(v2d); + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); if (ED_region_snap_size_apply(vzd->region, snap_test)) { ScrArea *area = CTX_wm_area(C); @@ -1806,7 +1806,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *region, const rctf *cur, const if (ok == false) { v2d->cur = sms.new_cur; - UI_view2d_curRect_validate(v2d); + UI_view2d_curRect_changed(C, v2d); ED_region_tag_redraw_no_rebuild(region); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); } @@ -1853,7 +1853,7 @@ static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w BLI_rctf_interp(&v2d->cur, &sms->orig_cur, &sms->new_cur, step); } - UI_view2d_curRect_validate(v2d); + UI_view2d_curRect_changed(C, v2d); UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); ED_region_tag_redraw_no_rebuild(region); @@ -1987,8 +1987,8 @@ static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_ (mouse >= (sh_min - V2D_SCROLL_HANDLE_SIZE_HOTSPOT))); bool in_bar = ((mouse < (sh_max - V2D_SCROLL_HANDLE_SIZE_HOTSPOT)) && (mouse > (sh_min + V2D_SCROLL_HANDLE_SIZE_HOTSPOT))); - bool out_min = mouse < (sh_min - V2D_SCROLL_HANDLE_SIZE_HOTSPOT); - bool out_max = mouse > (sh_max + V2D_SCROLL_HANDLE_SIZE_HOTSPOT); + const bool out_min = mouse < (sh_min - V2D_SCROLL_HANDLE_SIZE_HOTSPOT); + const bool out_max = mouse > (sh_max + V2D_SCROLL_HANDLE_SIZE_HOTSPOT); if (in_bar) { return SCROLLHANDLE_BAR; @@ -2176,8 +2176,8 @@ static void scroller_activate_apply(bContext *C, wmOperator *op) break; } - /* validate that view is in valid configuration after this operation */ - UI_view2d_curRect_validate(v2d); + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); /* request updates to be done... */ ED_region_tag_redraw_no_rebuild(vsm->region); @@ -2410,8 +2410,8 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op)) } } - /* validate that view is in valid configuration after this operation */ - UI_view2d_curRect_validate(v2d); + /* Inform v2d about changes after this operation. */ + UI_view2d_curRect_changed(C, v2d); if (ED_region_snap_size_apply(region, snap_test)) { ScrArea *area = CTX_wm_area(C); diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 238ebffe153..22171d8be66 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -656,7 +656,7 @@ void WM_OT_alembic_import(wmOperatorType *ot) WM_operator_properties_filesel(ot, FILE_TYPE_FOLDER | FILE_TYPE_ALEMBIC, FILE_BLENDER, - FILE_SAVE, + FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 096dc44c758..45ea52bdebc 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -113,6 +113,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(op->customdata); const bool selected_objects_only = RNA_boolean_get(op->ptr, "selected_objects_only"); + const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only"); const bool export_animation = RNA_boolean_get(op->ptr, "export_animation"); const bool export_hair = RNA_boolean_get(op->ptr, "export_hair"); const bool export_uvmaps = RNA_boolean_get(op->ptr, "export_uvmaps"); @@ -128,6 +129,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) export_normals, export_materials, selected_objects_only, + visible_objects_only, use_instancing, evaluation_mode, }; @@ -149,6 +151,7 @@ static void wm_usd_export_draw(bContext *UNUSED(C), wmOperator *op) col = uiLayoutColumn(box, true); uiItemR(col, ptr, "selected_objects_only", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "visible_objects_only", 0, NULL, ICON_NONE); col = uiLayoutColumn(box, true); uiItemR(col, ptr, "export_animation", 0, NULL, ICON_NONE); @@ -192,6 +195,13 @@ void WM_OT_usd_export(struct wmOperatorType *ot) "exported as empty transform"); RNA_def_boolean(ot->srna, + "visible_objects_only", + true, + "Visible Only", + "Only visible objects are exported. Invisible parents of exported objects are " + "exported as empty transform"); + + RNA_def_boolean(ot->srna, "export_animation", false, "Animation", diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index 3dc6227434e..e43eea35a91 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -462,8 +462,10 @@ static int add_vertex_handle_cyclic_at_point(bContext *C, const float tolerance_in_pixels_squared = 4 * 4; if (spline->flag & MASK_SPLINE_CYCLIC) { - /* No cycling toggle needed, we've got nothing meaningful to do in this operator. */ - return OPERATOR_CANCELLED; + /* The spline is already cyclic, so there is no need to handle anything here. + * Return PASS_THROUGH so that it's possible to add vertices close to the endpoints of the + * cyclic spline. */ + return OPERATOR_PASS_THROUGH; } float co_pixel[2]; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index c617c921d70..8acbb328ab0 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -594,9 +594,7 @@ static void draw_mask_layers(const bContext *C, const int width, const int height) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); MaskLayer *mask_layer; @@ -633,7 +631,7 @@ static void draw_mask_layers(const bContext *C, } GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type) @@ -740,8 +738,7 @@ void ED_mask_draw_region( if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { /* More blending types could be supported in the future. */ - GPU_blend(true); - GPU_blend_set_func(GPU_DST_COLOR, GPU_ZERO); + GPU_blend(GPU_BLEND_MULTIPLY); } GPU_matrix_push(); @@ -753,12 +750,12 @@ void ED_mask_draw_region( IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR); GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GL_R16F, false, buffer, 1.0f, 1.0f, NULL); + immDrawPixelsTex(&state, 0.0f, 0.0f, width, height, GPU_R16F, false, buffer, 1.0f, 1.0f, NULL); GPU_matrix_pop(); if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } MEM_freeN(buffer); diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index e41445aef09..589b51ce942 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -93,6 +93,10 @@ if(WITH_BULLET) add_definitions(-DWITH_BULLET) endif() +if(WITH_GMP) + add_definitions(-DWITH_GMP) +endif() + add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index 97bd6ee0039..1b5e374b2a7 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -39,6 +39,9 @@ #include "WM_types.h" +#include "UI_interface.h" +#include "UI_resources.h" + #include "ED_mesh.h" #include "ED_screen.h" @@ -46,6 +49,7 @@ #include "mesh_intern.h" /* own include */ +#include "tools/bmesh_boolean.h" #include "tools/bmesh_intersect.h" #include "tools/bmesh_separate.h" @@ -134,6 +138,11 @@ enum { ISECT_SEPARATE_NONE = 2, }; +enum { + ISECT_SOLVER_FAST = 0, + ISECT_SOLVER_EXACT = 1, +}; + static int edbm_intersect_exec(bContext *C, wmOperator *op) { const int mode = RNA_enum_get(op->ptr, "mode"); @@ -142,6 +151,14 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op) bool use_separate_cut = false; const int separate_mode = RNA_enum_get(op->ptr, "separate_mode"); const float eps = RNA_float_get(op->ptr, "threshold"); +#ifdef WITH_GMP + const bool exact = RNA_enum_get(op->ptr, "solver") == ISECT_SOLVER_EXACT; +#else + if (RNA_enum_get(op->ptr, "solver") == ISECT_SOLVER_EXACT) { + BKE_report(op->reports, RPT_WARNING, "Compiled without GMP, using fast solver"); + } + const bool exact = false; +#endif bool use_self; bool has_isect; @@ -186,19 +203,25 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op) continue; } - has_isect = BM_mesh_intersect(em->bm, - em->looptris, - em->tottri, - test_fn, - NULL, - use_self, - use_separate_all, - true, - true, - true, - true, - -1, - eps); + if (exact) { + has_isect = BM_mesh_boolean_knife( + em->bm, em->looptris, em->tottri, test_fn, NULL, use_self, use_separate_all); + } + else { + has_isect = BM_mesh_intersect(em->bm, + em->looptris, + em->tottri, + test_fn, + NULL, + use_self, + use_separate_all, + true, + true, + true, + true, + -1, + eps); + } if (use_separate_cut) { /* detach selected/un-selected faces */ @@ -220,6 +243,34 @@ static int edbm_intersect_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void edbm_intersect_ui(bContext *UNUSED(C), wmOperator *op) +{ + uiLayout *layout = op->layout; + uiLayout *row; + PointerRNA ptr; + + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + bool use_exact = RNA_enum_get(&ptr, "solver") == ISECT_SOLVER_EXACT; + + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemS(layout); + row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "separate_mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemS(layout); + + row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemS(layout); + + if (!use_exact) { + uiItemR(layout, &ptr, "threshold", 0, NULL, ICON_NONE); + } +} + void MESH_OT_intersect(struct wmOperatorType *ot) { static const EnumPropertyItem isect_mode_items[] = { @@ -243,6 +294,12 @@ void MESH_OT_intersect(struct wmOperatorType *ot) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem isect_intersect_solver_items[] = { + {ISECT_SOLVER_FAST, "FAST", 0, "Fast", "Faster Solver, some limitations"}, + {ISECT_SOLVER_EXACT, "EXACT", 0, "Exact", "Exact Solver, slower, handles more cases"}, + {0, NULL, 0, NULL, NULL}, + }; + /* identifiers */ ot->name = "Intersect (Knife)"; ot->description = "Cut an intersection into faces"; @@ -251,6 +308,7 @@ void MESH_OT_intersect(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_intersect_exec; ot->poll = ED_operator_editmesh; + ot->ui = edbm_intersect_ui; /* props */ RNA_def_enum(ot->srna, "mode", isect_mode_items, ISECT_SEL_UNSEL, "Source", ""); @@ -258,6 +316,12 @@ void MESH_OT_intersect(struct wmOperatorType *ot) ot->srna, "separate_mode", isect_separate_items, ISECT_SEPARATE_CUT, "Separate Mode", ""); RNA_def_float_distance( ot->srna, "threshold", 0.000001f, 0.0, 0.01, "Merge threshold", "", 0.0, 0.001); + RNA_def_enum(ot->srna, + "solver", + isect_intersect_solver_items, + ISECT_SOLVER_EXACT, + "Solver", + "Which Intersect solver to use"); /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -280,6 +344,15 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) { const int boolean_operation = RNA_enum_get(op->ptr, "operation"); bool use_swap = RNA_boolean_get(op->ptr, "use_swap"); + bool use_self = RNA_boolean_get(op->ptr, "use_self"); +#ifdef WITH_GMP + const bool use_exact = RNA_enum_get(op->ptr, "solver") == ISECT_SOLVER_EXACT; +#else + if (RNA_enum_get(op->ptr, "solver") == ISECT_SOLVER_EXACT) { + BKE_report(op->reports, RPT_WARNING, "Compiled without GMP, using fast solver"); + } + const bool use_exact = false; +#endif const float eps = RNA_float_get(op->ptr, "threshold"); int (*test_fn)(BMFace *, void *); bool has_isect; @@ -298,19 +371,25 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) continue; } - has_isect = BM_mesh_intersect(em->bm, - em->looptris, - em->tottri, - test_fn, - NULL, - false, - false, - true, - true, - false, - true, - boolean_operation, - eps); + if (use_exact) { + has_isect = BM_mesh_boolean( + em->bm, em->looptris, em->tottri, test_fn, NULL, use_self, boolean_operation); + } + else { + has_isect = BM_mesh_intersect(em->bm, + em->looptris, + em->tottri, + test_fn, + NULL, + false, + false, + true, + true, + false, + true, + boolean_operation, + eps); + } edbm_intersect_select(em, obedit->data, has_isect); @@ -326,6 +405,34 @@ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static void edbm_intersect_boolean_ui(bContext *UNUSED(C), wmOperator *op) +{ + uiLayout *layout = op->layout; + uiLayout *row; + PointerRNA ptr; + + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + bool use_exact = RNA_enum_get(&ptr, "solver") == ISECT_SOLVER_EXACT; + + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + + row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "operation", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemS(layout); + + row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "solver", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemS(layout); + + uiItemR(layout, &ptr, "use_swap", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "use_self", 0, NULL, ICON_NONE); + if (!use_exact) { + uiItemR(layout, &ptr, "threshold", 0, NULL, ICON_NONE); + } +} + void MESH_OT_intersect_boolean(struct wmOperatorType *ot) { static const EnumPropertyItem isect_boolean_operation_items[] = { @@ -335,6 +442,12 @@ void MESH_OT_intersect_boolean(struct wmOperatorType *ot) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem isect_boolean_solver_items[] = { + {ISECT_SOLVER_FAST, "FAST", 0, "Fast", "Faster Solver, some limitations"}, + {ISECT_SOLVER_EXACT, "EXACT", 0, "Exact", "Exact Solver, slower, handles more cases"}, + {0, NULL, 0, NULL, NULL}, + }; + /* identifiers */ ot->name = "Intersect (Boolean)"; ot->description = "Cut solid geometry from selected to unselected"; @@ -343,21 +456,29 @@ void MESH_OT_intersect_boolean(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_intersect_boolean_exec; ot->poll = ED_operator_editmesh; + ot->ui = edbm_intersect_boolean_ui; /* props */ RNA_def_enum(ot->srna, "operation", isect_boolean_operation_items, BMESH_ISECT_BOOLEAN_DIFFERENCE, - "Boolean", - ""); + "Boolean operation", + "Which boolean operation to apply"); RNA_def_boolean(ot->srna, "use_swap", false, "Swap", "Use with difference intersection to swap which side is kept"); + RNA_def_boolean(ot->srna, "use_self", false, "Self", "Do self-union or self-intersection"); RNA_def_float_distance( ot->srna, "threshold", 0.000001f, 0.0, 0.01, "Merge threshold", "", 0.0, 0.001); + RNA_def_enum(ot->srna, + "solver", + isect_boolean_solver_items, + ISECT_SOLVER_EXACT, + "Solver", + "Which Boolean solver to use"); /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 6f4f75e802a..6facee77c1e 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1051,7 +1051,7 @@ static void knife_init_colors(KnifeColors *colors) static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void *arg) { const KnifeTool_OpData *kcd = arg; - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_matrix_push_projection(); GPU_polygon_offset(1.0f, 1.0f); @@ -1128,9 +1128,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v int i, snapped_verts_count, other_verts_count; float fcol[4]; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertBuf *vert = GPU_vertbuf_create_with_format(format); GPU_vertbuf_data_alloc(vert, kcd->totlinehit); @@ -1147,16 +1145,13 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v 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_shader_set_srgb_uniform(batch->interface); GPU_point_size(11); if (snapped_verts_count > 0) { - GPU_batch_draw_advanced(batch, 0, snapped_verts_count, 0, 0); + GPU_batch_draw_range(batch, 0, snapped_verts_count); } /* now draw the rest */ @@ -1164,13 +1159,12 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v GPU_batch_uniform_4fv(batch, "color", fcol); GPU_point_size(7); if (other_verts_count > 0) { - GPU_batch_draw_advanced(batch, snapped_verts_count, other_verts_count, 0, 0); + GPU_batch_draw_range(batch, snapped_verts_count, other_verts_count); } - GPU_batch_program_use_end(batch); GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (kcd->totkedge > 0) { @@ -1228,7 +1222,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), v GPU_matrix_pop_projection(); /* Reset default */ - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } /** diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 8eeba5007e1..34fcee779de 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -354,10 +354,6 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) if (ob->mode == OB_MODE_SCULPT) { ED_sculpt_undo_geometry_begin(ob, "mask slice"); - /* TODO: The ideal functionality would be to preserve the current face sets and add a new one - * for the new triangles, but this data-layer needs to be rebuild in order to make sculpt mode - * not crash when modifying the geometry. */ - CustomData_free_layers(&mesh->pdata, CD_SCULPT_FACE_SETS, mesh->totpoly); } BMesh *bm; @@ -429,14 +425,14 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) BKE_mesh_calc_normals(ob->data); if (ob->mode == OB_MODE_SCULPT) { - ED_sculpt_undo_geometry_end(ob); SculptSession *ss = ob->sculpt; - /* Rebuild a new valid Face Set layer for the object. */ - ss->face_sets = CustomData_add_layer( - &mesh->pdata, CD_SCULPT_FACE_SETS, CD_CALLOC, NULL, mesh->totpoly); - for (int i = 0; i < mesh->totpoly; i++) { - ss->face_sets[i] = 1; + ss->face_sets = CustomData_get_layer(&((Mesh *)ob->data)->pdata, CD_SCULPT_FACE_SETS); + if (ss->face_sets) { + /* Assign a new Face Set ID to the new faces created by the slice operation. */ + const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data); + ED_sculpt_face_sets_initialize_none_to_id(ob->data, next_face_set_id); } + ED_sculpt_undo_geometry_end(ob); } BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); diff --git a/source/blender/editors/mesh/editmesh_preselect_edgering.c b/source/blender/editors/mesh/editmesh_preselect_edgering.c index d9bd63ef35f..aa1df3d76fc 100644 --- a/source/blender/editors/mesh/editmesh_preselect_edgering.c +++ b/source/blender/editors/mesh/editmesh_preselect_edgering.c @@ -159,7 +159,7 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl return; } - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_matrix_push(); GPU_matrix_mul(matrix); @@ -197,7 +197,7 @@ void EDBM_preselect_edgering_draw(struct EditMesh_PreSelEdgeRing *psel, const fl GPU_matrix_pop(); /* Reset default */ - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } static void view3d_preselect_mesh_edgering_update_verts_from_edge( diff --git a/source/blender/editors/mesh/editmesh_preselect_elem.c b/source/blender/editors/mesh/editmesh_preselect_elem.c index d53a1e2b55c..dfd646c767f 100644 --- a/source/blender/editors/mesh/editmesh_preselect_elem.c +++ b/source/blender/editors/mesh/editmesh_preselect_elem.c @@ -133,7 +133,7 @@ void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matr return; } - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_matrix_push(); GPU_matrix_mul(matrix); @@ -204,7 +204,7 @@ void EDBM_preselect_elem_draw(struct EditMesh_PreSelElem *psel, const float matr GPU_matrix_pop(); /* Reset default */ - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } static void view3d_preselect_mesh_elem_update_from_vert(struct EditMesh_PreSelElem *psel, diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index d2e9b57e950..52c109b3854 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -110,7 +110,7 @@ void EDBM_select_mirrored(BMEditMesh *em, } } - EDBM_verts_mirror_cache_begin(em, axis, true, true, use_topology); + EDBM_verts_mirror_cache_begin(em, axis, true, true, false, use_topology); if (!extend) { EDBM_flag_disable_all(em, BM_ELEM_SELECT); @@ -1423,15 +1423,13 @@ void MESH_OT_select_mode(wmOperatorType *ot) static void walker_select_count(BMEditMesh *em, int walkercode, void *start, - const bool select, - const bool select_mix, - int *r_totsel, - int *r_totunsel) + int r_count_by_select[2]) { BMesh *bm = em->bm; BMElem *ele; BMWalker walker; - int tot[2] = {0, 0}; + + r_count_by_select[0] = r_count_by_select[1] = 0; BMW_init(&walker, bm, @@ -1443,17 +1441,15 @@ static void walker_select_count(BMEditMesh *em, BMW_NIL_LAY); for (ele = BMW_begin(&walker, start); ele; ele = BMW_step(&walker)) { - tot[(BM_elem_flag_test_bool(ele, BM_ELEM_SELECT) != select)] += 1; + r_count_by_select[BM_elem_flag_test(ele, BM_ELEM_SELECT) ? 1 : 0] += 1; - if (!select_mix && tot[0] && tot[1]) { - tot[0] = tot[1] = -1; + /* Early exit when mixed (could be optional if needed. */ + if (r_count_by_select[0] && r_count_by_select[1]) { + r_count_by_select[0] = r_count_by_select[1] = -1; break; } } - *r_totsel = tot[0]; - *r_totunsel = tot[1]; - BMW_end(&walker); } @@ -1590,18 +1586,18 @@ static void mouse_mesh_loop_edge( { bool edge_boundary = false; - /* cycle between BMW_EDGELOOP / BMW_EDGEBOUNDARY */ + /* Cycle between BMW_EDGELOOP / BMW_EDGEBOUNDARY. */ if (select_cycle && BM_edge_is_boundary(eed)) { - int tot[2]; + int count_by_select[2]; - /* if the loops selected toggle the boundaries */ - walker_select_count(em, BMW_EDGELOOP, eed, select, false, &tot[0], &tot[1]); - if (tot[select] == 0) { + /* If the loops selected toggle the boundaries. */ + walker_select_count(em, BMW_EDGELOOP, eed, count_by_select); + if (count_by_select[!select] == 0) { edge_boundary = true; - /* if the boundaries selected, toggle back to the loop */ - walker_select_count(em, BMW_EDGEBOUNDARY, eed, select, false, &tot[0], &tot[1]); - if (tot[select] == 0) { + /* If the boundaries selected, toggle back to the loop. */ + walker_select_count(em, BMW_EDGEBOUNDARY, eed, count_by_select); + if (count_by_select[!select] == 0) { edge_boundary = false; } } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 1e4144db47e..4e1a56b3b55 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2513,7 +2513,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology); + EDBM_verts_mirror_cache_begin(em, 0, false, true, false, use_topology); } /* if there is a mirror modifier with clipping, flag the verts that @@ -2658,7 +2658,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) /* Mirror before smooth. */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, 0, false, true, use_topology); + EDBM_verts_mirror_cache_begin(em, 0, false, true, false, use_topology); } bool failed_repeat_loop = false; @@ -7600,7 +7600,7 @@ static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) BMVert *v; int i; - EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, use_topology, thresh, index); + EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, false, use_topology, thresh, index); BM_mesh_elem_table_ensure(bm, BM_VERT); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 46c63d2e057..a90c8dea87b 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -523,7 +523,7 @@ void EDBM_flag_enable_all(BMEditMesh *em, const char hflag) * \{ */ /** - * Return a new UVVertMap from the editmesh + * Return a new #UvVertMap from the edit-mesh. */ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool use_winding) { @@ -1059,6 +1059,7 @@ static BMVert *cache_mirr_intptr_as_bmvert(const intptr_t *index_lookup, int ind * \param em: Editmesh. * \param use_self: Allow a vertex to point to its self (middle verts). * \param use_select: Restrict to selected verts. + * \param respecthide: Skip hidden vertices. * \param use_topology: Use topology mirror. * \param maxdist: Distance for close point test. * \param r_index: Optional array to write into, as an alternative to a customdata layer @@ -1068,6 +1069,7 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, + const bool respecthide, /* extra args */ const bool use_topology, float maxdist, @@ -1110,6 +1112,10 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, else { tree = BLI_kdtree_3d_new(bm->totvert); BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + if (respecthide && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + continue; + } + BLI_kdtree_3d_insert(tree, i, v->co); } BLI_kdtree_3d_balance(tree); @@ -1118,44 +1124,45 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, #define VERT_INTPTR(_v, _i) (r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset)) BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { - BLI_assert(BM_elem_index_get(v) == i); + if (respecthide && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + continue; + } - /* temporary for testing, check for selection */ if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) { - /* do nothing */ + continue; } - else { - BMVert *v_mirr; - int *idx = VERT_INTPTR(v, i); - if (use_topology) { - v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); - } - else { - int i_mirr; - float co[3]; - copy_v3_v3(co, v->co); - co[axis] *= -1.0f; - - v_mirr = NULL; - i_mirr = BLI_kdtree_3d_find_nearest(tree, co, NULL); - if (i_mirr != -1) { - BMVert *v_test = BM_vert_at_index(bm, i_mirr); - if (len_squared_v3v3(co, v_test->co) < maxdist_sq) { - v_mirr = v_test; - } + BLI_assert(BM_elem_index_get(v) == i); + BMVert *v_mirr; + int *idx = VERT_INTPTR(v, i); + + if (use_topology) { + v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); + } + else { + int i_mirr; + float co[3]; + copy_v3_v3(co, v->co); + co[axis] *= -1.0f; + + v_mirr = NULL; + i_mirr = BLI_kdtree_3d_find_nearest(tree, co, NULL); + if (i_mirr != -1) { + BMVert *v_test = BM_vert_at_index(bm, i_mirr); + if (len_squared_v3v3(co, v_test->co) < maxdist_sq) { + v_mirr = v_test; } } + } - if (v_mirr && (use_self || (v_mirr != v))) { - const int i_mirr = BM_elem_index_get(v_mirr); - *idx = i_mirr; - idx = VERT_INTPTR(v_mirr, i_mirr); - *idx = i; - } - else { - *idx = -1; - } + if (v_mirr && (use_self || (v_mirr != v))) { + const int i_mirr = BM_elem_index_get(v_mirr); + *idx = i_mirr; + idx = VERT_INTPTR(v_mirr, i_mirr); + *idx = i; + } + else { + *idx = -1; } } @@ -1173,12 +1180,14 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, + const bool respecthide, const bool use_topology) { EDBM_verts_mirror_cache_begin_ex(em, axis, use_self, use_select, + respecthide, /* extra args */ use_topology, BM_SEARCH_MAXDIST_MIRR, diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index f608e5ce6a5..22ea222cf01 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -1014,6 +1014,10 @@ static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperato Mesh *me = ED_mesh_context(C); if (BKE_mesh_has_custom_loop_normals(me)) { + BMEditMesh *em = me->edit_mesh; + if (em != NULL && em->bm->lnor_spacearr != NULL) { + BKE_lnor_spacearr_clear(em->bm->lnor_spacearr); + } return mesh_customdata_clear_exec__internal(C, BM_LOOP, CD_CUSTOMLOOPNORMAL); } return OPERATOR_CANCELLED; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 5278da67777..bd14919d1d7 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -590,8 +590,9 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) loopofs = 0; polyofs = 0; - /* inverse transform for all selected meshes in this object */ - invert_m4_m4(imat, ob->obmat); + /* Inverse transform for all selected meshes in this object, + * See #object_join_exec for detailed comment on why the safe version is used. */ + invert_m4_m4_safe_ortho(imat, ob->obmat); /* Add back active mesh first. * This allows to keep things similar as they were, as much as possible @@ -741,6 +742,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 81b8cd70353..72180d58ecb 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1450,6 +1450,7 @@ static int collection_instance_add_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } @@ -2647,7 +2648,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) ob_gpencil = ED_gpencil_add_object(C, ob->loc, local_view_bits); copy_v3_v3(ob_gpencil->rot, ob->rot); copy_v3_v3(ob_gpencil->scale, ob->scale); - BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, ob, false, false, true); + BKE_gpencil_convert_curve(bmain, scene, ob_gpencil, ob, false, 1.0f, 0.0f); gpencilConverted = true; } } @@ -2783,6 +2784,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, scene); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } @@ -3003,6 +3005,7 @@ static int duplicate_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } @@ -3094,6 +3097,7 @@ static int object_add_named_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); ED_outliner_select_sync_from_object_tag(C); return OPERATOR_FINISHED; @@ -3163,20 +3167,45 @@ static int object_join_exec(bContext *C, wmOperator *op) } } + int ret = OPERATOR_CANCELLED; if (ob->type == OB_MESH) { - return ED_mesh_join_objects_exec(C, op); - } - if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - return ED_curve_join_objects_exec(C, op); - } - if (ob->type == OB_ARMATURE) { - return ED_armature_join_objects_exec(C, op); - } - if (ob->type == OB_GPENCIL) { - return ED_gpencil_join_objects_exec(C, op); - } - - return OPERATOR_CANCELLED; + ret = ED_mesh_join_objects_exec(C, op); + } + else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { + ret = ED_curve_join_objects_exec(C, op); + } + else if (ob->type == OB_ARMATURE) { + ret = ED_armature_join_objects_exec(C, op); + } + else if (ob->type == OB_GPENCIL) { + ret = ED_gpencil_join_objects_exec(C, op); + } + + if (ret & OPERATOR_FINISHED) { + /* Even though internally failure to invert is accounted for with a fallback, + * show a warning since the result may not be what the user expects. See T80077. + * + * Failure to invert the matrix is typically caused by zero scaled axes + * (which can be caused by constraints, even if the input scale isn't zero). + * + * Internally the join functions use #invert_m4_m4_safe_ortho which creates + * an inevitable matrix from one that has one or more degenerate axes. + * + * In most cases we don't worry about special handling for non-inevitable matrices however for + * joining objects there may be flat 2D objects where it's not obvious the scale is zero. + * In this case, using #invert_m4_m4_safe_ortho works as well as we can expect, + * joining the contents, flattening on the axis that's zero scaled. + * If the zero scale is removed, the data on this axis remains un-scaled + * (something that wouldn't work for #invert_m4_m4_safe). */ + float imat_test[4][4]; + if (!invert_m4_m4(imat_test, ob->obmat)) { + BKE_report(op->reports, + RPT_WARNING, + "Active object final transform has one or more zero scaled axes"); + } + } + + return ret; } void OBJECT_OT_join(wmOperatorType *ot) diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index cb92fab3cb0..4d55aff1d1f 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -745,7 +745,7 @@ static int bake(Render *re, /* We build a depsgraph for the baking, * so we don't need to change the original data to adjust visibility and modifiers. */ Depsgraph *depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER); - DEG_graph_build_from_view_layer(depsgraph, bmain, scene, view_layer); + DEG_graph_build_from_view_layer(depsgraph); int op_result = OPERATOR_CANCELLED; bool ok = false; @@ -1596,9 +1596,8 @@ static void bake_set_props(wmOperator *op, Scene *scene) prop = RNA_struct_find_property(op->ptr, "cage_object"); if (!RNA_property_is_set(op->ptr, prop)) { - if (bake->cage_object) { - RNA_property_string_set(op->ptr, prop, bake->cage_object->id.name + 2); - } + RNA_property_string_set( + op->ptr, prop, (bake->cage_object) ? bake->cage_object->id.name + 2 : ""); } prop = RNA_struct_find_property(op->ptr, "normal_space"); diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index bcb1b8afbdd..70404af6433 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -663,10 +663,13 @@ static const EnumPropertyItem constraint_owner_items[] = { {0, NULL, 0, NULL, NULL}, }; -static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) +static bool edit_constraint_poll_generic(bContext *C, + StructRNA *rna_type, + const bool is_liboverride_allowed) { PointerRNA ptr = CTX_data_pointer_get_type(C, "constraint", rna_type); Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C); + bConstraint *con = ptr.data; if (!ob) { CTX_wm_operator_poll_msg_set(C, "Context missing active object"); @@ -678,9 +681,11 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) return false; } - if (ID_IS_OVERRIDE_LIBRARY(ob) && ptr.data != NULL) { - CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); - return (((bConstraint *)ptr.data)->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0; + if (ID_IS_OVERRIDE_LIBRARY(ob) && !is_liboverride_allowed) { + if ((con == NULL) || (con->flag & CONSTRAINT_OVERRIDE_LIBRARY_LOCAL) != 0) { + CTX_wm_operator_poll_msg_set(C, "Cannot edit constraints coming from library override"); + return false; + } } return true; @@ -688,7 +693,14 @@ static bool edit_constraint_poll_generic(bContext *C, StructRNA *rna_type) static bool edit_constraint_poll(bContext *C) { - return edit_constraint_poll_generic(C, &RNA_Constraint); + return edit_constraint_poll_generic(C, &RNA_Constraint, false); +} + +/* Used by operators performing actions allowed also on constraints from the overridden linked + * object (not only from added 'local' ones). */ +static bool edit_constraint_liboverride_allowed_poll(bContext *C) +{ + return edit_constraint_poll_generic(C, &RNA_Constraint, true); } static void edit_constraint_properties(wmOperatorType *ot) @@ -864,7 +876,7 @@ void CONSTRAINT_OT_stretchto_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = stretchto_reset_invoke; ot->exec = stretchto_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -919,7 +931,7 @@ void CONSTRAINT_OT_limitdistance_reset(wmOperatorType *ot) /* callbacks */ ot->invoke = limitdistance_reset_invoke; ot->exec = limitdistance_reset_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -997,7 +1009,7 @@ void CONSTRAINT_OT_childof_set_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_set_inverse_invoke; ot->exec = childof_set_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1046,7 +1058,7 @@ void CONSTRAINT_OT_childof_clear_inverse(wmOperatorType *ot) /* callbacks */ ot->invoke = childof_clear_inverse_invoke; ot->exec = childof_clear_inverse_exec; - ot->poll = edit_constraint_poll; + ot->poll = edit_constraint_liboverride_allowed_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1693,8 +1705,8 @@ void POSE_OT_constraints_clear(wmOperatorType *ot) /* callbacks */ ot->exec = pose_constraints_clear_exec; - ot->poll = - ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected bones too? + ot->poll = ED_operator_posemode_exclusive; // XXX - do we want to ensure there are selected + // bones too? } static int object_constraints_clear_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1942,7 +1954,8 @@ static bool get_new_constraint_target( /* perform some special operations on the target */ if (only_curve) { - /* Curve-Path option must be enabled for follow-path constraints to be able to work */ + /* Curve-Path option must be enabled for follow-path constraints to be able to work + */ Curve *cu = (Curve *)ob->data; cu->flag |= CU_PATH; } @@ -2214,8 +2227,8 @@ void OBJECT_OT_constraint_add_with_targets(wmOperatorType *ot) /* identifiers */ ot->name = "Add Constraint (with Targets)"; ot->description = - "Add a constraint to the active object, with target (where applicable) set to the selected " - "Objects/Bones"; + "Add a constraint to the active object, with target (where applicable) set to the " + "selected Objects/Bones"; ot->idname = "OBJECT_OT_constraint_add_with_targets"; /* api callbacks */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 04113f70e52..966aeed75ab 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -145,6 +145,72 @@ Object *ED_object_active_context(const bContext *C) return ob; } +/** + * Return an array of objects: + * - When in the property space, return the pinned or active object. + * - When in edit-mode/pose-mode, return an array of objects in the mode. + * - Otherwise return selected objects, + * the callers \a filter_fn needs to check of they are editable + * (assuming they need to be modified). + */ +Object **ED_object_array_in_mode_or_selected(bContext *C, + bool (*filter_fn)(Object *ob, void *user_data), + void *filter_user_data, + uint *r_objects_len) +{ + ScrArea *area = CTX_wm_area(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Object *ob_active = OBACT(view_layer); + Object **objects; + + Object *ob = NULL; + bool use_ob = true; + if (area && (area->spacetype == SPACE_PROPERTIES)) { + /* May return pinned object. */ + ob = ED_object_context(C); + } + else if (ob_active && (ob_active->mode & + (OB_MODE_ALL_PAINT | OB_MODE_ALL_SCULPT | OB_MODE_ALL_PAINT_GPENCIL))) { + /* When painting, limit to active. */ + ob = ob_active; + } + else { + /* Otherwise use full selection. */ + use_ob = false; + } + + if (use_ob) { + if ((ob != NULL) && !filter_fn(ob, filter_user_data)) { + ob = NULL; + } + *r_objects_len = (ob != NULL) ? 1 : 0; + objects = MEM_mallocN(sizeof(*objects) * *r_objects_len, __func__); + if (ob != NULL) { + objects[0] = ob; + } + } + else { + const View3D *v3d = (area && area->spacetype == SPACE_VIEW3D) ? area->spacedata.first : NULL; + /* When in a mode that supports multiple active objects, use "objects in mode" + * instead of the object's selection. */ + if ((ob_active != NULL) && (ob_active->mode & (OB_MODE_EDIT | OB_MODE_POSE))) { + objects = BKE_view_layer_array_from_objects_in_mode( + view_layer, + v3d, + r_objects_len, + {.no_dup_data = true, .filter_fn = filter_fn, .filter_userdata = filter_user_data}); + } + else { + objects = BKE_view_layer_array_selected_objects( + view_layer, + v3d, + r_objects_len, + {.no_dup_data = true, .filter_fn = filter_fn, .filter_userdata = filter_user_data}); + } + } + return objects; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c index 6e0376358bb..32668598df1 100644 --- a/source/blender/editors/object/object_facemap_ops.c +++ b/source/blender/editors/object/object_facemap_ops.c @@ -26,6 +26,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_mesh_types.h" @@ -99,71 +100,61 @@ void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum) } } -static void object_fmap_swap_edit_mode(Object *ob, int num1, int num2) +static void object_fmap_remap_edit_mode(Object *ob, const int *remap) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; + if (ob->type != OB_MESH) { + return; + } + + Mesh *me = ob->data; + if (me->edit_mesh) { + BMEditMesh *em = me->edit_mesh; + const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); - if (me->edit_mesh) { - BMEditMesh *em = me->edit_mesh; - const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP); - - if (cd_fmap_offset != -1) { - BMFace *efa; - BMIter iter; - int *map; - - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); - - if (map) { - if (num1 != -1) { - if (*map == num1) { - *map = num2; - } - else if (*map == num2) { - *map = num1; - } - } - } + if (cd_fmap_offset != -1) { + BMFace *efa; + BMIter iter; + int *map; + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset); + + if (map && *map != -1) { + *map = remap[*map]; } } } } } -static void object_fmap_swap_object_mode(Object *ob, int num1, int num2) +static void object_fmap_remap_object_mode(Object *ob, const int *remap) { - if (ob->type == OB_MESH) { - Mesh *me = ob->data; + if (ob->type != OB_MESH) { + return; + } - if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { - int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP); - int i; - - if (map) { - for (i = 0; i < me->totpoly; i++) { - if (num1 != -1) { - if (map[i] == num1) { - map[i] = num2; - } - else if (map[i] == num2) { - map[i] = num1; - } - } + Mesh *me = ob->data; + if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { + int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP); + int i; + + if (map) { + for (i = 0; i < me->totpoly; i++) { + if (map[i] != -1) { + map[i] = remap[map[i]]; } } } } } -static void object_facemap_swap(Object *ob, int num1, int num2) +static void object_facemap_remap(Object *ob, const int *remap) { if (BKE_object_is_in_editmode(ob)) { - object_fmap_swap_edit_mode(ob, num1, num2); + object_fmap_remap_edit_mode(ob, remap); } else { - object_fmap_swap_object_mode(ob, num1, num2); + object_fmap_remap_object_mode(ob, remap); } } @@ -432,45 +423,46 @@ static int face_map_move_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); bFaceMap *fmap; int dir = RNA_enum_get(op->ptr, "direction"); - int pos1, pos2 = -1, count; fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1); if (!fmap) { return OPERATOR_CANCELLED; } - count = BLI_listbase_count(&ob->fmaps); - pos1 = BLI_findindex(&ob->fmaps, fmap); + if (!fmap->prev && !fmap->next) { + return OPERATOR_CANCELLED; + } - if (dir == 1) { /*up*/ - void *prev = fmap->prev; + int pos1 = BLI_findindex(&ob->fmaps, fmap); + int pos2 = pos1 - dir; + int len = BLI_listbase_count(&ob->fmaps); + int *map = MEM_mallocN(len * sizeof(*map), __func__); - if (prev) { - pos2 = pos1 - 1; - } - else { - pos2 = count - 1; + if (!IN_RANGE(pos2, -1, len)) { + const int offset = len - dir; + for (int i = 0; i < len; i++) { + map[i] = (i + offset) % len; } + pos2 = map[pos1]; + } + else { + range_vn_i(map, len, 0); + SWAP(int, map[pos1], map[pos2]); + } - BLI_remlink(&ob->fmaps, fmap); + void *prev = fmap->prev; + void *next = fmap->next; + BLI_remlink(&ob->fmaps, fmap); + if (dir == 1) { /*up*/ BLI_insertlinkbefore(&ob->fmaps, prev, fmap); } else { /*down*/ - void *next = fmap->next; - - if (next) { - pos2 = pos1 + 1; - } - else { - pos2 = 0; - } - - BLI_remlink(&ob->fmaps, fmap); BLI_insertlinkafter(&ob->fmaps, next, fmap); } - /* iterate through mesh and substitute the indices as necessary */ - object_facemap_swap(ob, pos2, pos1); + /* Iterate through mesh and substitute the indices as necessary. */ + object_facemap_remap(ob, map); + MEM_freeN(map); ob->actfmap = pos2 + 1; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index ceb6553bdf6..14882ab8ffc 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -107,7 +107,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); BKE_object_eval_reset(ob_eval); if (ob->type == OB_MESH) { - Mesh *me_eval = mesh_create_eval_final_view(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); + Mesh *me_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); BKE_mesh_eval_delete(me_eval); } else if (ob->type == OB_LATTICE) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 732d2f6ad52..d9196425098 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -134,13 +134,11 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewLayer *view_layer = CTX_data_view_layer(C); Object *obedit = CTX_data_edit_object(C); - BMVert *eve; - BMIter iter; - Nurb *nu; - BezTriple *bezt; - BPoint *bp; Object *par; - int a, v1 = 0, v2 = 0, v3 = 0, v4 = 0, nr = 1; + +#define INDEX_UNSET -1 + int par1, par2, par3, par4; + par1 = par2 = par3 = par4 = INDEX_UNSET; /* we need 1 to 3 selected vertices */ @@ -165,114 +163,108 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) * objects are also up to date. */ BKE_scene_graph_update_tagged(depsgraph, bmain); - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + BMVert *eve; + BMIter iter; + int curr_index; + BM_ITER_MESH_INDEX (eve, &iter, em->bm, BM_VERTS_OF_MESH, curr_index) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - if (v1 == 0) { - v1 = nr; + if (par1 == INDEX_UNSET) { + par1 = curr_index; } - else if (v2 == 0) { - v2 = nr; + else if (par2 == INDEX_UNSET) { + par2 = curr_index; } - else if (v3 == 0) { - v3 = nr; + else if (par3 == INDEX_UNSET) { + par3 = curr_index; } - else if (v4 == 0) { - v4 = nr; + else if (par4 == INDEX_UNSET) { + par4 = curr_index; } else { break; } } - nr++; } } else if (ELEM(obedit->type, OB_SURF, OB_CURVE)) { ListBase *editnurb = object_editcurve_get(obedit); - nu = editnurb->first; - while (nu) { + for (Nurb *nu = editnurb->first; nu != NULL; nu = nu->next) { if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { + BezTriple *bezt = nu->bezt; + for (int curr_index = 0; curr_index < nu->pntsu; curr_index++, bezt++) { if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt)) { - if (v1 == 0) { - v1 = nr; + if (par1 == INDEX_UNSET) { + par1 = curr_index; } - else if (v2 == 0) { - v2 = nr; + else if (par2 == INDEX_UNSET) { + par2 = curr_index; } - else if (v3 == 0) { - v3 = nr; + else if (par3 == INDEX_UNSET) { + par3 = curr_index; } - else if (v4 == 0) { - v4 = nr; + else if (par4 == INDEX_UNSET) { + par4 = curr_index; } else { break; } } - nr++; - bezt++; } } else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { + BPoint *bp = nu->bp; + const int num_points = nu->pntsu * nu->pntsv; + for (int curr_index = 0; curr_index < num_points; curr_index++, bp++) { if (bp->f1 & SELECT) { - if (v1 == 0) { - v1 = nr; + if (par1 == INDEX_UNSET) { + par1 = curr_index; } - else if (v2 == 0) { - v2 = nr; + else if (par2 == INDEX_UNSET) { + par2 = curr_index; } - else if (v3 == 0) { - v3 = nr; + else if (par3 == INDEX_UNSET) { + par3 = curr_index; } - else if (v4 == 0) { - v4 = nr; + else if (par4 == INDEX_UNSET) { + par4 = curr_index; } else { break; } } - nr++; - bp++; } } - nu = nu->next; } } else if (obedit->type == OB_LATTICE) { Lattice *lt = obedit->data; - a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - bp = lt->editlatt->latt->def; - while (a--) { + const int num_points = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * + lt->editlatt->latt->pntsw; + BPoint *bp = lt->editlatt->latt->def; + for (int curr_index = 0; curr_index < num_points; curr_index++, bp++) { if (bp->f1 & SELECT) { - if (v1 == 0) { - v1 = nr; + if (par1 == INDEX_UNSET) { + par1 = curr_index; } - else if (v2 == 0) { - v2 = nr; + else if (par2 == INDEX_UNSET) { + par2 = curr_index; } - else if (v3 == 0) { - v3 = nr; + else if (par3 == INDEX_UNSET) { + par3 = curr_index; } - else if (v4 == 0) { - v4 = nr; + else if (par4 == INDEX_UNSET) { + par4 = curr_index; } else { break; } } - nr++; - bp++; } } - if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3))) { + if (par4 != INDEX_UNSET || par1 == INDEX_UNSET || (par2 != INDEX_UNSET && par3 == INDEX_UNSET)) { BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to"); return OPERATOR_CANCELLED; } @@ -289,11 +281,11 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) Object workob; ob->parent = BASACT(view_layer)->object; - if (v3) { + if (par3 != INDEX_UNSET) { ob->partype = PARVERT3; - ob->par1 = v1 - 1; - ob->par2 = v2 - 1; - ob->par3 = v3 - 1; + ob->par1 = par1; + ob->par2 = par2; + ob->par3 = par3; /* inverse parent matrix */ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); @@ -301,7 +293,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) } else { ob->partype = PARVERT1; - ob->par1 = v1 - 1; + ob->par1 = par1; /* inverse parent matrix */ BKE_object_workob_calc_parent(depsgraph, scene, ob, &workob); @@ -317,6 +309,8 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT, NULL); return OPERATOR_FINISHED; + +#undef INDEX_UNSET } void OBJECT_OT_vertex_parent_set(wmOperatorType *ot) @@ -1474,7 +1468,8 @@ static int make_links_scene_exec(bContext *C, wmOperator *op) /* redraw the 3D view because the object center points are colored differently */ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL); - /* one day multiple scenes will be visible, then we should have some update function for them */ + /* one day multiple scenes will be visible, then we should have some update function for them + */ return OPERATOR_FINISHED; } @@ -1794,9 +1789,9 @@ static Collection *single_object_users_collection(Main *bmain, if (is_master_collection && copy_collections && child->collection != collection_child_new) { /* We do not want a collection sync here, our collections are in a complete uninitialized - * state currently. With current code, that would lead to a memory leak - because of reasons. - * It would be a useless loss of computing anyway, since caller has to fully refresh - * view-layers/collections caching at the end. */ + * state currently. With current code, that would lead to a memory leak - because of + * reasons. It would be a useless loss of computing anyway, since caller has to fully + * refresh view-layers/collections caching at the end. */ BKE_collection_child_add_no_sync(collection, collection_child_new); BLI_remlink(&collection->children, child); MEM_freeN(child); diff --git a/source/blender/editors/object/object_remesh.c b/source/blender/editors/object/object_remesh.c index 8d8f01dd61a..f14c734da4e 100644 --- a/source/blender/editors/object/object_remesh.c +++ b/source/blender/editors/object/object_remesh.c @@ -294,7 +294,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), { VoxelSizeEditCustomData *cd = arg; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -363,7 +363,7 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 253287c382e..de9cca38a6e 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -72,15 +72,32 @@ #include "ED_mesh.h" #include "ED_object.h" +#include "ED_screen.h" #include "UI_resources.h" #include "object_intern.h" +static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob); + /* -------------------------------------------------------------------- */ -/** \name Public Utility Functions +/** \name Local Utility Functions * \{ */ +static bool object_array_for_wpaint_filter(Object *ob, void *user_data) +{ + bContext *C = user_data; + if (vertex_group_supported_poll_ex(C, ob)) { + return true; + } + return false; +} + +static Object **object_array_for_wpaint(bContext *C, uint *r_objects_len) +{ + return ED_object_array_in_mode_or_selected(C, object_array_for_wpaint_filter, C, r_objects_len); +} + static bool vertex_group_use_vert_sel(Object *ob) { if (ob->mode == OB_MODE_EDIT) { @@ -100,6 +117,12 @@ static Lattice *vgroup_edit_lattice(Object *ob) return (lt->editlatt) ? lt->editlatt->latt : lt; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Public Utility Functions + * \{ */ + bool ED_vgroup_sync_from_pose(Object *ob) { Object *armobj = BKE_object_pose_armature_get(ob); @@ -2407,7 +2430,7 @@ void ED_vgroup_mirror(Object *ob, goto cleanup; } - EDBM_verts_mirror_cache_begin(em, 0, true, false, use_topology); + EDBM_verts_mirror_cache_begin(em, 0, true, false, false, use_topology); BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); @@ -2659,14 +2682,21 @@ static void vgroup_assign_verts(Object *ob, const float weight) /** \name Shared Operator Poll Functions * \{ */ +static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob) +{ + if (!ED_operator_object_active_local_editable_ex(C, ob)) { + return false; + } + const ID *data = ob->data; + return (OB_TYPE_SUPPORT_VGROUP(ob->type) && + /* Data checks. */ + (data != NULL) && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data)); +} + static bool vertex_group_supported_poll(bContext *C) { Object *ob = ED_object_context(C); - ID *data = (ob) ? ob->data : NULL; - - return (ob && !ID_IS_LINKED(ob) && OB_TYPE_SUPPORT_VGROUP(ob->type) && - !ID_IS_OVERRIDE_LIBRARY(ob) && data && !ID_IS_LINKED(data) && - !ID_IS_OVERRIDE_LIBRARY(data)); + return vertex_group_supported_poll_ex(C, ob); } static bool vertex_group_poll(bContext *C) @@ -3077,6 +3107,12 @@ void OBJECT_OT_vertex_group_deselect(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vertex Group Copy Operator + * \{ */ + static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); @@ -3090,12 +3126,6 @@ static int vertex_group_copy_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Vertex Group Copy Operator - * \{ */ - void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) { /* identifiers */ @@ -3111,6 +3141,12 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vertex Group Levels Operator + * \{ */ + static int vertex_group_levels_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); @@ -3133,12 +3169,6 @@ static int vertex_group_levels_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Vertex Group Levels Operator - * \{ */ - void OBJECT_OT_vertex_group_levels(wmOperatorType *ot) { /* identifiers */ @@ -3161,6 +3191,12 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot) ot->srna, "gain", 1.f, 0.f, FLT_MAX, "Gain", "Value to multiply weights by", 0.0f, 10.f); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vertex Group Normalize Operator + * \{ */ + static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); @@ -3178,12 +3214,6 @@ static int vertex_group_normalize_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Vertex Group Normalize Operator - * \{ */ - void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot) { /* identifiers */ @@ -3200,6 +3230,12 @@ void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vertex Group Normalize All Operator + * \{ */ + static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); @@ -3226,12 +3262,6 @@ static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Vertex Group Normalize All Operator - * \{ */ - void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) { /* identifiers */ @@ -3512,22 +3542,11 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op) { const float fac = RNA_float_get(op->ptr, "factor"); const int repeat = RNA_int_get(op->ptr, "repeat"); - eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); const float fac_expand = RNA_float_get(op->ptr, "expand"); - ViewLayer *view_layer = CTX_data_view_layer(C); - Object *ob_ctx = ED_object_context(C); uint objects_len; - Object **objects; - if (ob_ctx->mode == OB_MODE_WEIGHT_PAINT) { - /* Until weight paint supports multi-edit, use only the active. */ - objects_len = 1; - objects = &ob_ctx; - } - else { - objects = BKE_view_layer_array_from_objects_in_mode_unique_data( - view_layer, CTX_wm_view3d(C), &objects_len, ob_ctx->mode); - } + Object **objects = object_array_for_wpaint(C, &objects_len); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; @@ -3544,9 +3563,7 @@ static int vertex_group_smooth_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); } - if (objects != &ob_ctx) { - MEM_freeN(objects); - } + MEM_freeN(objects); return OPERATOR_FINISHED; } @@ -3588,22 +3605,29 @@ void OBJECT_OT_vertex_group_smooth(wmOperatorType *ot) static int vertex_group_clean_exec(bContext *C, wmOperator *op) { - Object *ob = ED_object_context(C); + const float limit = RNA_float_get(op->ptr, "limit"); + const bool keep_single = RNA_boolean_get(op->ptr, "keep_single"); + const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); - float limit = RNA_float_get(op->ptr, "limit"); - bool keep_single = RNA_boolean_get(op->ptr, "keep_single"); - eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + uint objects_len; + Object **objects = object_array_for_wpaint(C, &objects_len); - int subset_count, vgroup_tot; + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob = objects[ob_index]; - const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type( - ob, subset_type, &vgroup_tot, &subset_count); - vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); - MEM_freeN((void *)vgroup_validmap); + int subset_count, vgroup_tot; - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type( + ob, subset_type, &vgroup_tot, &subset_count); + + vgroup_clean_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit, keep_single); + MEM_freeN((void *)vgroup_validmap); + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + } + MEM_freeN(objects); return OPERATOR_FINISHED; } @@ -3611,7 +3635,7 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) { /* identifiers */ - ot->name = "Clean Vertex Group"; + ot->name = "Clean Vertex Group Weights"; ot->idname = "OBJECT_OT_vertex_group_clean"; ot->description = "Remove vertex group assignments which are not required"; @@ -3692,25 +3716,36 @@ void OBJECT_OT_vertex_group_quantize(wmOperatorType *ot) static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) { - Object *ob = ED_object_context(C); - const int limit = RNA_int_get(op->ptr, "limit"); - eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + const eVGroupSelect subset_type = RNA_enum_get(op->ptr, "group_select_mode"); + int remove_multi_count = 0; - int subset_count, vgroup_tot; + uint objects_len; + Object **objects = object_array_for_wpaint(C, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob = objects[ob_index]; - const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type( - ob, subset_type, &vgroup_tot, &subset_count); - int remove_tot = vgroup_limit_total_subset(ob, vgroup_validmap, vgroup_tot, subset_count, limit); - MEM_freeN((void *)vgroup_validmap); + int subset_count, vgroup_tot; + const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type( + ob, subset_type, &vgroup_tot, &subset_count); + const int remove_count = vgroup_limit_total_subset( + ob, vgroup_validmap, vgroup_tot, subset_count, limit); + MEM_freeN((void *)vgroup_validmap); - BKE_reportf( - op->reports, remove_tot ? RPT_INFO : RPT_WARNING, "%d vertex weights limited", remove_tot); + if (remove_count != 0) { + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + } + remove_multi_count += remove_count; + } + MEM_freeN(objects); - if (remove_tot) { - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + if (remove_multi_count) { + BKE_reportf(op->reports, + remove_multi_count ? RPT_INFO : RPT_WARNING, + "%d vertex weights limited", + remove_multi_count); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 488bb7121a2..eb7ddfefb9c 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3213,11 +3213,11 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) immUniformColor4ub(255, 255, 255, 128); GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); imm_draw_circle_wire_2d(pos, (float)x, (float)y, pe_brush_size_get(scene, brush), 40); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index f75dd428968..940ca963fc6 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -339,7 +339,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R GPU_offscreen_bind(oglrender->ofs, true); GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); + GPU_clear_depth(1.0f); GPU_matrix_reset(); wmOrtho2(0, scene->r.xsch, 0, scene->r.ysch); @@ -879,7 +879,6 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { - Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; @@ -929,7 +928,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) if (oglrender->timer) { /* exec will not have a timer */ Depsgraph *depsgraph = oglrender->depsgraph; scene->r.cfra = oglrender->cfrao; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } @@ -1119,7 +1118,6 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr) static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) { - Main *bmain = CTX_data_main(C); OGLRender *oglrender = op->customdata; Scene *scene = oglrender->scene; Depsgraph *depsgraph = oglrender->depsgraph; @@ -1134,7 +1132,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) CFRA++; } while (CFRA < oglrender->nfra) { - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); CFRA++; } @@ -1161,7 +1159,7 @@ static bool screen_opengl_render_anim_step(bContext *C, wmOperator *op) WM_cursor_time(oglrender->win, scene->r.cfra); - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); if (view_context) { if (oglrender->rv3d->persp == RV3D_CAMOB && oglrender->v3d->camera && diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 711f89b9fda..2b52ae117fc 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -56,6 +56,7 @@ #include "BKE_linestyle.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_object.h" #include "BKE_paint.h" #include "BKE_report.h" #include "BKE_scene.h" @@ -95,39 +96,74 @@ #include "render_intern.h" // own include -/** - * Object list for material operations. - * has exception for pinned object. - */ -static Object **object_array_for_shading(bContext *C, uint *r_objects_len) -{ - ScrArea *area = CTX_wm_area(C); - SpaceProperties *sbuts = NULL; - View3D *v3d = NULL; - if (area != NULL) { - if (area->spacetype == SPACE_PROPERTIES) { - sbuts = area->spacedata.first; - } - else if (area->spacetype == SPACE_VIEW3D) { - v3d = area->spacedata.first; +static bool object_materials_supported_poll_ex(bContext *C, const Object *ob); + +/* -------------------------------------------------------------------- */ +/** \name Local Utilities + * \{ */ + +static bool object_array_for_shading_edit_mode_enabled_filter(Object *ob, void *user_data) +{ + bContext *C = user_data; + if (object_materials_supported_poll_ex(C, ob)) { + if (BKE_object_is_in_editmode(ob) == true) { + return true; } } + return false; +} - Object **objects; - if (sbuts != NULL && sbuts->pinid && GS(sbuts->pinid->name) == ID_OB) { - objects = MEM_mallocN(sizeof(*objects), __func__); - objects[0] = (Object *)sbuts->pinid; - *r_objects_len = 1; +static Object **object_array_for_shading_edit_mode_enabled(bContext *C, uint *r_objects_len) +{ + return ED_object_array_in_mode_or_selected( + C, object_array_for_shading_edit_mode_enabled_filter, C, r_objects_len); +} + +static bool object_array_for_shading_edit_mode_disabled_filter(Object *ob, void *user_data) +{ + bContext *C = user_data; + if (object_materials_supported_poll_ex(C, ob)) { + if (BKE_object_is_in_editmode(ob) == false) { + return true; + } } - else { - ViewLayer *view_layer = CTX_data_view_layer(C); - objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - view_layer, v3d, r_objects_len); + return false; +} + +static Object **object_array_for_shading_edit_mode_disabled(bContext *C, uint *r_objects_len) +{ + return ED_object_array_in_mode_or_selected( + C, object_array_for_shading_edit_mode_disabled_filter, C, r_objects_len); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Shared Operator Poll Functions + * \{ */ + +static bool object_materials_supported_poll_ex(bContext *C, const Object *ob) +{ + if (!ED_operator_object_active_local_editable_ex(C, ob)) { + return false; } - return objects; + const ID *data = ob->data; + return (OB_TYPE_SUPPORT_MATERIAL(ob->type) && + /* Object data checks. */ + data && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data)); } -/********************** material slot operators *********************/ +static bool object_materials_supported_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + return object_materials_supported_poll_ex(C, ob); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot Add Operator + * \{ */ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -162,12 +198,18 @@ void OBJECT_OT_material_slot_add(wmOperatorType *ot) /* api callbacks */ ot->exec = material_slot_add_exec; - ot->poll = ED_operator_object_active_local_editable; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot Remove Operator + * \{ */ + static int material_slot_remove_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); @@ -207,12 +249,18 @@ void OBJECT_OT_material_slot_remove(wmOperatorType *ot) /* api callbacks */ ot->exec = material_slot_remove_exec; - ot->poll = ED_operator_object_active_local_editable; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot Assign Operator + * \{ */ + static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op)) { View3D *v3d = CTX_wm_view3d(C); @@ -222,7 +270,7 @@ static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op)) const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL; uint objects_len = 0; - Object **objects = object_array_for_shading(C, &objects_len); + Object **objects = object_array_for_shading_edit_mode_enabled(C, &objects_len); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; short mat_nr_active = -1; @@ -310,12 +358,18 @@ void OBJECT_OT_material_slot_assign(wmOperatorType *ot) /* api callbacks */ ot->exec = material_slot_assign_exec; - ot->poll = ED_operator_object_active_local_editable; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot (De)Select Operator + * \{ */ + static int material_slot_de_select(bContext *C, bool select) { bool changed_multi = false; @@ -323,7 +377,7 @@ static int material_slot_de_select(bContext *C, bool select) const Material *mat_active = obact ? BKE_object_material_get(obact, obact->actcol) : NULL; uint objects_len = 0; - Object **objects = object_array_for_shading(C, &objects_len); + Object **objects = object_array_for_shading_edit_mode_enabled(C, &objects_len); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; short mat_nr_active = -1; @@ -461,6 +515,12 @@ void OBJECT_OT_material_slot_deselect(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot Copy Operator + * \{ */ + static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); @@ -515,6 +575,12 @@ void OBJECT_OT_material_slot_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Slot Move Operator + * \{ */ + static int material_slot_move_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); @@ -576,8 +642,8 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) ot->description = "Move the active material up/down in the list"; /* api callbacks */ - ot->poll = ED_operator_object_active_local_editable; ot->exec = material_slot_move_exec; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -590,37 +656,46 @@ void OBJECT_OT_material_slot_move(wmOperatorType *ot) "Direction to move the active material towards"); } -static int material_slot_remove_unused_exec(bContext *C, wmOperator *op) -{ - Object *ob = CTX_data_active_object(C); +/** \} */ - if (!ob) { - return OPERATOR_CANCELLED; - } +/* -------------------------------------------------------------------- */ +/** \name Material Slot Remove Unused Operator + * \{ */ +static int material_slot_remove_unused_exec(bContext *C, wmOperator *op) +{ /* Removing material slots in edit mode screws things up, see bug #21822.*/ - if (ob == CTX_data_edit_object(C)) { + Object *ob_active = CTX_data_active_object(C); + if (ob_active && BKE_object_is_in_editmode(ob_active)) { BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode"); return OPERATOR_CANCELLED; } - int actcol = ob->actcol; - + Main *bmain = CTX_data_main(C); int removed = 0; - for (int slot = 1; slot <= ob->totcol; slot++) { - while (slot <= ob->totcol && !BKE_object_material_slot_used(ob->data, slot)) { - ob->actcol = slot; - BKE_object_material_slot_remove(CTX_data_main(C), ob); - if (actcol >= slot) { - actcol--; - } + uint objects_len = 0; + Object **objects = object_array_for_shading_edit_mode_disabled(C, &objects_len); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob = objects[ob_index]; + int actcol = ob->actcol; + for (int slot = 1; slot <= ob->totcol; slot++) { + while (slot <= ob->totcol && !BKE_object_material_slot_used(ob->data, slot)) { + ob->actcol = slot; + BKE_object_material_slot_remove(bmain, ob); + + if (actcol >= slot) { + actcol--; + } - removed++; + removed++; + } } - } + ob->actcol = actcol; - ob->actcol = actcol; + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + } + MEM_freeN(objects); if (!removed) { return OPERATOR_CANCELLED; @@ -628,16 +703,15 @@ static int material_slot_remove_unused_exec(bContext *C, wmOperator *op) BKE_reportf(op->reports, RPT_INFO, "Removed %d slots", removed); - if (ob->mode & OB_MODE_TEXTURE_PAINT) { + if (ob_active->mode & OB_MODE_TEXTURE_PAINT) { Scene *scene = CTX_data_scene(C); - BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL); + BKE_paint_proj_mesh_data_check(scene, ob_active, NULL, NULL, NULL, NULL); WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL); } - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); - WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); - WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_active); + WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob_active); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob_active); return OPERATOR_FINISHED; } @@ -651,13 +725,17 @@ void OBJECT_OT_material_slot_remove_unused(wmOperatorType *ot) /* api callbacks */ ot->exec = material_slot_remove_unused_exec; - ot->poll = ED_operator_object_active_local_editable; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/********************** new material operator *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name New Material Operator + * \{ */ static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -720,14 +798,18 @@ void MATERIAL_OT_new(wmOperatorType *ot) ot->description = "Add a new material"; /* api callbacks */ - ot->poll = ED_operator_object_active_local_editable; ot->exec = new_material_exec; + ot->poll = object_materials_supported_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } -/********************** new texture operator *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name New Texture Operator + * \{ */ static int new_texture_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -776,7 +858,11 @@ void TEXTURE_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } -/********************** new world operator *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name new world operator + * \{ */ static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) { @@ -827,7 +913,11 @@ void WORLD_OT_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } -/********************** render layer operators *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render Layer Add Operator + * \{ */ static int view_layer_add_exec(bContext *C, wmOperator *op) { @@ -877,6 +967,12 @@ void SCENE_OT_view_layer_add(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "type", type_items, 0, "Type", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render Layer Remove Operator + * \{ */ + static bool view_layer_remove_poll(bContext *C) { Scene *scene = CTX_data_scene(C); @@ -913,7 +1009,12 @@ void SCENE_OT_view_layer_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } -/********************** light cache operators *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Light Cache Bake Operator + * \{ */ + enum { LIGHTCACHE_SUBSET_ALL = 0, LIGHTCACHE_SUBSET_DIRTY, @@ -1079,6 +1180,12 @@ void SCENE_OT_light_cache_bake(wmOperatorType *ot) RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Light Cache Free Operator + * \{ */ + static bool light_cache_free_poll(bContext *C) { Scene *scene = CTX_data_scene(C); @@ -1122,7 +1229,11 @@ void SCENE_OT_light_cache_free(wmOperatorType *ot) ot->poll = light_cache_free_poll; } -/********************** render view operators *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render View Remove Operator + * \{ */ static bool render_view_remove_poll(bContext *C) { @@ -1158,6 +1269,12 @@ void SCENE_OT_render_view_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render View Add Operator + * \{ */ + static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1187,8 +1304,14 @@ void SCENE_OT_render_view_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/** \} */ + #ifdef WITH_FREESTYLE +/* -------------------------------------------------------------------- */ +/** \name Free Style Module Add Operator + * \{ */ + static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports) { if (!lineset) { @@ -1241,6 +1364,12 @@ void SCENE_OT_freestyle_module_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Module Remove Operator + * \{ */ + static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1287,6 +1416,12 @@ static int freestyle_module_move_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Module Move Operator + * \{ */ + void SCENE_OT_freestyle_module_move(wmOperatorType *ot) { static const EnumPropertyItem direction_items[] = { @@ -1316,6 +1451,12 @@ void SCENE_OT_freestyle_module_move(wmOperatorType *ot) "Direction to move the chosen style module towards"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set Add Operator + * \{ */ + static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); @@ -1344,6 +1485,12 @@ void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set Copy Operator + * \{ */ + static bool freestyle_active_lineset_poll(bContext *C) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1379,6 +1526,12 @@ void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set Paste Operator + * \{ */ + static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1407,6 +1560,12 @@ void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set Remove Operator + * \{ */ + static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); @@ -1435,6 +1594,12 @@ void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set Move Operator + * \{ */ + static int freestyle_lineset_move_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -1478,6 +1643,12 @@ void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot) "Direction to move the active line set towards"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Line Set New Operator + * \{ */ + static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -1516,6 +1687,12 @@ void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Add "Color" Operator + * \{ */ + static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1557,6 +1734,12 @@ void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot) ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Add "Alpha" Operator + * \{ */ + static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1598,6 +1781,12 @@ void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot) ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Add "Thickness" Operator + * \{ */ + static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1639,6 +1828,12 @@ void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot) ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Add "Geometry" Operator + * \{ */ + static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1680,6 +1875,12 @@ void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot) ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Remove Operator + * \{ */ + static int freestyle_get_modifier_type(PointerRNA *ptr) { if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier)) { @@ -1747,6 +1948,12 @@ void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Copy Operator + * \{ */ + static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1797,6 +2004,12 @@ void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Modifier Move Operator + * \{ */ + static int freestyle_modifier_move_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1866,6 +2079,12 @@ void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot) "Direction to move the chosen modifier towards"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Free Style Stroke Material Create Operator + * \{ */ + static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -1898,6 +2117,12 @@ void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot) #endif /* WITH_FREESTYLE */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Texture Slot Move Operator + * \{ */ + static int texture_slot_move_exec(bContext *C, wmOperator *op) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id; @@ -1966,7 +2191,11 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); } -/********************** material operators *********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Copy Operator + * \{ */ /* material copy/paste */ static int copy_material_exec(bContext *C, wmOperator *UNUSED(op)) @@ -1997,6 +2226,12 @@ void MATERIAL_OT_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Paste Operator + * \{ */ + static int paste_material_exec(bContext *C, wmOperator *UNUSED(op)) { Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data; @@ -2027,6 +2262,12 @@ void MATERIAL_OT_paste(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #MTex Copy/Paste Utilities + * \{ */ + static short mtexcopied = 0; /* must be reset on file load */ static MTex mtexcopybuf; @@ -2093,6 +2334,12 @@ static void paste_mtex_copybuf(ID *id) } } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Texture Slot Copy Operator + * \{ */ + static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op)) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id; @@ -2131,6 +2378,12 @@ void TEXTURE_OT_slot_copy(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Texture Slot Paste Operator + * \{ */ + static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op)) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).owner_id; @@ -2185,3 +2438,5 @@ void TEXTURE_OT_slot_paste(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL; } + +/** \} */ diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 7d0ad42c703..ce454d5eac2 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -194,7 +194,7 @@ void ED_render_engine_changed(Main *bmain, const bool update_scene_data) update_ctx.scene = scene; LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { /* TDODO(sergey): Iterate over depsgraphs instead? */ - update_ctx.depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); + update_ctx.depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer); update_ctx.view_layer = view_layer; ED_render_id_flush_update(&update_ctx, &scene->id); } diff --git a/source/blender/editors/scene/scene_edit.c b/source/blender/editors/scene/scene_edit.c index fa63a890de7..47edb322701 100644 --- a/source/blender/editors/scene/scene_edit.c +++ b/source/blender/editors/scene/scene_edit.c @@ -116,10 +116,10 @@ bool ED_scene_delete(bContext *C, Main *bmain, Scene *scene) /* Depsgraph updates after scene becomes active in a window. */ void ED_scene_change_update(Main *bmain, Scene *scene, ViewLayer *layer) { - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, layer, true); + Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, layer); BKE_scene_set_background(bmain, scene); - DEG_graph_relations_update(depsgraph, bmain, scene, layer); + DEG_graph_relations_update(depsgraph); DEG_on_visible_update(bmain, false); ED_render_engine_changed(bmain, false); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 38bac3afef6..921cc92299e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -93,9 +93,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si rect.ymax = scirct->ymax - region->winrct.ymin; /* set transp line */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; UI_GetThemeColor3fv(TH_EDITOR_OUTLINE, color); @@ -134,8 +132,7 @@ static void region_draw_emboss(const ARegion *region, const rcti *scirct, int si immEnd(); immUnbindProgram(); - GPU_blend(false); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_NONE); } void ED_region_pixelspace(ARegion *region) @@ -248,7 +245,7 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* NOTE(fclem): There is something strange going on with Mesa and GPU_SHADER_2D_UNIFORM_COLOR * that causes a crash on some GPUs (see T76113). Using 3D variant avoid the issue. */ immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -266,12 +263,12 @@ static void draw_azone_arrow(float x1, float y1, float x2, float y2, AZEdge edge immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void region_draw_azone_tab_arrow(ScrArea *area, ARegion *region, AZone *az) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* add code to draw region hidden as 'too small' */ switch (az->edge) { @@ -305,21 +302,17 @@ static void area_azone_tag_update(ScrArea *area) static void region_draw_azones(ScrArea *area, ARegion *region) { - AZone *az; - if (!area) { return; } GPU_line_width(1.0f); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_translate_2f(-region->winrct.xmin, -region->winrct.ymin); - for (az = area->actionzones.first; az; az = az->next) { + LISTBASE_FOREACH (AZone *, az, &area->actionzones) { /* test if action zone is over this region */ rcti azrct; BLI_rcti_init(&azrct, az->x1, az->x2, az->y1, az->y2); @@ -349,7 +342,7 @@ static void region_draw_azones(ScrArea *area, ARegion *region) GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void region_draw_status_text(ScrArea *area, ARegion *region) @@ -358,11 +351,9 @@ static void region_draw_status_text(ScrArea *area, ARegion *region) if (overlap) { GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); - GPU_clear(GPU_COLOR_BIT); } else { UI_ThemeClearColor(TH_HEADER); - GPU_clear(GPU_COLOR_BIT); } int fontid = BLF_set_default(); @@ -378,8 +369,7 @@ static void region_draw_status_text(ScrArea *area, ARegion *region) const float y1 = pad; const float y2 = region->winy - pad; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); float color[4] = {0.0f, 0.0f, 0.0f, 0.5f}; UI_GetThemeColor3fv(TH_BACK, color); @@ -527,7 +517,6 @@ void ED_region_do_draw(bContext *C, ARegion *region) if (area && area_is_pseudo_minimized(area)) { UI_ThemeClearColor(TH_EDITOR_OUTLINE); - GPU_clear(GPU_COLOR_BIT); return; } /* optional header info instead? */ @@ -548,7 +537,7 @@ void ED_region_do_draw(bContext *C, ARegion *region) /* for debugging unneeded area redraws and partial redraw */ if (G.debug_value == 888) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -559,7 +548,7 @@ void ED_region_do_draw(bContext *C, ARegion *region) region->drawrct.xmax - region->winrct.xmin, region->drawrct.ymax - region->winrct.ymin); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } memset(®ion->drawrct, 0, sizeof(region->drawrct)); @@ -711,10 +700,8 @@ void ED_region_tag_redraw_partial(ARegion *region, const rcti *rct, bool rebuild void ED_area_tag_redraw(ScrArea *area) { - ARegion *region; - if (area) { - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { ED_region_tag_redraw(region); } } @@ -722,10 +709,8 @@ void ED_area_tag_redraw(ScrArea *area) void ED_area_tag_redraw_no_rebuild(ScrArea *area) { - ARegion *region; - if (area) { - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { ED_region_tag_redraw_no_rebuild(region); } } @@ -733,10 +718,8 @@ void ED_area_tag_redraw_no_rebuild(ScrArea *area) void ED_area_tag_redraw_regiontype(ScrArea *area, int regiontype) { - ARegion *region; - if (area) { - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiontype == regiontype) { ED_region_tag_redraw(region); } @@ -756,14 +739,12 @@ void ED_area_tag_refresh(ScrArea *area) /* use NULL to disable it */ void ED_area_status_text(ScrArea *area, const char *str) { - ARegion *region; - /* happens when running transform operators in background mode */ if (area == NULL) { return; } - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiontype == RGN_TYPE_HEADER) { if (str) { if (region->headerstr == NULL) { @@ -948,7 +929,6 @@ static void region_azone_edge(AZone *az, ARegion *region) /* region already made zero sized, in shape of edge */ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) { - AZone *azt; int tot = 0, add; /* Edge offset multiplied by the */ @@ -956,7 +936,7 @@ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) const float tab_size_x = 0.7f * U.widget_unit; const float tab_size_y = 0.4f * U.widget_unit; - for (azt = area->actionzones.first; azt; azt = azt->next) { + LISTBASE_FOREACH (AZone *, azt, &area->actionzones) { if (azt->edge == az->edge) { tot++; } @@ -1852,7 +1832,6 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) WorkSpace *workspace = WM_window_get_active_workspace(win); const bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook); ViewLayer *view_layer = WM_window_get_active_view_layer(win); - ARegion *region; rcti rect, overlap_rect; rcti window_rect; @@ -1869,7 +1848,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) area->type = BKE_spacetype_from_id(area->spacetype); } - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { region->type = BKE_regiontype_from_id_or_first(area->type, region->regiontype); } @@ -1893,7 +1872,7 @@ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) area_azone_init(win, screen, area); /* region windows, default and own handlers */ - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { region_subwindow(region); if (region->visible) { @@ -2012,7 +1991,6 @@ void ED_region_toggle_hidden(bContext *C, ARegion *region) void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free) { SpaceType *st; - ARegion *region; const char spacetype = area_dst->spacetype; const short flag_copy = HEADER_NO_PULLDOWN; @@ -2032,13 +2010,13 @@ void ED_area_data_copy(ScrArea *area_dst, ScrArea *area_src, const bool do_free) /* regions */ if (do_free) { st = BKE_spacetype_from_id(spacetype); - for (region = area_dst->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area_dst->regionbase) { BKE_area_region_free(st, region); } BLI_freelistN(&area_dst->regionbase); } st = BKE_spacetype_from_id(area_src->spacetype); - for (region = area_src->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area_src->regionbase) { ARegion *newar = BKE_area_region_copy(st, region); BLI_addtail(&area_dst->regionbase, newar); } @@ -2053,6 +2031,241 @@ void ED_area_data_swap(ScrArea *area_dst, ScrArea *area_src) SWAP(ListBase, area_dst->regionbase, area_src->regionbase); } +/* -------------------------------------------------------------------- */ +/** \name Region Alignment Syncing for Space Switching + * \{ */ + +/** + * Store the alignment & other info per region type + * (use as a region-type aligned array). + * + * \note Currently this is only done for headers, + * we might want to do this with the tool-bar in the future too. + */ +struct RegionTypeAlignInfo { + struct { + /** + * Values match #ARegion.alignment without flags (see #RGN_ALIGN_ENUM_FROM_MASK). + * store all so we can sync alignment without adding extra checks. + */ + short alignment; + /** + * Needed for detecting which header displays the space-type switcher. + */ + bool hidden; + } by_type[RGN_TYPE_LEN]; +}; + +static void region_align_info_from_area(ScrArea *area, struct RegionTypeAlignInfo *r_align_info) +{ + for (int index = 0; index < RGN_TYPE_LEN; index++) { + r_align_info->by_type[index].alignment = -1; + /* Default to true, when it doesn't exist - it's effectively hidden. */ + r_align_info->by_type[index].hidden = true; + } + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + r_align_info->by_type[index].alignment = RGN_ALIGN_ENUM_FROM_MASK(region->alignment); + r_align_info->by_type[index].hidden = (region->flag & RGN_FLAG_HIDDEN) != 0; + } + } +} + +/** + * Keeping alignment between headers keep the space-type selector button in the same place. + * This is complicated by the editor-type selector being placed on the header + * closest to the screen edge which changes based on hidden state. + * + * The tool-header is used when visible, otherwise the header is used. + */ +static short region_alignment_from_header_and_tool_header_state( + const struct RegionTypeAlignInfo *region_align_info, const short fallback) +{ + const short header_alignment = region_align_info->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool header_hidden = region_align_info->by_type[RGN_TYPE_HEADER].hidden; + const bool tool_header_hidden = region_align_info->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + if ((tool_header_alignment != -1) && + /* If tool-header is hidden, use header alignment. */ + ((tool_header_hidden == false) || + /* Don't prioritize the tool-header if both are hidden (behave as if both are visible). + * Without this, switching to a space with headers hidden will flip the alignment + * upon switching to a space with visible headers. */ + (header_hidden && tool_header_hidden))) { + return tool_header_alignment; + } + if (header_alignment != -1) { + return header_alignment; + } + return fallback; +} + +/** + * Notes on header alignment syncing. + * + * This is as involved as it is because: + * + * - There are currently 3 kinds of headers. + * - All headers can independently visible & flipped to another side + * (except for the tool-header that depends on the header visibility). + * - We don't want the space-switching button to flip when switching spaces. + * From the user perspective it feels like a bug to move the button you click on + * to the opposite side of the area. + * - The space-switcher may be on either the header or the tool-header + * depending on the tool-header visibility. + * + * How this works: + * + * - When headers match on both spaces, we copy the alignment + * from the previous regions to the next regions when syncing. + * - Otherwise detect the _primary_ header (the one that shows the space type) + * and use this to set alignment for the headers in the destination area. + * - Header & tool-header/footer may be on opposite sides, this is preserved when syncing. + */ +static void region_align_info_to_area_for_headers( + const struct RegionTypeAlignInfo *region_align_info_src, + const struct RegionTypeAlignInfo *region_align_info_dst, + ARegion *region_by_type[RGN_TYPE_LEN]) +{ + /* Abbreviate access. */ + const short header_alignment_src = region_align_info_src->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_src = + region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].alignment; + + const bool tool_header_hidden_src = region_align_info_src->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + const short primary_header_alignment_src = region_alignment_from_header_and_tool_header_state( + region_align_info_src, -1); + + /* Neither alignments are usable, don't sync. */ + if (primary_header_alignment_src == -1) { + return; + } + + const short header_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_HEADER].alignment; + const short tool_header_alignment_dst = + region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].alignment; + const short footer_alignment_dst = region_align_info_dst->by_type[RGN_TYPE_FOOTER].alignment; + + const bool tool_header_hidden_dst = region_align_info_dst->by_type[RGN_TYPE_TOOL_HEADER].hidden; + + /* New synchronized alignments to set (or ignore when left as -1). */ + short header_alignment_sync = -1; + short tool_header_alignment_sync = -1; + short footer_alignment_sync = -1; + + /* Both source/destination areas have same region configurations regarding headers. + * Simply copy the values. */ + if (((header_alignment_src != -1) == (header_alignment_dst != -1)) && + ((tool_header_alignment_src != -1) == (tool_header_alignment_dst != -1)) && + (tool_header_hidden_src == tool_header_hidden_dst)) { + if (header_alignment_dst != -1) { + header_alignment_sync = header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = tool_header_alignment_src; + } + } + else { + /* Not an exact match, check the space selector isn't moving. */ + const short primary_header_alignment_dst = region_alignment_from_header_and_tool_header_state( + region_align_info_dst, -1); + + if (primary_header_alignment_src != primary_header_alignment_dst) { + if ((header_alignment_dst != -1) && (tool_header_alignment_dst != -1)) { + if (header_alignment_dst == tool_header_alignment_dst) { + /* Apply to both. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + tool_header_alignment_sync = primary_header_alignment_src; + header_alignment_sync = (tool_header_alignment_sync == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + else { + /* Apply what we can to regions that exist. */ + if (header_alignment_dst != -1) { + header_alignment_sync = primary_header_alignment_src; + } + if (tool_header_alignment_dst != -1) { + tool_header_alignment_sync = primary_header_alignment_src; + } + } + } + } + + if (footer_alignment_dst != -1) { + if ((header_alignment_dst != -1) && (header_alignment_dst == footer_alignment_dst)) { + /* Apply to both. */ + footer_alignment_sync = primary_header_alignment_src; + } + else { + /* Keep on opposite sides. */ + footer_alignment_sync = (primary_header_alignment_src == RGN_ALIGN_BOTTOM) ? + RGN_ALIGN_TOP : + RGN_ALIGN_BOTTOM; + } + } + + /* Finally apply synchronized flags. */ + if (header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (tool_header_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_TOOL_HEADER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(tool_header_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } + + if (footer_alignment_sync != -1) { + ARegion *region = region_by_type[RGN_TYPE_FOOTER]; + if (region != NULL) { + region->alignment = RGN_ALIGN_ENUM_FROM_MASK(footer_alignment_sync) | + RGN_ALIGN_FLAG_FROM_MASK(region->alignment); + } + } +} + +static void region_align_info_to_area( + ScrArea *area, const struct RegionTypeAlignInfo region_align_info_src[RGN_TYPE_LEN]) +{ + ARegion *region_by_type[RGN_TYPE_LEN] = {NULL}; + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + const int index = region->regiontype; + if ((uint)index < RGN_TYPE_LEN) { + region_by_type[index] = region; + } + } + + struct RegionTypeAlignInfo region_align_info_dst; + region_align_info_from_area(area, ®ion_align_info_dst); + + if ((region_by_type[RGN_TYPE_HEADER] != NULL) || + (region_by_type[RGN_TYPE_TOOL_HEADER] != NULL)) { + region_align_info_to_area_for_headers( + region_align_info_src, ®ion_align_info_dst, region_by_type); + } + + /* Note that we could support other region types. */ +} + +/** \} */ + /* *********** Space switching code *********** */ void ED_area_swapspace(bContext *C, ScrArea *sa1, ScrArea *sa2) @@ -2091,7 +2304,6 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi if (area->spacetype != type) { SpaceType *st; SpaceLink *slold = area->spacedata.first; - SpaceLink *sl; /* store area->type->exit callback */ void *area_exit = area->type ? area->type->exit : NULL; /* When the user switches between space-types from the type-selector, @@ -2104,9 +2316,13 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi * the space type defaults to in this case instead * (needed for preferences to have space-type on bottom). */ - int header_alignment = ED_area_header_alignment_or_fallback(area, -1); - const bool sync_header_alignment = ((header_alignment != -1) && - ((slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0)); + + bool sync_header_alignment = false; + struct RegionTypeAlignInfo region_align_info[RGN_TYPE_LEN]; + if ((slold != NULL) && (slold->link_flag & SPACE_FLAG_TYPE_TEMPORARY) == 0) { + region_align_info_from_area(area, region_align_info); + sync_header_alignment = true; + } /* in some cases (opening temp space) we don't want to * call area exit callback, so we temporarily unset it */ @@ -2131,8 +2347,10 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi * (e.g. with properties editor) until space-data is properly created */ /* check previously stored space */ - for (sl = area->spacedata.first; sl; sl = sl->next) { - if (sl->spacetype == type) { + SpaceLink *sl = NULL; + LISTBASE_FOREACH (SpaceLink *, sl_iter, &area->spacedata) { + if (sl_iter->spacetype == type) { + sl = sl_iter; break; } } @@ -2180,28 +2398,7 @@ void ED_area_newspace(bContext *C, ScrArea *area, int type, const bool skip_regi /* Sync header alignment. */ if (sync_header_alignment) { - /* Spaces with footer. */ - if (st->spaceid == SPACE_TEXT) { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - } - if (region->regiontype == RGN_TYPE_FOOTER) { - int footer_alignment = (header_alignment == RGN_ALIGN_BOTTOM) ? RGN_ALIGN_TOP : - RGN_ALIGN_BOTTOM; - region->alignment = footer_alignment; - break; - } - } - } - else { - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { - region->alignment = header_alignment; - break; - } - } - } + region_align_info_to_area(area, region_align_info); } ED_area_init(CTX_wm_manager(C), win, area); @@ -2329,11 +2526,9 @@ static void region_clear_color(const bContext *C, const ARegion *region, ThemeCo float back[4]; UI_GetThemeColor4fv(colorid, back); GPU_clear_color(back[3] * back[0], back[3] * back[1], back[3] * back[2], back[3]); - GPU_clear(GPU_COLOR_BIT); } else { UI_ThemeClearColor(colorid); - GPU_clear(GPU_COLOR_BIT); } } @@ -2357,14 +2552,12 @@ BLI_INLINE bool streq_array_any(const char *s, const char *arr[]) * correct old \a uiBlock, and NULL otherwise. */ static void ed_panel_draw(const bContext *C, - ScrArea *area, ARegion *region, ListBase *lb, PanelType *pt, Panel *panel, int w, int em, - bool vertical, char *unique_panel_str) { const uiStyle *style = UI_style_get_dpi(); @@ -2380,13 +2573,13 @@ static void ed_panel_draw(const bContext *C, uiBlock *block = UI_block_begin(C, region, block_name, UI_EMBOSS); bool open; - panel = UI_panel_begin(area, region, lb, block, pt, panel, &open); + panel = UI_panel_begin(region, lb, block, pt, panel, &open); /* bad fixed values */ int xco, yco, h = 0; int headerend = w - UI_UNIT_X; - if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + if (pt->draw_header_preset && !(pt->flag & PNL_NO_HEADER)) { /* for preset menu */ panel->layout = UI_block_layout(block, UI_LAYOUT_HORIZONTAL, @@ -2405,7 +2598,7 @@ static void ed_panel_draw(const bContext *C, panel->layout = NULL; } - if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + if (pt->draw_header && !(pt->flag & PNL_NO_HEADER)) { int labelx, labely; UI_panel_label_offset(block, &labelx, &labely); @@ -2482,21 +2675,12 @@ static void ed_panel_draw(const bContext *C, Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt); if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) { - ed_panel_draw(C, - area, - region, - &panel->children, - child_pt, - child_panel, - w, - em, - vertical, - unique_panel_str); + ed_panel_draw(C, region, &panel->children, child_pt, child_panel, w, em, unique_panel_str); } } } - UI_panel_end(area, region, block, w, h, open); + UI_panel_end(region, block, w, h, open); } /** @@ -2508,14 +2692,12 @@ void ED_region_panels_layout_ex(const bContext *C, ARegion *region, ListBase *paneltypes, const char *contexts[], - int contextnr, - const bool vertical, const char *category_override) { /* collect panels to draw */ WorkSpace *workspace = CTX_wm_workspace(C); LinkNode *panel_types_stack = NULL; - for (PanelType *pt = paneltypes->last; pt; pt = pt->prev) { + LISTBASE_FOREACH_BACKWARD (PanelType *, pt, paneltypes) { /* Only draw top level panels. */ if (pt->parent) { continue; @@ -2560,25 +2742,13 @@ void ED_region_panels_layout_ex(const bContext *C, const int category_tabs_width = UI_PANEL_CATEGORY_MARGIN_WIDTH; int margin_x = 0; const bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE; - const bool is_context_new = (contextnr != -1) ? UI_view2d_tab_set(v2d, contextnr) : false; bool update_tot_size = true; - /* before setting the view */ - if (vertical) { - /* only allow scrolling in vertical direction */ - v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y; - v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); - v2d->scroll &= ~V2D_SCROLL_BOTTOM; - v2d->scroll |= V2D_SCROLL_RIGHT; - } - else { - /* for now, allow scrolling in both directions (since layouts are optimized for vertical, - * they often don't fit in horizontal layout) - */ - v2d->keepofs &= ~(V2D_LOCKOFS_X | V2D_LOCKOFS_Y | V2D_KEEPOFS_X | V2D_KEEPOFS_Y); - v2d->scroll |= V2D_SCROLL_BOTTOM; - v2d->scroll &= ~V2D_SCROLL_RIGHT; - } + /* only allow scrolling in vertical direction */ + v2d->keepofs |= V2D_LOCKOFS_X | V2D_KEEPOFS_Y; + v2d->keepofs &= ~(V2D_LOCKOFS_Y | V2D_KEEPOFS_X); + v2d->scroll &= ~V2D_SCROLL_BOTTOM; + v2d->scroll |= V2D_SCROLL_RIGHT; /* collect categories */ if (use_category_tabs) { @@ -2603,14 +2773,8 @@ void ED_region_panels_layout_ex(const bContext *C, } } - if (vertical) { - w = BLI_rctf_size_x(&v2d->cur); - em = (region->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */ - } - else { - w = UI_PANEL_WIDTH; - em = (region->type->prefsizex) ? 10 : 20; - } + w = BLI_rctf_size_x(&v2d->cur); + em = (region->type->prefsizex) ? 10 : 20; /* works out to 10*UI_UNIT_X or 20*UI_UNIT_X */ w -= margin_x; int w_box_panel = w - UI_PANEL_BOX_STYLE_MARGIN * 2.0f; @@ -2643,14 +2807,12 @@ void ED_region_panels_layout_ex(const bContext *C, } ed_panel_draw(C, - area, region, ®ion->panels, pt, panel, (pt->flag & PNL_DRAW_BOX) ? w_box_panel : w, em, - vertical, NULL); } @@ -2678,14 +2840,12 @@ void ED_region_panels_layout_ex(const bContext *C, char unique_panel_str[8]; UI_list_panel_unique_str(panel, unique_panel_str); ed_panel_draw(C, - area, region, ®ion->panels, panel->type, panel, (panel->type->flag & PNL_DRAW_BOX) ? w_box_panel : w, em, - vertical, unique_panel_str); } } @@ -2713,7 +2873,7 @@ void ED_region_panels_layout_ex(const bContext *C, y = fabsf(region->sizey * UI_DPI_FAC - 1); } } - else if (vertical) { + else { /* We always keep the scroll offset - * so the total view gets increased with the scrolled away part. */ if (v2d->cur.ymax < -FLT_EPSILON) { @@ -2728,19 +2888,6 @@ void ED_region_panels_layout_ex(const bContext *C, y = -y; } - else { - /* don't jump back when panels close or hide */ - if (!is_context_new) { - if (v2d->tot.xmax > v2d->winx) { - x = max_ii(x, 0); - } - else { - x = max_ii(x, v2d->cur.xmax); - } - } - - y = -y; - } if (update_tot_size) { /* this also changes the 'cur' */ @@ -2754,8 +2901,7 @@ void ED_region_panels_layout_ex(const bContext *C, void ED_region_panels_layout(const bContext *C, ARegion *region) { - bool vertical = true; - ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, NULL, -1, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, NULL, NULL); } void ED_region_panels_draw(const bContext *C, ARegion *region) @@ -2799,12 +2945,10 @@ void ED_region_panels_draw(const bContext *C, ARegion *region) UI_view2d_scrollers_draw(v2d, mask); } -void ED_region_panels_ex( - const bContext *C, ARegion *region, const char *contexts[], int contextnr, const bool vertical) +void ED_region_panels_ex(const bContext *C, ARegion *region, const char *contexts[]) { /* TODO: remove? */ - ED_region_panels_layout_ex( - C, region, ®ion->type->paneltypes, contexts, contextnr, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, contexts, NULL); ED_region_panels_draw(C, region); } @@ -2830,7 +2974,6 @@ void ED_region_header_layout(const bContext *C, ARegion *region) const uiStyle *style = UI_style_get_dpi(); uiBlock *block; uiLayout *layout; - HeaderType *ht; Header header = {NULL}; bool region_layout_based = region->flag & RGN_FLAG_DYNAMIC_SIZE; @@ -2853,7 +2996,7 @@ void ED_region_header_layout(const bContext *C, ARegion *region) UI_view2d_view_ortho(®ion->v2d); /* draw all headers types */ - for (ht = region->type->headertypes.first; ht; ht = ht->next) { + LISTBASE_FOREACH (HeaderType *, ht, ®ion->type->headertypes) { if (ht->poll && !ht->poll(C, ht)) { continue; } @@ -2947,43 +3090,11 @@ int ED_area_headersize(void) return U.widget_unit + (int)(UI_DPI_FAC * HEADER_PADDING_Y); } -int ED_area_header_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_HEADER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_header_alignment(const ScrArea *area) -{ - return ED_area_header_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP); -} - int ED_area_footersize(void) { return ED_area_headersize(); } -int ED_area_footer_alignment_or_fallback(const ScrArea *area, int fallback) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region->regiontype == RGN_TYPE_FOOTER) { - return region->alignment; - } - } - return fallback; -} - -int ED_area_footer_alignment(const ScrArea *area) -{ - return ED_area_footer_alignment_or_fallback( - area, (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM); -} - /** * \return the final height of a global \a area, accounting for DPI. */ @@ -3084,19 +3195,17 @@ void ED_region_info_draw_multiline(ARegion *region, rect.ymin = rect.ymax - header_height * num_lines; /* setup scissor */ - GPU_scissor_get_i(scissor); + GPU_scissor_get(scissor); GPU_scissor(rect.xmin, rect.ymin, BLI_rcti_size_x(&rect) + 1, BLI_rcti_size_y(&rect) + 1); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor4fv(fill_color); immRecti(pos, rect.xmin, rect.ymin, rect.xmax + 1, rect.ymax + 1); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* text */ UI_FontThemeColor(fontid, TH_TEXT_HI); diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index c17a34f97b9..3c70bf1bfd8 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -204,7 +204,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult } if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; - EditBone *ebone, *flipbone = NULL; + EditBone *flipbone = NULL; const bool editable_bones = CTX_data_equals(member, "editable_bones"); if (arm && arm->edbo) { @@ -216,7 +216,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult arm = ob->data; /* Attention: X-Axis Mirroring is also handled here... */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled @@ -262,7 +262,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) { bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL; - EditBone *ebone, *flipbone = NULL; + EditBone *flipbone = NULL; const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones"); if (arm && arm->edbo) { @@ -274,7 +274,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult arm = ob->data; /* Attention: X-Axis Mirroring is also handled here... */ - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) { /* first and foremost, bone must be visible and selected */ if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) { /* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled @@ -479,8 +479,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if (CTX_data_equals(member, "sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { + LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); @@ -491,8 +490,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if (CTX_data_equals(member, "selected_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { + LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } @@ -505,8 +503,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult if (CTX_data_equals(member, "selected_editable_sequences")) { Editing *ed = BKE_sequencer_editing_get(scene, false); if (ed) { - Sequence *seq; - for (seq = ed->seqbasep->first; seq; seq = seq->next) { + LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) { if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) { CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq); } @@ -520,16 +517,14 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult bAnimContext ac; if (ANIM_animdata_get_context(C, &ac) != 0) { ListBase anim_data = {NULL, NULL}; - bAnimListElem *ale; ANIM_animdata_filter(&ac, &anim_data, ANIMFILTER_DATA_VISIBLE, ac.data, ac.datatype); - for (ale = anim_data.first; ale; ale = ale->next) { + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { if (ale->datatype != ALE_NLASTRIP) { continue; } NlaTrack *nlt = (NlaTrack *)ale->data; - NlaStrip *strip; - for (strip = nlt->strips.first; strip; strip = strip->next) { + LISTBASE_FOREACH (NlaStrip *, strip, &nlt->strips) { if (strip->flag & NLASTRIP_FLAG_SELECT) { CTX_data_list_add(result, &scene->id, &RNA_NlaStrip, strip); } @@ -637,9 +632,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { if ((gpl->flag & GP_LAYER_HIDE) == 0) { CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); } @@ -653,9 +646,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult bGPdata *gpd = ED_gpencil_data_get_active_direct(area, obact); if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { if (BKE_gpencil_layer_is_editable(gpl)) { CTX_data_list_add(result, &gpd->id, &RNA_GPencilLayer, gpl); } @@ -670,12 +661,9 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); if (gpd) { - bGPDlayer *gpl; - - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe)) { bGPDframe *gpf; - bGPDstroke *gps; bGPDframe *init_gpf = gpl->actframe; if (is_multiedit) { init_gpf = gpl->frames.first; @@ -683,7 +671,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult for (gpf = init_gpf; gpf; gpf = gpf->next) { if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { - for (gps = gpf->strokes.first; gps; gps = gps->next) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { if (ED_gpencil_stroke_can_use_direct(area, gps)) { /* check if the color is editable */ if (ED_gpencil_stroke_color_use(obact, gpl, gps) == false) { diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index 40a452a5363..8ded845b008 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -296,8 +296,7 @@ static GPUBatch *batch_screen_edges_get(int *corner_len) */ static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(0, 0, 0, 50); draw_join_shape(area, dir, pos); @@ -308,10 +307,8 @@ static void scrarea_draw_shape_dark(ScrArea *area, char dir, uint pos) */ static void scrarea_draw_shape_light(ScrArea *area, char UNUSED(dir), uint pos) { - GPU_blend_set_func(GPU_DST_COLOR, GPU_SRC_ALPHA); - /* value 181 was hardly computed: 181~105 */ - immUniformColor4ub(255, 255, 255, 50); - /* draw_join_shape(area, dir); */ + GPU_blend(GPU_BLEND_ALPHA); + immUniformColor4ub(255, 255, 255, 25); immRectf(pos, area->v1->vec.x, area->v1->vec.y, area->v3->vec.x, area->v3->vec.y); } @@ -343,6 +340,7 @@ static void drawscredge_area_draw( } GPUBatch *batch = batch_screen_edges_get(NULL); + GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES); GPU_batch_uniform_4fv(batch, "rect", (float *)&rect); GPU_batch_draw(batch); } @@ -381,11 +379,9 @@ void ED_screen_draw_edges(wmWindow *win) float col[4], corner_scale, edge_thickness; int verts_per_corner = 0; - ScrArea *area; - rcti scissor_rect; BLI_rcti_init_minmax(&scissor_rect); - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){area->v1->vec.x, area->v1->vec.y}); BLI_rcti_do_minmax_v(&scissor_rect, (int[2]){area->v3->vec.x, area->v3->vec.y}); } @@ -412,9 +408,7 @@ void ED_screen_draw_edges(wmWindow *win) corner_scale = U.pixelsize * 8.0f; edge_thickness = corner_scale * 0.21f; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = batch_screen_edges_get(&verts_per_corner); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_AREA_EDGES); @@ -422,11 +416,11 @@ void ED_screen_draw_edges(wmWindow *win) GPU_batch_uniform_1f(batch, "scale", corner_scale); GPU_batch_uniform_4fv(batch, "color", col); - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { drawscredge_area(area, winsize_x, winsize_y, edge_thickness); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (U.pixelsize <= 1.0f) { GPU_scissor_test(false); @@ -469,12 +463,12 @@ void ED_screen_draw_join_shape(ScrArea *sa1, ScrArea *sa2) break; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); scrarea_draw_shape_dark(sa2, dir, pos); scrarea_draw_shape_light(sa1, dira, pos); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -486,9 +480,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); /* splitpoint */ - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor4ub(255, 255, 255, 100); @@ -530,7 +522,7 @@ void ED_screen_draw_split_preview(ScrArea *area, const int dir, const float fac) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -614,8 +606,8 @@ void ED_screen_preview_render(const bScreen *screen, int size_x, int size_y, uin GPUOffScreen *offscreen = GPU_offscreen_create(size_x, size_y, true, false, err_out); GPU_offscreen_bind(offscreen, true); - GPU_clear_color(0.0, 0.0, 0.0, 0.0); - GPU_clear(GPU_COLOR_BIT | GPU_DEPTH_BIT); + GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); + GPU_clear_depth(1.0f); screen_preview_draw(screen, size_x, size_y); diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 06e800433b1..f534296bd0b 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -230,8 +230,7 @@ bScreen *screen_add(Main *bmain, const char *name, const rcti *rect) void screen_data_copy(bScreen *to, bScreen *from) { - ScrVert *s1, *s2; - ScrEdge *se; + ScrVert *s2; ScrArea *area, *saf; /* free contents of 'to', is from blenkernel screen.c */ @@ -245,11 +244,11 @@ void screen_data_copy(bScreen *to, bScreen *from) BLI_listbase_clear(&to->regionbase); s2 = to->vertbase.first; - for (s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) { + for (ScrVert *s1 = from->vertbase.first; s1; s1 = s1->next, s2 = s2->next) { s1->newv = s2; } - for (se = to->edgebase.first; se; se = se->next) { + LISTBASE_FOREACH (ScrEdge *, se, &to->edgebase) { se->v1 = se->v1->newv; se->v2 = se->v2->newv; BKE_screen_sort_scrvert(&(se->v1), &(se->v2)); @@ -271,7 +270,7 @@ void screen_data_copy(bScreen *to, bScreen *from) } /* put at zero (needed?) */ - for (s1 = from->vertbase.first; s1; s1 = s1->next) { + LISTBASE_FOREACH (ScrVert *, s1, &from->vertbase) { s1->newv = NULL; } } @@ -538,9 +537,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) /* file read, set all screens, ... */ void ED_screens_init(Main *bmain, wmWindowManager *wm) { - wmWindow *win; - - for (win = wm->windows.first; win; win = win->next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { if (BKE_workspace_active_get(win->workspace_hook) == NULL) { BKE_workspace_active_set(win->workspace_hook, bmain->workspaces.first); } @@ -552,7 +549,7 @@ void ED_screens_init(Main *bmain, wmWindowManager *wm) } if (U.uiflag & USER_HEADER_FROM_PREF) { - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { BKE_screen_header_alignment_reset(screen); } } @@ -614,7 +611,6 @@ void ED_area_exit(bContext *C, ScrArea *area) wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); ScrArea *prevsa = CTX_wm_area(C); - ARegion *region; if (area->type && area->type->exit) { area->type->exit(wm, area); @@ -622,7 +618,7 @@ void ED_area_exit(bContext *C, ScrArea *area) CTX_wm_area_set(C, area); - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { ED_region_exit(C, region); } @@ -683,10 +679,11 @@ static void screen_cursor_set(wmWindow *win, const int xy[2]) { const bScreen *screen = WM_window_get_active_screen(win); AZone *az = NULL; - ScrArea *area; + ScrArea *area = NULL; - for (area = screen->areabase.first; area; area = area->next) { - if ((az = ED_area_actionzone_find_xy(area, xy))) { + LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) { + if ((az = ED_area_actionzone_find_xy(area_iter, xy))) { + area = area_iter; break; } } @@ -733,7 +730,6 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) } ScrArea *area = NULL; - ARegion *region; ARegion *region_prev = screen->active_region; ED_screen_areas_iter (win, screen, area_iter) { @@ -750,7 +746,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) } if (area) { /* Make overlap active when mouse over. */ - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (ED_region_contains_xy(region, xy)) { screen->active_region = region; break; @@ -767,8 +763,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) ED_screen_areas_iter (win, screen, area_iter) { bool do_draw = false; - for (region = area_iter->regionbase.first; region; region = region->next) { - + LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) { /* Call old area's deactivate if assigned. */ if (region == region_prev && area_iter->type->deactivate) { area_iter->type->deactivate(area_iter); @@ -789,7 +784,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) } if (do_draw) { - for (region = area_iter->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area_iter->regionbase) { if (ELEM(region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER)) { ED_region_tag_redraw_no_rebuild(region); } @@ -826,13 +821,12 @@ int ED_screen_area_active(const bContext *C) if (win && screen && area) { AZone *az = ED_area_actionzone_find_xy(area, &win->eventstate->x); - ARegion *region; if (az && az->type == AZONE_REGION) { return 1; } - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region == screen->active_region) { return 1; } @@ -883,10 +877,10 @@ static void screen_global_area_refresh(wmWindow *win, const short height_min, const short height_max) { - ScrArea *area; - - for (area = win->global_areas.areabase.first; area; area = area->next) { - if (area->spacetype == space_type) { + ScrArea *area = NULL; + LISTBASE_FOREACH (ScrArea *, area_iter, &win->global_areas.areabase) { + if (area_iter->spacetype == space_type) { + area = area_iter; break; } } @@ -1081,7 +1075,6 @@ static void screen_set_3dview_camera(Scene *scene, v3d->camera = BKE_view_layer_camera_find(view_layer); // XXX if (screen == curscreen) handle_view3d_lock(); if (!v3d->camera) { - ARegion *region; ListBase *regionbase; /* regionbase is in different place depending if space is active */ @@ -1092,7 +1085,7 @@ static void screen_set_3dview_camera(Scene *scene, regionbase = &v3d->regionbase; } - for (region = regionbase->first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, regionbase) { if (region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; if (rv3d->persp == RV3D_CAMOB) { @@ -1240,13 +1233,12 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const wmWindowManager *wm = CTX_wm_manager(C); WorkSpace *workspace = WM_window_get_active_workspace(win); bScreen *screen, *oldscreen; - ARegion *region; if (area) { /* ensure we don't have a button active anymore, can crash when * switching screens with tooltip open because region and tooltip * are no longer in the same screen */ - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { UI_blocklist_free(C, ®ion->uiblocks); if (region->regiontimer) { @@ -1299,7 +1291,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const glob_area->global->flag &= ~GLOBAL_AREA_IS_HIDDEN; } /* restore the old side panels/header visibility */ - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { region->flag = region->flagfullscreen; } } @@ -1364,7 +1356,7 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *area, const glob_area->global->flag |= GLOBAL_AREA_IS_HIDDEN; } /* temporarily hide the side panels/header */ - for (region = newa->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &newa->regionbase) { region->flagfullscreen = region->flag; if (ELEM(region->regiontype, @@ -1537,13 +1529,11 @@ void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable) static ARegion *time_top_left_3dwindow(bScreen *screen) { ARegion *aret = NULL; - ScrArea *area; int min = 10000; - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (area->spacetype == SPACE_VIEW3D) { - ARegion *region; - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiontype == RGN_TYPE_WINDOW) { if (region->winrct.xmin - region->winrct.ymin < min) { aret = region; @@ -1576,15 +1566,14 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) { Scene *scene = DEG_get_input_scene(depsgraph); - DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_TIME); + DEG_time_tag_update(bmain); #ifdef DURIAN_CAMERA_SWITCH void *camera = BKE_scene_camera_switch_find(scene); if (camera && scene->camera != camera) { - bScreen *screen; scene->camera = camera; /* are there cameras in the views that are not in the scene? */ - for (screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { BKE_screen_view3d_scene_sync(screen, scene); } DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); @@ -1594,7 +1583,7 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) ED_clip_update_frame(bmain, scene->r.cfra); /* this function applies the changes too */ - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } /* @@ -1602,10 +1591,9 @@ void ED_update_for_newframe(Main *bmain, Depsgraph *depsgraph) */ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene) { - ScrArea *area; const bool is_multiview = (scene->r.scemode & R_MULTIVIEW) != 0; - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { switch (area->spacetype) { case SPACE_VIEW3D: { View3D *v3d; @@ -1616,8 +1604,7 @@ bool ED_screen_stereo3d_required(const bScreen *screen, const Scene *scene) v3d = area->spacedata.first; if (v3d->camera && v3d->stereo3d_camera == STEREO_3D_ID) { - ARegion *region; - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { if (region->regiondata && region->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d = region->regiondata; if (rv3d->persp == RV3D_CAMOB) { diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c index 0b83a657265..4917dfa5e69 100644 --- a/source/blender/editors/screen/screen_geometry.c +++ b/source/blender/editors/screen/screen_geometry.c @@ -162,7 +162,6 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen) const int screen_size_x = BLI_rcti_size_x(&screen_rect); const int screen_size_y = BLI_rcti_size_y(&screen_rect); - ScrVert *sv = NULL; int screen_size_x_prev, screen_size_y_prev; float min[2], max[2]; @@ -170,7 +169,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen) min[0] = min[1] = 20000.0f; max[0] = max[1] = 0.0f; - for (sv = screen->vertbase.first; sv; sv = sv->next) { + LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { const float fv[2] = {(float)sv->vec.x, (float)sv->vec.y}; minmax_v2v2_v2(min, max, fv); } @@ -183,7 +182,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen) const float facy = ((float)screen_size_y - 1) / ((float)screen_size_y_prev - 1); /* make sure it fits! */ - for (sv = screen->vertbase.first; sv; sv = sv->next) { + LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { sv->vec.x = screen_rect.xmin + round_fl_to_short((sv->vec.x - min[0]) * facx); CLAMP(sv->vec.x, screen_rect.xmin, screen_rect.xmax - 1); @@ -208,7 +207,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen) screen_geom_select_connected_edge(win, se); /* all selected vertices get the right offset */ - for (sv = screen->vertbase.first; sv; sv = sv->next) { + LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { /* if is a collapsed area */ if (sv != area->v1 && sv != area->v4) { if (sv->flag) { @@ -232,7 +231,7 @@ void screen_geom_vertices_scale(const wmWindow *win, bScreen *screen) screen_geom_select_connected_edge(win, se); /* all selected vertices get the right offset */ - for (sv = screen->vertbase.first; sv; sv = sv->next) { + LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { /* if is not a collapsed area */ if (sv != area->v2 && sv != area->v3) { if (sv->flag) { diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b002b23a7f3..5730d8b2d03 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -363,6 +363,11 @@ bool ED_operator_object_active_editable(bContext *C) } /** Object must be editable and fully local (i.e. not an override). */ +bool ED_operator_object_active_local_editable_ex(bContext *C, const Object *ob) +{ + return ED_operator_object_active_editable_ex(C, ob) && !ID_IS_OVERRIDE_LIBRARY(ob); +} + bool ED_operator_object_active_local_editable(bContext *C) { Object *ob = ED_object_active_context(C); @@ -692,10 +697,9 @@ static bool actionzone_area_poll(bContext *C) if (screen && win && win->eventstate) { const int *xy = &win->eventstate->x; - AZone *az; LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - for (az = area->actionzones.first; az; az = az->next) { + LISTBASE_FOREACH (AZone *, az, &area->actionzones) { if (BLI_rcti_isect_pt_v(&az->rect, xy)) { return 1; } @@ -3068,13 +3072,12 @@ static void SCREEN_OT_keyframe_jump(wmOperatorType *ot) static int marker_jump_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - TimeMarker *marker; int closest = CFRA; const bool next = RNA_boolean_get(op->ptr, "next"); bool found = false; /* find matching marker in the right direction */ - for (marker = scene->markers.first; marker; marker = marker->next) { + LISTBASE_FOREACH (TimeMarker *, marker, &scene->markers) { if (next) { if ((marker->frame > CFRA) && (!found || closest > marker->frame)) { closest = marker->frame; @@ -3170,8 +3173,9 @@ static int screen_maximize_area_exec(bContext *C, wmOperator *op) /* search current screen for 'fullscreen' areas */ /* prevents restoring info header, when mouse is over it */ - for (area = screen->areabase.first; area; area = area->next) { - if (area->full) { + LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) { + if (area_iter->full) { + area = area_iter; break; } } @@ -3619,12 +3623,10 @@ static void SCREEN_OT_area_options(wmOperatorType *ot) static int spacedata_cleanup_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); - bScreen *screen; - ScrArea *area; int tot = 0; - for (screen = bmain->screens.first; screen; screen = screen->id.next) { - for (area = screen->areabase.first; area; area = area->next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { if (area->spacedata.first != area->spacedata.last) { SpaceLink *sl = area->spacedata.first; @@ -3854,7 +3856,6 @@ static int region_quadview_exec(bContext *C, wmOperator *op) region->alignment = 0; if (area->spacetype == SPACE_VIEW3D) { - ARegion *region_iter; RegionView3D *rv3d = region->regiondata; /* if this is a locked view, use settings from 'User' view */ @@ -3878,7 +3879,7 @@ static int region_quadview_exec(bContext *C, wmOperator *op) rv3d->rflag |= RV3D_GPULIGHT_UPDATE; /* Accumulate locks, in case they're mixed. */ - for (region_iter = area->regionbase.first; region_iter; region_iter = region_iter->next) { + LISTBASE_FOREACH (ARegion *, region_iter, &area->regionbase) { if (region_iter->regiontype == RGN_TYPE_WINDOW) { RegionView3D *rv3d_iter = region_iter->regiondata; rv3d->viewlock_quad |= rv3d_iter->viewlock; @@ -4436,13 +4437,11 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = WM_window_get_active_view_layer(win); - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, false); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer); Scene *scene_eval = (depsgraph != NULL) ? DEG_get_evaluated_scene(depsgraph) : NULL; wmTimer *wt = screen->animtimer; ScreenAnimData *sad = wt->customdata; wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *window; - ScrArea *area; int sync; double time; @@ -4588,12 +4587,11 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv ED_update_for_newframe(bmain, depsgraph); } - for (window = wm->windows.first; window; window = window->next) { + LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { const bScreen *win_screen = WM_window_get_active_screen(window); - for (area = win_screen->areabase.first; area; area = area->next) { - ARegion *region; - for (region = area->regionbase.first; region; region = region->next) { + LISTBASE_FOREACH (ScrArea *, area, &win_screen->areabase) { + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { bool redraw = false; if (region == sad->region) { redraw = true; @@ -4867,8 +4865,9 @@ static int fullscreen_back_exec(bContext *C, wmOperator *op) ScrArea *area = NULL; /* search current screen for 'fullscreen' areas */ - for (area = screen->areabase.first; area; area = area->next) { - if (area->full) { + LISTBASE_FOREACH (ScrArea *, area_iter, &screen->areabase) { + if (area_iter->full) { + area = area_iter; break; } } diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index b20dc80d158..702c824077d 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -409,8 +409,7 @@ static void workspace_add_menu(bContext *UNUSED(C), uiLayout *layout, void *temp WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template); if (startup_config) { - for (WorkSpace *workspace = startup_config->workspaces.first; workspace; - workspace = workspace->id.next) { + LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) { uiLayout *row = uiLayoutRow(layout, false); workspace_append_button(row, ot_append, workspace, startup_config->main); has_startup_items = true; @@ -420,8 +419,7 @@ static void workspace_add_menu(bContext *UNUSED(C), uiLayout *layout, void *temp if (builtin_config) { bool has_title = false; - for (WorkSpace *workspace = builtin_config->workspaces.first; workspace; - workspace = workspace->id.next) { + LISTBASE_FOREACH (WorkSpace *, workspace, &builtin_config->workspaces) { if (startup_config && BLI_findstring(&startup_config->workspaces, workspace->id.name, offsetof(ID, name))) { continue; diff --git a/source/blender/editors/screen/workspace_layout_edit.c b/source/blender/editors/screen/workspace_layout_edit.c index 8a36cffa1f1..f4b076aca00 100644 --- a/source/blender/editors/screen/workspace_layout_edit.c +++ b/source/blender/editors/screen/workspace_layout_edit.c @@ -168,8 +168,7 @@ static bool workspace_change_find_new_layout_cb(const WorkSpaceLayout *layout, v static bScreen *screen_fullscreen_find_associated_normal_screen(const Main *bmain, bScreen *screen) { - for (bScreen *screen_iter = bmain->screens.first; screen_iter; - screen_iter = screen_iter->id.next) { + LISTBASE_FOREACH (bScreen *, screen_iter, &bmain->screens) { if ((screen_iter != screen) && ELEM(screen_iter->state, SCREENMAXIMIZED, SCREENFULL)) { ScrArea *area = screen_iter->areabase.first; if (area && area->full == screen) { diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 88998d5063d..ee514fa745c 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -566,7 +566,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, if (load_tex(brush, vc, zoom, col, primary)) { GPU_color_mask(true, true, true, true); - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { GPU_matrix_push(); @@ -634,8 +634,7 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* Premultiplied alpha blending. */ - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -670,8 +669,6 @@ static bool paint_draw_tex_overlay(UnifiedPaintSettings *ups, GPU_texture_unbind(texture); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_STENCIL, MTEX_MAP_MODE_VIEW)) { GPU_matrix_pop(); } @@ -696,7 +693,7 @@ static bool paint_draw_cursor_overlay( float center[2]; GPU_color_mask(true, true, true, true); - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); if (ups->draw_anchored) { copy_v2_v2(center, ups->anchored_initial_mouse); @@ -729,8 +726,7 @@ static bool paint_draw_cursor_overlay( uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint texCoord = GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR); @@ -757,8 +753,6 @@ static bool paint_draw_cursor_overlay( immUnbindProgram(); - GPU_blend_set_func(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA); - if (do_pop) { GPU_matrix_pop(); } @@ -781,7 +775,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups, bool alpha_overlay_active = false; ePaintOverlayControlFlags flags = BKE_paint_get_overlay_flags(); - gpuPushAttr(GPU_DEPTH_BUFFER_BIT | GPU_BLEND_BIT); + eGPUBlend blend_state = GPU_blend_get(); + eGPUDepthTest depth_test = GPU_depth_test_get(); /* Translate to region. */ GPU_matrix_push(); @@ -811,7 +806,8 @@ static bool paint_draw_alpha_overlay(UnifiedPaintSettings *ups, } GPU_matrix_pop(); - gpuPopAttr(); + GPU_blend(blend_state); + GPU_depth_test(depth_test); return alpha_overlay_active; } @@ -922,7 +918,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc) PaintCurvePoint *cp = pc->points; GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Draw the bezier handles and the curve segment between the current and next point. */ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -983,7 +979,7 @@ static void paint_draw_curve_cursor(Brush *brush, ViewContext *vc) draw_rect_point( pos, selec_col, handle_col, &cp->bez.vec[2][0], 8.0f, cp->bez.f3 || cp->bez.f2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); immUnbindProgram(); @@ -1151,9 +1147,9 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, immUniformColor4f(1.0f, 1.0f, 1.0f, 0.6f); /* Cursor normally draws on top, but for this part we need depth tests. */ - const bool depth_test = GPU_depth_test_enabled(); + const eGPUDepthTest depth_test = GPU_depth_test_get(); if (!depth_test) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } GPU_line_width(1.0f); @@ -1167,7 +1163,7 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, /* Restore depth test value. */ if (!depth_test) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } } @@ -1542,7 +1538,7 @@ static void paint_cursor_preview_boundary_data_update(PaintCursorContext *pconte } ss->boundary_preview = SCULPT_boundary_data_init( - pcontext->vc.obact, ss->active_vertex_index, pcontext->radius); + pcontext->vc.obact, pcontext->brush, ss->active_vertex_index, pcontext->radius); } static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) @@ -1762,9 +1758,6 @@ static void paint_cursor_cursor_draw_3d_view_brush_cursor_active(PaintCursorCont GPU_matrix_pop(); - /* This Cloth brush cursor overlay always works in cursor space. */ - paint_cursor_drawing_setup_cursor_space(pcontext); - GPU_matrix_pop_projection(); wmWindowViewport(pcontext->win); } @@ -1842,7 +1835,7 @@ static void paint_cursor_update_anchored_location(PaintCursorContext *pcontext) static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext) { GPU_line_width(2.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); pcontext->pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1852,7 +1845,7 @@ static void paint_cursor_setup_2D_drawing(PaintCursorContext *pcontext) static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) { GPU_line_width(2.0f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); pcontext->pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -1862,7 +1855,7 @@ static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) static void paint_cursor_restore_drawing_state(void) { immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 431ab998f62..d2ae6912fc3 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -438,7 +438,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda if (pop) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -467,7 +467,7 @@ static void gradient_draw_line(bContext *UNUSED(C), int x, int y, void *customda immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index db7de01bee5..456c1f61cb1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -407,7 +407,6 @@ typedef struct ProjPaintState { SpinLock *tile_lock; Mesh *me_eval; - bool me_eval_free; int totlooptri_eval; int totloop_eval; int totpoly_eval; @@ -4033,27 +4032,14 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask; cddata_masks.fmask |= CD_MASK_MTFACE; cddata_masks.lmask |= CD_MASK_MLOOPUV; - - /* Workaround for subsurf selection, try the display mesh first */ - if (ps->source == PROJ_SRC_IMAGE_CAM) { - /* using render mesh, assume only camera was rendered from */ - ps->me_eval = mesh_create_eval_final_render(depsgraph, scene_eval, ob_eval, &cddata_masks); - ps->me_eval_free = true; - } - else { - if (ps->do_face_sel) { - cddata_masks.vmask |= CD_MASK_ORIGINDEX; - cddata_masks.emask |= CD_MASK_ORIGINDEX; - cddata_masks.pmask |= CD_MASK_ORIGINDEX; - } - ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); - ps->me_eval_free = false; + if (ps->do_face_sel) { + cddata_masks.vmask |= CD_MASK_ORIGINDEX; + cddata_masks.emask |= CD_MASK_ORIGINDEX; + cddata_masks.pmask |= CD_MASK_ORIGINDEX; } + ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { - if (ps->me_eval_free) { - BKE_id_free(NULL, ps->me_eval); - } ps->me_eval = NULL; return false; } @@ -4636,9 +4622,6 @@ static void project_paint_end(ProjPaintState *ps) MEM_freeN(ps->cavities); } - if (ps->me_eval_free) { - BKE_id_free(NULL, ps->me_eval); - } ps->me_eval = NULL; } diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 05ffb80d8a1..ab8b81a8155 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -31,6 +31,7 @@ #include "BLI_lasso_2d.h" #include "BLI_math_geom.h" #include "BLI_math_matrix.h" +#include "BLI_rect.h" #include "BLI_task.h" #include "BLI_utildefines.h" @@ -221,392 +222,383 @@ void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot) 1.0f); } -/* Box select, operator is VIEW3D_OT_select_box, defined in view3d_select.c. */ +/* Sculpt Gesture Operators. */ -static bool is_effected(float planes[4][4], const float co[3]) -{ - return isect_point_planes_v3(planes, 4, co); -} +typedef enum eSculptGestureShapeType { + SCULPT_GESTURE_SHAPE_BOX, + SCULPT_GESTURE_SHAPE_LASSO, +} eMaskGesturesShapeType; -static void flip_plane(float out[4], const float in[4], const char symm) -{ - if (symm & PAINT_SYMM_X) { - out[0] = -in[0]; - } - else { - out[0] = in[0]; - } - if (symm & PAINT_SYMM_Y) { - out[1] = -in[1]; - } - else { - out[1] = in[1]; - } - if (symm & PAINT_SYMM_Z) { - out[2] = -in[2]; - } - else { - out[2] = in[2]; - } +typedef struct LassoGestureData { + float projviewobjmat[4][4]; - out[3] = in[3]; -} + rcti boundbox; + int width; -static void mask_box_select_task_cb(void *__restrict userdata, - const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) -{ - MaskTaskData *data = userdata; + /* 2D bitmap to test if a vertex is affected by the lasso shape. */ + BLI_bitmap *mask_px; +} LassoGestureData; - PBVHNode *node = data->nodes[i]; +typedef struct SculptGestureContext { + SculptSession *ss; + ViewContext vc; - const PaintMaskFloodMode mode = data->mode; - const float value = data->value; - float(*clip_planes_final)[4] = data->clip_planes_final; + /* Enabled and currently active symmetry. */ + ePaintSymmetryFlags symm; + ePaintSymmetryFlags symmpass; - PBVHVertexIter vi; - bool any_masked = false; - bool redraw = false; + /* Operation parameters. */ + eMaskGesturesShapeType shape_type; + bool front_faces_only; - float vertex_normal[3]; + /* Mask operation parameters. */ + PaintMaskFloodMode mask_mode; + float mask_value; - BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) - { - SCULPT_vertex_normal_get(data->ob->sculpt, vi.index, vertex_normal); - float dot = dot_v3v3(data->view_normal, vertex_normal); - const bool is_effected_front_face = !(data->front_faces_only && dot < 0.0f); + /* View parameters. */ + float true_view_normal[3]; + float view_normal[3]; - if (is_effected_front_face && is_effected(clip_planes_final, vi.co)) { - float prevmask = *vi.mask; - if (!any_masked) { - any_masked = true; + float true_clip_planes[4][4]; + float clip_planes[4][4]; - SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); + /* Lasso Gesture. */ + LassoGestureData lasso; - if (data->multires) { - BKE_pbvh_node_mark_normals_update(node); - } - } - mask_flood_fill_set_elem(vi.mask, mode, value); - if (prevmask != *vi.mask) { - redraw = true; - } - } - } - BKE_pbvh_vertex_iter_end; + /* Task Callback Data. */ + PBVHNode **nodes; + int totnode; +} SculptGestureContext; - if (redraw) { - BKE_pbvh_node_mark_update_mask(node); - } +static void sculpt_gesture_operator_properties(wmOperatorType *ot) +{ + RNA_def_boolean(ot->srna, + "use_front_faces_only", + false, + "Front Faces Only", + "Affect only faces facing towards the view"); } -static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op) +static void sculpt_gesture_context_init_common(bContext *C, + wmOperator *op, + SculptGestureContext *sgcontext) { - ViewContext vc; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - ED_view3d_viewcontext_init(C, &vc, depsgraph); - - Sculpt *sd = vc.scene->toolsettings->sculpt; - BoundBox bb; - float clip_planes[4][4]; - float clip_planes_final[4][4]; - ARegion *region = vc.region; - Object *ob = vc.obact; - bool multires; - PBVH *pbvh; - PBVHNode **nodes; - int totnode; - int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; - - const PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode"); - const float value = RNA_float_get(op->ptr, "value"); - const bool front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only"); + ED_view3d_viewcontext_init(C, &sgcontext->vc, depsgraph); - rcti rect; - WM_operator_properties_border_to_rcti(op, &rect); + Sculpt *sd = sgcontext->vc.scene->toolsettings->sculpt; + Object *ob = sgcontext->vc.obact; - /* Transform the clip planes in object space. */ - ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &rect); + /* Operator properties. */ + sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only"); - BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false); - pbvh = ob->sculpt->pbvh; - multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); + /* SculptSession */ + sgcontext->ss = ob->sculpt; - SCULPT_undo_push_begin("Mask box fill"); + /* Symmetry. */ + sgcontext->symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; - /* Calculate the view normal in object space. */ + /* View Normal. */ float mat[3][3]; float view_dir[3] = {0.0f, 0.0f, 1.0f}; - float true_view_normal[3]; - copy_m3_m4(mat, vc.rv3d->viewinv); + copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv); mul_m3_v3(mat, view_dir); copy_m3_m4(mat, ob->imat); mul_m3_v3(mat, view_dir); - normalize_v3_v3(true_view_normal, view_dir); + normalize_v3_v3(sgcontext->true_view_normal, view_dir); +} - for (int symmpass = 0; symmpass <= symm; symmpass++) { - if (symmpass == 0 || (symm & symmpass && (symm != 5 || symmpass != 3) && - (symm != 6 || (symmpass != 3 && symmpass != 5)))) { +static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) +{ + SculptGestureContext *mcontext = user_data; + LassoGestureData *lasso = &mcontext->lasso; + int index = (y * lasso->width) + x; + int index_end = (y * lasso->width) + x_end; + do { + BLI_BITMAP_ENABLE(lasso->mask_px, index); + } while (++index != index_end); +} - /* Flip the planes symmetrically as needed. */ - for (int j = 0; j < 4; j++) { - flip_plane(clip_planes_final[j], clip_planes[j], symmpass); - } +static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op) +{ + SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), + "sculpt gesture context lasso"); + sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LASSO; + + sculpt_gesture_context_init_common(C, op, sgcontext); - PBVHFrustumPlanes frustum = {.planes = clip_planes_final, .num_planes = 4}; - BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, &nodes, &totnode); + int mcoords_len; + const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len); - negate_m4(clip_planes_final); + if (!mcoords) { + return NULL; + } - MaskTaskData data = { - .ob = ob, - .pbvh = pbvh, - .nodes = nodes, - .multires = multires, - .mode = mode, - .value = value, - .clip_planes_final = clip_planes_final, - .front_faces_only = front_faces_only, - }; + ED_view3d_ob_project_mat_get( + sgcontext->vc.rv3d, sgcontext->vc.obact, sgcontext->lasso.projviewobjmat); + BLI_lasso_boundbox(&sgcontext->lasso.boundbox, mcoords, mcoords_len); + sgcontext->lasso.width = sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin; + sgcontext->lasso.mask_px = BLI_BITMAP_NEW( + sgcontext->lasso.width * (sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin), + __func__); + + BLI_bitmap_draw_2d_poly_v2i_n(sgcontext->lasso.boundbox.xmin, + sgcontext->lasso.boundbox.ymin, + sgcontext->lasso.boundbox.xmax, + sgcontext->lasso.boundbox.ymax, + mcoords, + mcoords_len, + sculpt_gesture_lasso_px_cb, + sgcontext); - flip_v3_v3(data.view_normal, true_view_normal, symmpass); + BoundBox bb; + ED_view3d_clipping_calc(&bb, + sgcontext->true_clip_planes, + sgcontext->vc.region, + sgcontext->vc.obact, + &sgcontext->lasso.boundbox); + MEM_freeN((void *)mcoords); + + return sgcontext; +} - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_box_select_task_cb, &settings); +static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperator *op) +{ + SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), + "sculpt gesture context box"); + sgcontext->shape_type = SCULPT_GESTURE_SHAPE_BOX; - if (nodes) { - MEM_freeN(nodes); - } - } - } + sculpt_gesture_context_init_common(C, op, sgcontext); - if (multires) { - multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); - } + rcti rect; + WM_operator_properties_border_to_rcti(op, &rect); - BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask); + BoundBox bb; + ED_view3d_clipping_calc( + &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect); - SCULPT_undo_push_end(); + return sgcontext; +} - ED_region_tag_redraw(region); +static void sculpt_gesture_context_free(SculptGestureContext *sgcontext) +{ + MEM_SAFE_FREE(sgcontext->lasso.mask_px); + MEM_SAFE_FREE(sgcontext->nodes); + MEM_SAFE_FREE(sgcontext); +} - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); +static void flip_plane(float out[4], const float in[4], const char symm) +{ + if (symm & PAINT_SYMM_X) { + out[0] = -in[0]; + } + else { + out[0] = in[0]; + } + if (symm & PAINT_SYMM_Y) { + out[1] = -in[1]; + } + else { + out[1] = in[1]; + } + if (symm & PAINT_SYMM_Z) { + out[2] = -in[2]; + } + else { + out[2] = in[2]; + } - return true; + out[3] = in[3]; } -typedef struct LassoMaskData { - struct ViewContext *vc; - float projviewobjmat[4][4]; - BLI_bitmap *px; - int width; - /* Bounding box for scanfilling. */ - rcti rect; - int symmpass; +static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontext, + const ePaintSymmetryFlags symmpass) +{ + sgcontext->symmpass = symmpass; + for (int j = 0; j < 4; j++) { + flip_plane(sgcontext->clip_planes[j], sgcontext->true_clip_planes[j], symmpass); + } + negate_m4(sgcontext->clip_planes); + flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass); +} - MaskTaskData task_data; -} LassoMaskData; +static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext) +{ + SculptSession *ss = sgcontext->ss; + float clip_planes[4][4]; + copy_m4_m4(clip_planes, sgcontext->clip_planes); + negate_m4(clip_planes); + PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4}; + BKE_pbvh_search_gather(ss->pbvh, + BKE_pbvh_node_frustum_contain_AABB, + &frustum, + &sgcontext->nodes, + &sgcontext->totnode); +} -/** - * Lasso select. This could be defined as part of #VIEW3D_OT_select_lasso, - * still the shortcuts conflict, so we will use a separate operator. - */ -static bool is_effected_lasso(LassoMaskData *data, const float co[3]) +static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3]) { float scr_co_f[2]; int scr_co_s[2]; float co_final[3]; - flip_v3_v3(co_final, co, data->symmpass); + flip_v3_v3(co_final, co, sgcontext->symmpass); + /* First project point to 2d space. */ - ED_view3d_project_float_v2_m4(data->vc->region, co_final, scr_co_f, data->projviewobjmat); + ED_view3d_project_float_v2_m4( + sgcontext->vc.region, co_final, scr_co_f, sgcontext->lasso.projviewobjmat); scr_co_s[0] = scr_co_f[0]; scr_co_s[1] = scr_co_f[1]; - /* Clip against screen, because lasso is limited to screen only. */ - if ((scr_co_s[0] < data->rect.xmin) || (scr_co_s[1] < data->rect.ymin) || - (scr_co_s[0] >= data->rect.xmax) || (scr_co_s[1] >= data->rect.ymax)) { + /* Clip against lasso boundbox. */ + LassoGestureData *lasso = &sgcontext->lasso; + if (!BLI_rcti_isect_pt(&lasso->boundbox, scr_co_s[0], scr_co_s[1])) { return false; } - scr_co_s[0] -= data->rect.xmin; - scr_co_s[1] -= data->rect.ymin; + scr_co_s[0] -= lasso->boundbox.xmin; + scr_co_s[1] -= lasso->boundbox.ymin; - return BLI_BITMAP_TEST_BOOL(data->px, scr_co_s[1] * data->width + scr_co_s[0]); + return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]); } -static void mask_lasso_px_cb(int x, int x_end, int y, void *user_data) +static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd) { - LassoMaskData *data = user_data; - int index = (y * data->width) + x; - int index_end = (y * data->width) + x_end; - do { - BLI_BITMAP_ENABLE(data->px, index); - } while (++index != index_end); + float vertex_normal[3]; + SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal); + float dot = dot_v3v3(sgcontext->view_normal, vertex_normal); + const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f); + + if (!is_effected_front_face) { + return false; + } + + switch (sgcontext->shape_type) { + case SCULPT_GESTURE_SHAPE_BOX: + return isect_point_planes_v3(sgcontext->clip_planes, 4, vd->co); + case SCULPT_GESTURE_SHAPE_LASSO: + return sculpt_gesture_is_effected_lasso(sgcontext, vd->co); + } + return false; } -static void mask_gesture_lasso_task_cb(void *__restrict userdata, +static void mask_gesture_apply_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) { - LassoMaskData *lasso_data = userdata; - MaskTaskData *data = &lasso_data->task_data; - - PBVHNode *node = data->nodes[i]; + SculptGestureContext *sgcontext = userdata; + Object *ob = sgcontext->vc.obact; + PBVHNode *node = sgcontext->nodes[i]; - const PaintMaskFloodMode mode = data->mode; - const float value = data->value; + const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS; - PBVHVertexIter vi; + PBVHVertexIter vd; bool any_masked = false; + bool redraw = false; - float vertex_normal[3]; - - BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) + BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { - SCULPT_vertex_normal_get(data->ob->sculpt, vi.index, vertex_normal); - float dot = dot_v3v3(lasso_data->task_data.view_normal, vertex_normal); - const bool is_effected_front_face = !(data->front_faces_only && dot < 0.0f); - - if (is_effected_front_face && is_effected_lasso(lasso_data, vi.co)) { + if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { + float prevmask = *vd.mask; if (!any_masked) { any_masked = true; - SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); - BKE_pbvh_node_mark_redraw(node); - if (data->multires) { + if (is_multires) { BKE_pbvh_node_mark_normals_update(node); } } - - mask_flood_fill_set_elem(vi.mask, mode, value); + mask_flood_fill_set_elem(vd.mask, sgcontext->mask_mode, sgcontext->mask_value); + if (prevmask != *vd.mask) { + redraw = true; + } } } BKE_pbvh_vertex_iter_end; + + if (redraw) { + BKE_pbvh_node_mark_update_mask(node); + } } -static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) +static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext) { - int mcoords_len; - const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + BKE_sculpt_update_object_for_edit(depsgraph, mcontext->vc.obact, false, true, false); - if (mcoords) { - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - float clip_planes[4][4], clip_planes_final[4][4]; - BoundBox bb; - Object *ob; - ViewContext vc; - LassoMaskData data; - Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; - PBVH *pbvh; - PBVHNode **nodes; - int totnode; - bool multires; - PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode"); - float value = RNA_float_get(op->ptr, "value"); - const bool front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only"); - - /* Calculations of individual vertices are done in 2D screen space to diminish the amount of - * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle - * of lasso. */ - ED_view3d_viewcontext_init(C, &vc, depsgraph); - - /* Lasso data calculations. */ - data.vc = &vc; - ob = vc.obact; - ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat); - - BLI_lasso_boundbox(&data.rect, mcoords, mcoords_len); - data.width = data.rect.xmax - data.rect.xmin; - data.px = BLI_BITMAP_NEW(data.width * (data.rect.ymax - data.rect.ymin), __func__); - - BLI_bitmap_draw_2d_poly_v2i_n(data.rect.xmin, - data.rect.ymin, - data.rect.xmax, - data.rect.ymax, - mcoords, - mcoords_len, - mask_lasso_px_cb, - &data); - - ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &data.rect); - - BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false); - pbvh = ob->sculpt->pbvh; - multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); - - SCULPT_undo_push_begin("Mask lasso fill"); - - /* Calculate the view normal in object space. */ - float mat[3][3]; - float view_dir[3] = {0.0f, 0.0f, 1.0f}; - float true_view_normal[3]; - copy_m3_m4(mat, vc.rv3d->viewinv); - mul_m3_v3(mat, view_dir); - copy_m3_m4(mat, ob->imat); - mul_m3_v3(mat, view_dir); - normalize_v3_v3(true_view_normal, view_dir); - - for (int symmpass = 0; symmpass <= symm; symmpass++) { - if ((symmpass == 0) || (symm & symmpass && (symm != 5 || symmpass != 3) && - (symm != 6 || (symmpass != 3 && symmpass != 5)))) { - - /* Flip the planes symmetrically as needed. */ - for (int j = 0; j < 4; j++) { - flip_plane(clip_planes_final[j], clip_planes[j], symmpass); - } + SCULPT_undo_push_begin("Sculpt Gesture Apply"); - flip_v3_v3(data.task_data.view_normal, true_view_normal, symmpass); + for (ePaintSymmetryFlags symmpass = 0; symmpass <= mcontext->symm; symmpass++) { + if (SCULPT_is_symmetry_iteration_valid(symmpass, mcontext->symm)) { + sculpt_gesture_flip_for_symmetry_pass(mcontext, symmpass); + sculpt_gesture_update_effected_nodes(mcontext); - data.symmpass = symmpass; - - /* Gather nodes inside lasso's enclosing rectangle - * (should greatly help with bigger meshes). */ - PBVHFrustumPlanes frustum = {.planes = clip_planes_final, .num_planes = 4}; - BKE_pbvh_search_gather( - pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, &nodes, &totnode); - - negate_m4(clip_planes_final); + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, mcontext->totnode); + BLI_task_parallel_range( + 0, mcontext->totnode, mcontext, mask_gesture_apply_task_cb, &settings); - data.task_data.ob = ob; - data.task_data.pbvh = pbvh; - data.task_data.nodes = nodes; - data.task_data.multires = multires; - data.task_data.mode = mode; - data.task_data.value = value; - data.task_data.front_faces_only = front_faces_only; + MEM_SAFE_FREE(mcontext->nodes); + } + } - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, mask_gesture_lasso_task_cb, &settings); + if (BKE_pbvh_type(mcontext->ss->pbvh) == PBVH_GRIDS) { + multires_mark_as_modified(depsgraph, mcontext->vc.obact, MULTIRES_COORDS_MODIFIED); + } - if (nodes) { - MEM_freeN(nodes); - } - } - } + BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateMask); - if (multires) { - multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED); - } + SCULPT_undo_push_end(); - BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask); + ED_region_tag_redraw(mcontext->vc.region); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, mcontext->vc.obact); +} - SCULPT_undo_push_end(); +static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op) +{ + sgcontext->mask_mode = RNA_enum_get(op->ptr, "mode"); + sgcontext->mask_value = RNA_float_get(op->ptr, "value"); +} - ED_region_tag_redraw(vc.region); - MEM_freeN((void *)mcoords); - MEM_freeN(data.px); +static void paint_mask_gesture_operator_properties(wmOperatorType *ot) +{ + RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); + RNA_def_float( + ot->srna, + "value", + 1.0f, + 0.0f, + 1.0f, + "Value", + "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", + 0.0f, + 1.0f); +} - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); +static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op) +{ + SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op); + if (!sgcontext) { + return OPERATOR_CANCELLED; + } + sculpt_gesture_init_mask_properties(sgcontext, op); + sculpt_gesture_apply(C, sgcontext); + sculpt_gesture_context_free(sgcontext); + return OPERATOR_FINISHED; +} - return OPERATOR_FINISHED; +static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) +{ + SculptGestureContext *sgcontext = sculpt_gesture_init_from_lasso(C, op); + if (!sgcontext) { + return OPERATOR_CANCELLED; } - return OPERATOR_PASS_THROUGH; + sculpt_gesture_init_mask_properties(sgcontext, op); + sculpt_gesture_apply(C, sgcontext); + sculpt_gesture_context_free(sgcontext); + return OPERATOR_FINISHED; } void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) @@ -625,23 +617,9 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) /* Properties. */ WM_operator_properties_gesture_lasso(ot); + sculpt_gesture_operator_properties(ot); - RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); - RNA_def_float( - ot->srna, - "value", - 1.0f, - 0.0f, - 1.0f, - "Value", - "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", - 0.0f, - 1.0f); - RNA_def_boolean(ot->srna, - "use_front_faces_only", - false, - "Front Faces Only", - "Affect only faces facing towards the view"); + paint_mask_gesture_operator_properties(ot); } void PAINT_OT_mask_box_gesture(wmOperatorType *ot) @@ -660,21 +638,7 @@ void PAINT_OT_mask_box_gesture(wmOperatorType *ot) /* Properties. */ WM_operator_properties_border(ot); + sculpt_gesture_operator_properties(ot); - RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); - RNA_def_float( - ot->srna, - "value", - 1.0f, - 0.0f, - 1.0f, - "Value", - "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked", - 0.0f, - 1.0f); - RNA_def_boolean(ot->srna, - "use_front_faces_only", - false, - "Front Faces Only", - "Affect only faces facing towards the view"); + paint_mask_gesture_operator_properties(ot); } diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 90b0f017bd6..e709224f370 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -143,7 +143,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata if (stroke && brush) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); ARegion *region = stroke->vc.region; @@ -161,7 +161,7 @@ static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_line_smooth(false); } } @@ -691,6 +691,14 @@ static float paint_space_stroke_spacing(bContext *C, spacing = spacing * (1.5f - spacing_pressure); } + if (SCULPT_is_cloth_deform_brush(brush)) { + /* The spacing in tools that use the cloth solver should not be affected by the brush radius to + * avoid affecting the simulation update rate when changing the radius of the brush. + With a value of 100 and the brush default of 10 for spacing, a simulation step runs every 2 + pixels movement of the cursor. */ + size_clamp = 100.0f; + } + /* stroke system is used for 2d paint too, so we need to account for * the fact that brush can be scaled there. */ spacing *= stroke->zoom_2d; @@ -997,7 +1005,19 @@ static void stroke_done(bContext *C, wmOperator *op) /* Returns zero if the stroke dots should not be spaced, non-zero otherwise */ bool paint_space_stroke_enabled(Brush *br, ePaintMode mode) { - return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode); + if ((br->flag & BRUSH_SPACE) == 0) { + return false; + } + + if (br->sculpt_tool == SCULPT_TOOL_CLOTH || SCULPT_is_cloth_deform_brush(br)) { + /* The Cloth Brush is a special case for stroke spacing. Even if it has grab modes which do + * not support dynamic size, stroke spacing needs to be enabled so it is possible to control + * whether the simulation runs constantly or only when the brush moves when using the cloth + * grab brushes. */ + return true; + } + + return paint_supports_dynamic_size(br, mode); } static bool sculpt_is_grab_tool(Brush *br) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d68b1226b40..7a066f35f23 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -275,6 +275,19 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]) SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal); } +float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, + const int deform_target, + PBVHVertexIter *iter) +{ + switch (deform_target) { + case BRUSH_DEFORM_TARGET_GEOMETRY: + return iter->co; + case BRUSH_DEFORM_TARGET_CLOTH_SIM: + return ss->cache->cloth_sim->deformation_pos[iter->index]; + } + return iter->co; +} + /* Sculpt Face Sets and Visibility. */ int SCULPT_active_face_set_get(SculptSession *ss) @@ -2260,7 +2273,7 @@ static float brush_strength(const Sculpt *sd, case SCULPT_TOOL_DISPLACEMENT_ERASER: return alpha * pressure * overlap * feather; case SCULPT_TOOL_CLOTH: - if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { + if (ELEM(brush->cloth_deform_type, BRUSH_CLOTH_DEFORM_GRAB, BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) { /* Grab deform uses the same falloff as a regular grab brush. */ return root_alpha * feather; } @@ -2331,7 +2344,7 @@ static float brush_strength(const Sculpt *sd, } case SCULPT_TOOL_SMOOTH: - return alpha * pressure * feather; + return flip * alpha * pressure * feather; case SCULPT_TOOL_PINCH: if (flip > 0.0f) { @@ -5690,6 +5703,16 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe SCULPT_pose_brush_init(sd, ob, ss, brush); } + if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { + if (!ss->cache->cloth_sim) { + ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create(ss, brush, 1.0f, 0.0f, false); + SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim); + SCULPT_cloth_brush_build_nodes_constraints( + sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, FLT_MAX); + } + SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); + } + bool invert = ss->cache->pen_flip || ss->cache->invert || brush->flag & BRUSH_DIR_IN; /* Apply one type of brush action. */ @@ -5828,6 +5851,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); } + if (brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { + if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) { + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + } + } + MEM_SAFE_FREE(nodes); /* Update average stroke position. */ @@ -6365,14 +6394,15 @@ void SCULPT_cache_free(StrokeCache *cache) MEM_SAFE_FREE(cache->surface_smooth_laplacian_disp); MEM_SAFE_FREE(cache->layer_displacement_factor); MEM_SAFE_FREE(cache->prev_colors); + MEM_SAFE_FREE(cache->detail_directions); if (cache->pose_ik_chain) { SCULPT_pose_ik_chain_free(cache->pose_ik_chain); } for (int i = 0; i < PAINT_SYMM_AREAS; i++) { - if (cache->bdata[i]) { - SCULPT_boundary_data_free(cache->bdata[i]); + if (cache->boundaries[i]) { + SCULPT_boundary_data_free(cache->boundaries[i]); } } @@ -6604,13 +6634,19 @@ static float sculpt_brush_dynamic_size_get(Brush *brush, StrokeCache *cache, flo * generally used to create grab deformations. */ static bool sculpt_needs_delta_from_anchored_origin(Brush *brush) { - return ELEM(brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_POSE, - SCULPT_TOOL_BOUNDARY, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_ELASTIC_DEFORM) || - SCULPT_is_cloth_deform_brush(brush); + if (ELEM(brush->sculpt_tool, + SCULPT_TOOL_GRAB, + SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, + SCULPT_TOOL_THUMB, + SCULPT_TOOL_ELASTIC_DEFORM)) { + return true; + } + if (brush->sculpt_tool == SCULPT_TOOL_CLOTH && + brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { + return true; + } + return false; } /* In these brushes the grab delta is calculated from the previous stroke location, which is used @@ -6618,7 +6654,7 @@ static bool sculpt_needs_delta_from_anchored_origin(Brush *brush) static bool sculpt_needs_delta_for_tip_orientation(Brush *brush) { if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - return !SCULPT_is_cloth_deform_brush(brush); + return brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK; } return ELEM(brush->sculpt_tool, SCULPT_TOOL_CLAY_STRIPS, @@ -6664,7 +6700,9 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru copy_v3_v3(cache->orig_grab_location, cache->true_location); } } - else if (tool == SCULPT_TOOL_SNAKE_HOOK) { + else if (tool == SCULPT_TOOL_SNAKE_HOOK || + (tool == SCULPT_TOOL_CLOTH && + brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) { add_v3_v3(cache->true_location, cache->grab_delta); } @@ -7125,6 +7163,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, /* Update the active vertex of the SculptSession. */ ss->active_vertex_index = srd.active_vertex_index; + SCULPT_vertex_random_access_ensure(ss); copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss)); switch (BKE_pbvh_type(ss->pbvh)) { @@ -7306,7 +7345,8 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op) need_mask = true; } - if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { + if (brush->sculpt_tool == SCULPT_TOOL_CLOTH || + brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM) { need_mask = true; } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index c86e922a347..5e01e034715 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -130,34 +130,39 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, * deformations usually need in the boundary. */ static int BOUNDARY_INDICES_BLOCK_SIZE = 300; -static void sculpt_boundary_index_add(SculptBoundary *bdata, +static void sculpt_boundary_index_add(SculptBoundary *boundary, const int new_index, + const float distance, GSet *included_vertices) { - bdata->vertices[bdata->num_vertices] = new_index; + boundary->vertices[boundary->num_vertices] = new_index; + if (boundary->distance) { + boundary->distance[new_index] = distance; + } if (included_vertices) { BLI_gset_add(included_vertices, POINTER_FROM_INT(new_index)); } - bdata->num_vertices++; - if (bdata->num_vertices >= bdata->vertices_capacity) { - bdata->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - bdata->vertices = MEM_reallocN_id( - bdata->vertices, bdata->vertices_capacity * sizeof(int), "boundary indices"); + boundary->num_vertices++; + if (boundary->num_vertices >= boundary->vertices_capacity) { + boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE; + boundary->vertices = MEM_reallocN_id( + boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices"); } }; -static void sculpt_boundary_preview_edge_add(SculptBoundary *bdata, const int v1, const int v2) +static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2) { - bdata->edges[bdata->num_edges].v1 = v1; - bdata->edges[bdata->num_edges].v2 = v2; - bdata->num_edges++; + boundary->edges[boundary->num_edges].v1 = v1; + boundary->edges[boundary->num_edges].v2 = v2; + boundary->num_edges++; - if (bdata->num_edges >= bdata->edges_capacity) { - bdata->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; - bdata->edges = MEM_reallocN_id( - bdata->edges, bdata->edges_capacity * sizeof(SculptBoundaryPreviewEdge), "boundary edges"); + if (boundary->num_edges >= boundary->edges_capacity) { + boundary->edges_capacity += BOUNDARY_INDICES_BLOCK_SIZE; + boundary->edges = MEM_reallocN_id(boundary->edges, + boundary->edges_capacity * sizeof(SculptBoundaryPreviewEdge), + "boundary edges"); } }; @@ -199,7 +204,7 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, */ typedef struct BoundaryFloodFillData { - SculptBoundary *bdata; + SculptBoundary *boundary; GSet *included_vertices; EdgeSet *preview_edges; @@ -211,11 +216,16 @@ static bool boundary_floodfill_cb( SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) { BoundaryFloodFillData *data = userdata; - SculptBoundary *bdata = data->bdata; + SculptBoundary *boundary = data->boundary; if (SCULPT_vertex_is_boundary(ss, to_v)) { - sculpt_boundary_index_add(bdata, to_v, data->included_vertices); + const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v), + SCULPT_vertex_co_get(ss, to_v)); + const float distance_boundary_to_dst = boundary->distance ? + boundary->distance[from_v] + edge_len : + 0.0f; + sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices); if (!is_duplicate) { - sculpt_boundary_preview_edge_add(bdata, from_v, to_v); + sculpt_boundary_preview_edge_add(boundary, from_v, to_v); } return sculpt_boundary_is_vertex_in_editable_boundary(ss, to_v); } @@ -223,26 +233,32 @@ static bool boundary_floodfill_cb( } static void sculpt_boundary_indices_init(SculptSession *ss, - SculptBoundary *bdata, + SculptBoundary *boundary, + const bool init_boundary_distances, const int initial_boundary_index) { - bdata->vertices = MEM_malloc_arrayN( + const int totvert = SCULPT_vertex_count_get(ss); + boundary->vertices = MEM_malloc_arrayN( BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices"); - bdata->edges = MEM_malloc_arrayN( + if (init_boundary_distances) { + boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances"); + } + boundary->edges = MEM_malloc_arrayN( BOUNDARY_INDICES_BLOCK_SIZE, sizeof(SculptBoundaryPreviewEdge), "boundary edges"); GSet *included_vertices = BLI_gset_int_new_ex("included vertices", BOUNDARY_INDICES_BLOCK_SIZE); SculptFloodFill flood; SCULPT_floodfill_init(ss, &flood); - bdata->initial_vertex = initial_boundary_index; - copy_v3_v3(bdata->initial_vertex_position, SCULPT_vertex_co_get(ss, bdata->initial_vertex)); - sculpt_boundary_index_add(bdata, initial_boundary_index, included_vertices); + boundary->initial_vertex = initial_boundary_index; + copy_v3_v3(boundary->initial_vertex_position, + SCULPT_vertex_co_get(ss, boundary->initial_vertex)); + sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices); SCULPT_floodfill_add_initial(&flood, initial_boundary_index); BoundaryFloodFillData fdata = { - .bdata = bdata, + .boundary = boundary, .included_vertices = included_vertices, .last_visited_vertex = BOUNDARY_VERTEX_NONE, @@ -258,8 +274,8 @@ static void sculpt_boundary_indices_init(SculptSession *ss, SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) { if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) && sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) { - sculpt_boundary_preview_edge_add(bdata, fdata.last_visited_vertex, ni.index); - bdata->forms_loop = true; + sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index); + boundary->forms_loop = true; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -275,7 +291,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss, * the closest one. */ static void sculpt_boundary_edit_data_init(SculptSession *ss, - SculptBoundary *bdata, + SculptBoundary *boundary, const int initial_vertex, const float radius) { @@ -283,12 +299,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, const bool has_duplicates = BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS; - bdata->edit_info = MEM_malloc_arrayN( + boundary->edit_info = MEM_malloc_arrayN( totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info"); for (int i = 0; i < totvert; i++) { - bdata->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE; - bdata->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE; + boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE; + boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE; } GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int)); @@ -297,23 +313,23 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Initialized the first iteration with the vertices already in the boundary. This is propagation * step 0. */ BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices"); - for (int i = 0; i < bdata->num_vertices; i++) { - bdata->edit_info[bdata->vertices[i]].original_vertex = bdata->vertices[i]; - bdata->edit_info[bdata->vertices[i]].num_propagation_steps = 0; + for (int i = 0; i < boundary->num_vertices; i++) { + boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i]; + boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0; /* This ensures that all duplicate vertices in the boundary have the same original_vertex * index, so the deformation for them will be the same. */ if (has_duplicates) { SculptVertexNeighborIter ni_duplis; - SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, bdata->vertices[i], ni_duplis) { + SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) { if (ni_duplis.is_duplicate) { - bdata->edit_info[ni_duplis.index].original_vertex = bdata->vertices[i]; + boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i]; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); } - BLI_gsqueue_push(current_iteration, &bdata->vertices[i]); + BLI_gsqueue_push(current_iteration, &boundary->vertices[i]); } int num_propagation_steps = 0; @@ -323,7 +339,7 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* This steps is further away from the boundary than the brush radius, so stop adding more * steps. */ if (accum_distance > radius) { - bdata->max_propagation_steps = num_propagation_steps; + boundary->max_propagation_steps = num_propagation_steps; break; } @@ -333,19 +349,20 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { - if (bdata->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) { - bdata->edit_info[ni.index].original_vertex = bdata->edit_info[from_v].original_vertex; + if (boundary->edit_info[ni.index].num_propagation_steps == BOUNDARY_STEPS_NONE) { + boundary->edit_info[ni.index].original_vertex = + boundary->edit_info[from_v].original_vertex; BLI_BITMAP_ENABLE(visited_vertices, ni.index); if (ni.is_duplicate) { /* Grids duplicates handling. */ - bdata->edit_info[ni.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps; + boundary->edit_info[ni.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps; } else { - bdata->edit_info[ni.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[ni.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps + 1; BLI_gsqueue_push(next_iteration, &ni.index); @@ -357,10 +374,10 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni_duplis; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) { if (ni_duplis.is_duplicate) { - bdata->edit_info[ni_duplis.index].original_vertex = - bdata->edit_info[from_v].original_vertex; - bdata->edit_info[ni_duplis.index].num_propagation_steps = - bdata->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[ni_duplis.index].original_vertex = + boundary->edit_info[from_v].original_vertex; + boundary->edit_info[ni_duplis.index].num_propagation_steps = + boundary->edit_info[from_v].num_propagation_steps + 1; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); @@ -368,9 +385,9 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Check the distance using the vertex that was propagated from the initial vertex that * was used to initialize the boundary. */ - if (bdata->edit_info[from_v].original_vertex == initial_vertex) { - bdata->pivot_vertex = ni.index; - copy_v3_v3(bdata->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index)); + if (boundary->edit_info[from_v].original_vertex == initial_vertex) { + boundary->pivot_vertex = ni.index; + copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index)); accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v), SCULPT_vertex_co_get(ss, ni.index)); } @@ -406,23 +423,67 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, * on the brush curve and its propagation steps. The falloff goes from the boundary into the mesh. */ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, - SculptBoundary *bdata, - Brush *brush) + SculptBoundary *boundary, + Brush *brush, + const float radius) { const int totvert = SCULPT_vertex_count_get(ss); BKE_curvemapping_init(brush->curve); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != -1) { - bdata->edit_info[i].strength_factor = BKE_brush_curve_strength( - brush, bdata->edit_info[i].num_propagation_steps, bdata->max_propagation_steps); + if (boundary->edit_info[i].num_propagation_steps != -1) { + boundary->edit_info[i].strength_factor = BKE_brush_curve_strength( + brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps); + } + + if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) { + /* All vertices that are propagated from the original vertex won't be affected by the + * boundary falloff, so there is no need to calculate anything else. */ + continue; + } + + if (!boundary->distance) { + /* There are falloff modes that do not require to modify the previously calculated falloff + * based on boundary distances. */ + continue; + } + + const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex]; + float falloff_distance = 0.0f; + float direction = 1.0f; + + switch (brush->boundary_falloff_type) { + case BRUSH_BOUNDARY_FALLOFF_RADIUS: + falloff_distance = boundary_distance; + break; + case BRUSH_BOUNDARY_FALLOFF_LOOP: { + const int div = boundary_distance / radius; + const float mod = fmodf(boundary_distance, radius); + falloff_distance = div % 2 == 0 ? mod : radius - mod; + } break; + case BRUSH_BOUNDARY_FALLOFF_LOOP_INVERT: { + const int div = boundary_distance / radius; + const float mod = fmodf(boundary_distance, radius); + falloff_distance = div % 2 == 0 ? mod : radius - mod; + /* Inverts the faloff in the intervals 1 2 5 6 9 10 ... */ + if (((div - 1) & 2) == 0) { + direction = -1.0f; + } + } break; + case BRUSH_BOUNDARY_FALLOFF_CONSTANT: + /* For constant falloff distances are not allocated, so this should never happen. */ + BLI_assert(false); } + + boundary->edit_info[i].strength_factor *= direction * BKE_brush_curve_strength( + brush, falloff_distance, radius); } } /* Main function to get SculptBoundary data both for brush deformation and viewport preview. Can * return NULL if there is no boundary from the given vertex using the given radius. */ SculptBoundary *SCULPT_boundary_data_init(Object *object, + Brush *brush, const int initial_vertex, const float radius) { @@ -444,111 +505,118 @@ SculptBoundary *SCULPT_boundary_data_init(Object *object, return NULL; } - SculptBoundary *bdata = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data"); + SculptBoundary *boundary = MEM_callocN(sizeof(SculptBoundary), "Boundary edit data"); + + const bool init_boundary_distances = brush->boundary_falloff_type != + BRUSH_BOUNDARY_FALLOFF_CONSTANT; + sculpt_boundary_indices_init(ss, boundary, init_boundary_distances, boundary_initial_vertex); - sculpt_boundary_indices_init(ss, bdata, boundary_initial_vertex); - sculpt_boundary_edit_data_init(ss, bdata, boundary_initial_vertex, radius); + const float boundary_radius = radius * (1.0f + brush->boundary_offset); + sculpt_boundary_edit_data_init(ss, boundary, boundary_initial_vertex, boundary_radius); - return bdata; + return boundary; } -void SCULPT_boundary_data_free(SculptBoundary *bdata) +void SCULPT_boundary_data_free(SculptBoundary *boundary) { - MEM_SAFE_FREE(bdata->vertices); - MEM_SAFE_FREE(bdata->edit_info); - MEM_SAFE_FREE(bdata->bend.pivot_positions); - MEM_SAFE_FREE(bdata->bend.pivot_rotation_axis); - MEM_SAFE_FREE(bdata->slide.directions); - MEM_SAFE_FREE(bdata); + MEM_SAFE_FREE(boundary->vertices); + MEM_SAFE_FREE(boundary->distance); + MEM_SAFE_FREE(boundary->edit_info); + MEM_SAFE_FREE(boundary->bend.pivot_positions); + MEM_SAFE_FREE(boundary->bend.pivot_rotation_axis); + MEM_SAFE_FREE(boundary->slide.directions); + MEM_SAFE_FREE(boundary); } /* These functions initialize the required vectors for the desired deformation using the * SculptBoundaryEditInfo. They calculate the data using the vertices that have the * max_propagation_steps value and them this data is copied to the rest of the vertices using the * original vertex index. */ -static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - bdata->bend.pivot_rotation_axis = MEM_calloc_arrayN( + boundary->bend.pivot_rotation_axis = MEM_calloc_arrayN( totvert, 3 * sizeof(float), "pivot rotation axis"); - bdata->bend.pivot_positions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "pivot positions"); + boundary->bend.pivot_positions = MEM_calloc_arrayN( + totvert, 3 * sizeof(float), "pivot positions"); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) { + if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) { float dir[3]; float normal[3]; SCULPT_vertex_normal_get(ss, i, normal); sub_v3_v3v3(dir, - SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex), + SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), SCULPT_vertex_co_get(ss, i)); cross_v3_v3v3( - bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex], dir, normal); - normalize_v3(bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]); - copy_v3_v3(bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex], + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal); + normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); + copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex], SCULPT_vertex_co_get(ss, i)); } } for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { - copy_v3_v3(bdata->bend.pivot_positions[i], - bdata->bend.pivot_positions[bdata->edit_info[i].original_vertex]); - copy_v3_v3(bdata->bend.pivot_rotation_axis[i], - bdata->bend.pivot_rotation_axis[bdata->edit_info[i].original_vertex]); + if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { + copy_v3_v3(boundary->bend.pivot_positions[i], + boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]); + copy_v3_v3(boundary->bend.pivot_rotation_axis[i], + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); } } } -static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *boundary) { const int totvert = SCULPT_vertex_count_get(ss); - bdata->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions"); + boundary->slide.directions = MEM_calloc_arrayN(totvert, 3 * sizeof(float), "slide directions"); for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps == bdata->max_propagation_steps) { - sub_v3_v3v3(bdata->slide.directions[bdata->edit_info[i].original_vertex], - SCULPT_vertex_co_get(ss, bdata->edit_info[i].original_vertex), + if (boundary->edit_info[i].num_propagation_steps == boundary->max_propagation_steps) { + sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex], + SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), SCULPT_vertex_co_get(ss, i)); - normalize_v3(bdata->slide.directions[bdata->edit_info[i].original_vertex]); + normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]); } } for (int i = 0; i < totvert; i++) { - if (bdata->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { - copy_v3_v3(bdata->slide.directions[i], - bdata->slide.directions[bdata->edit_info[i].original_vertex]); + if (boundary->edit_info[i].num_propagation_steps != BOUNDARY_STEPS_NONE) { + copy_v3_v3(boundary->slide.directions[i], + boundary->slide.directions[boundary->edit_info[i].original_vertex]); } } } -static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *bdata) +static void sculpt_boundary_twist_data_init(SculptSession *ss, SculptBoundary *boundary) { - zero_v3(bdata->twist.pivot_position); - float(*poly_verts)[3] = MEM_malloc_arrayN(bdata->num_vertices, sizeof(float) * 3, "poly verts"); - for (int i = 0; i < bdata->num_vertices; i++) { - add_v3_v3(bdata->twist.pivot_position, SCULPT_vertex_co_get(ss, bdata->vertices[i])); - copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, bdata->vertices[i])); + zero_v3(boundary->twist.pivot_position); + float(*poly_verts)[3] = MEM_malloc_arrayN( + boundary->num_vertices, sizeof(float) * 3, "poly verts"); + for (int i = 0; i < boundary->num_vertices; i++) { + add_v3_v3(boundary->twist.pivot_position, SCULPT_vertex_co_get(ss, boundary->vertices[i])); + copy_v3_v3(poly_verts[i], SCULPT_vertex_co_get(ss, boundary->vertices[i])); } - mul_v3_fl(bdata->twist.pivot_position, 1.0f / bdata->num_vertices); - if (bdata->forms_loop) { - normal_poly_v3(bdata->twist.rotation_axis, poly_verts, bdata->num_vertices); + mul_v3_fl(boundary->twist.pivot_position, 1.0f / boundary->num_vertices); + if (boundary->forms_loop) { + normal_poly_v3(boundary->twist.rotation_axis, poly_verts, boundary->num_vertices); } else { - sub_v3_v3v3(bdata->twist.rotation_axis, - SCULPT_vertex_co_get(ss, bdata->pivot_vertex), - SCULPT_vertex_co_get(ss, bdata->initial_vertex)); - normalize_v3(bdata->twist.rotation_axis); + sub_v3_v3v3(boundary->twist.rotation_axis, + SCULPT_vertex_co_get(ss, boundary->pivot_vertex), + SCULPT_vertex_co_get(ss, boundary->initial_vertex)); + normalize_v3(boundary->twist.rotation_axis); } MEM_freeN(poly_verts); } static float sculpt_boundary_displacement_from_grab_delta_get(SculptSession *ss, - SculptBoundary *bdata) + SculptBoundary *boundary) { float plane[4]; float pos[3]; float normal[3]; - sub_v3_v3v3(normal, ss->cache->initial_location, bdata->initial_pivot_position); + sub_v3_v3v3(normal, ss->cache->initial_location, boundary->initial_pivot_position); normalize_v3(normal); plane_from_point_normal_v3(plane, ss->cache->initial_location, normal); add_v3_v3v3(pos, ss->cache->initial_location, ss->cache->grab_delta_symmetry); @@ -563,7 +631,9 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; + const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -571,7 +641,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); float angle_factor = disp / ss->cache->radius; /* Angle Snapping when inverting the brush. */ if (ss->cache->invert) { @@ -582,16 +652,20 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - float t_orig_co[3]; - sub_v3_v3v3(t_orig_co, orig_data.co, bdata->bend.pivot_positions[vd.index]); - rotate_v3_v3v3fl(vd.co, - t_orig_co, - bdata->bend.pivot_rotation_axis[vd.index], - angle * bdata->edit_info[vd.index].strength_factor * mask); - add_v3_v3(vd.co, bdata->bend.pivot_positions[vd.index]); + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { + const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + float t_orig_co[3]; + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]); + rotate_v3_v3v3fl(target_co, + t_orig_co, + boundary->bend.pivot_rotation_axis[vd.index], + angle * boundary->edit_info[vd.index].strength_factor * mask); + add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]); + } } if (vd.mvert) { @@ -608,7 +682,9 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; + const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -616,18 +692,22 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - madd_v3_v3v3fl(vd.co, - orig_data.co, - bdata->slide.directions[vd.index], - bdata->edit_info[vd.index].strength_factor * disp * mask * strength); + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { + const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, + orig_data.co, + boundary->slide.directions[vd.index], + boundary->edit_info[vd.index].strength_factor * disp * mask * strength); + } } if (vd.mvert) { @@ -644,7 +724,9 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; + const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -652,20 +734,24 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - float normal[3]; - normal_short_to_float_v3(normal, orig_data.no); - madd_v3_v3v3fl(vd.co, - orig_data.co, - normal, - bdata->edit_info[vd.index].strength_factor * disp * mask * strength); + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { + const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + float normal[3]; + normal_short_to_float_v3(normal, orig_data.no); + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, + orig_data.co, + normal, + boundary->edit_info[vd.index].strength_factor * disp * mask * strength); + } } if (vd.mvert) { @@ -682,7 +768,9 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; + const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -693,13 +781,17 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - madd_v3_v3v3fl(vd.co, - orig_data.co, - ss->cache->grab_delta_symmetry, - bdata->edit_info[vd.index].strength_factor * mask * strength); + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { + const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + madd_v3_v3v3fl(target_co, + orig_data.co, + ss->cache->grab_delta_symmetry, + boundary->edit_info[vd.index].strength_factor * mask * strength); + } } if (vd.mvert) { @@ -716,7 +808,9 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, SculptThreadedTaskData *data = userdata; SculptSession *ss = data->ob->sculpt; const int symm_area = ss->cache->mirror_symmetry_pass; - SculptBoundary *bdata = ss->cache->bdata[symm_area]; + SculptBoundary *boundary = ss->cache->boundaries[symm_area]; + const ePaintSymmetryFlags symm = data->sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; + const Brush *brush = data->brush; const float strength = ss->cache->bstrength; @@ -724,7 +818,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, bdata); + const float disp = strength * sculpt_boundary_displacement_from_grab_delta_get(ss, boundary); float angle_factor = disp / ss->cache->radius; /* Angle Snapping when inverting the brush. */ if (ss->cache->invert) { @@ -735,16 +829,20 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - if (bdata->edit_info[vd.index].num_propagation_steps != -1) { - const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + if (boundary->edit_info[vd.index].num_propagation_steps != -1) { SCULPT_orig_vert_data_update(&orig_data, &vd); - float t_orig_co[3]; - sub_v3_v3v3(t_orig_co, orig_data.co, bdata->twist.pivot_position); - rotate_v3_v3v3fl(vd.co, - t_orig_co, - bdata->twist.rotation_axis, - angle * mask * bdata->edit_info[vd.index].strength_factor); - add_v3_v3(vd.co, bdata->twist.pivot_position); + if (SCULPT_check_vertex_pivot_symmetry( + orig_data.co, boundary->initial_vertex_position, symm)) { + const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; + float t_orig_co[3]; + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position); + rotate_v3_v3v3fl(target_co, + t_orig_co, + boundary->twist.rotation_axis, + angle * mask * boundary->edit_info[vd.index].strength_factor); + add_v3_v3(target_co, boundary->twist.pivot_position); + } } if (vd.mvert) { @@ -774,20 +872,20 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn sd, ob, location, ss->cache->radius_squared, false); } - ss->cache->bdata[symm_area] = SCULPT_boundary_data_init( - ob, initial_vertex, ss->cache->initial_radius); + ss->cache->boundaries[symm_area] = SCULPT_boundary_data_init( + ob, brush, initial_vertex, ss->cache->initial_radius); - if (ss->cache->bdata[symm_area]) { + if (ss->cache->boundaries[symm_area]) { switch (brush->boundary_deform_type) { case BRUSH_BOUNDARY_DEFORM_BEND: - sculpt_boundary_bend_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_bend_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_EXPAND: - sculpt_boundary_slide_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_slide_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_TWIST: - sculpt_boundary_twist_data_init(ss, ss->cache->bdata[symm_area]); + sculpt_boundary_twist_data_init(ss, ss->cache->boundaries[symm_area]); break; case BRUSH_BOUNDARY_DEFORM_INFLATE: case BRUSH_BOUNDARY_DEFORM_GRAB: @@ -795,12 +893,13 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn break; } - sculpt_boundary_falloff_factor_init(ss, ss->cache->bdata[symm_area], brush); + sculpt_boundary_falloff_factor_init( + ss, ss->cache->boundaries[symm_area], brush, ss->cache->initial_radius); } } /* No active boundary under the cursor. */ - if (!ss->cache->bdata[symm_area]) { + if (!ss->cache->boundaries[symm_area]) { return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 2637cb45906..c3666c8aaad 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -134,6 +134,7 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush, #define CLOTH_SIMULATION_ITERATIONS 5 #define CLOTH_MAX_CONSTRAINTS_PER_VERTEX 1024 #define CLOTH_SIMULATION_TIME_STEP 0.01f +#define CLOTH_DEFORMATION_TARGET_STRENGTH 0.35f static bool cloth_brush_sim_has_length_constraint(SculptClothSimulation *cloth_sim, const int v1, @@ -168,6 +169,8 @@ static void cloth_brush_add_length_constraint(SculptSession *ss, length_constraint->elem_position_a = cloth_sim->pos[v1]; length_constraint->elem_position_b = cloth_sim->pos[v2]; + length_constraint->type = SCULPT_CLOTH_CONSTRAINT_STRUCTURAL; + if (use_persistent) { length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1), SCULPT_vertex_persistent_co_get(ss, v2)); @@ -200,6 +203,8 @@ static void cloth_brush_add_softbody_constraint(SculptClothSimulation *cloth_sim length_constraint->elem_position_a = cloth_sim->pos[v]; length_constraint->elem_position_b = cloth_sim->init_pos[v]; + length_constraint->type = SCULPT_CLOTH_CONSTRAINT_SOFTBODY; + length_constraint->length = 0.0f; length_constraint->strength = strength; @@ -219,6 +224,8 @@ static void cloth_brush_add_deformation_constraint(SculptClothSimulation *cloth_ length_constraint->elem_index_a = v; length_constraint->elem_index_b = v; + length_constraint->type = SCULPT_CLOTH_CONSTRAINT_DEFORMATION; + length_constraint->elem_position_a = cloth_sim->pos[v]; length_constraint->elem_position_b = cloth_sim->deformation_pos[v]; @@ -297,15 +304,34 @@ static void do_cloth_brush_build_constraints_task_cb_ex( } } - if (cloth_is_deform_brush && len_squared < radius_squared) { - const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius); - cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade); + if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) { + /* The cloth brush works by applying forces in most of its modes, but some of them require + * deformation coordinates to make the simulation stable. */ + if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB && len_squared < radius_squared) { + /* When the grab brush brush is used as part of the cloth brush, deformation constraints + * are created with different strengths and only inside the radius of the brush. */ + const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius); + cloth_brush_add_deformation_constraint(data->cloth_sim, vd.index, fade); + } + else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) { + /* Cloth Snake Hook creates deformation constraint with fixed strength because the strength + * is controlled per iteration using cloth_sim->deformation_strength. */ + cloth_brush_add_deformation_constraint( + data->cloth_sim, vd.index, CLOTH_DEFORMATION_TARGET_STRENGTH); + } + } + else if (data->cloth_sim->deformation_pos) { + /* Any other tool that target the cloth simulation handle the falloff in + * their own code when modifying the deformation coordinates of the simulation, so + * deformation constraints are created with a fixed strength for all vertices. */ + cloth_brush_add_deformation_constraint( + data->cloth_sim, vd.index, CLOTH_DEFORMATION_TARGET_STRENGTH); } if (pin_simulation_boundary) { const float sim_falloff = cloth_brush_simulation_falloff_get( brush, ss->cache->initial_radius, ss->cache->location, vd.co); - /* Vertex is inside the area of the simulation without any falloff aplied. */ + /* Vertex is inside the area of the simulation without any falloff applied. */ if (sim_falloff < 1.0f) { /* Create constraints with more strength the closer the vertex is to the simulation * boundary. */ @@ -383,7 +409,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, brush, ss->cache->radius, ss->cache->initial_location, cloth_sim->init_pos[vd.index]); float current_vertex_location[3]; - if (SCULPT_is_cloth_deform_brush(brush)) { + if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { SCULPT_orig_vert_data_update(&orig_data, &vd); copy_v3_v3(current_vertex_location, orig_data.co); } @@ -442,6 +468,12 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, fade); zero_v3(force); break; + case BRUSH_CLOTH_DEFORM_SNAKE_HOOK: + copy_v3_v3(cloth_sim->deformation_pos[vd.index], cloth_sim->pos[vd.index]); + madd_v3_v3fl(cloth_sim->deformation_pos[vd.index], ss->cache->grab_delta_symmetry, fade); + cloth_sim->deformation_strength[vd.index] = fade; + zero_v3(force); + break; case BRUSH_CLOTH_DEFORM_PINCH_POINT: if (use_falloff_plane) { float distance = dist_signed_to_plane_v3(vd.co, deform_plane); @@ -505,49 +537,6 @@ static ListBase *cloth_brush_collider_cache_create(Depsgraph *depsgraph) return cache; } -static SculptClothSimulation *cloth_brush_simulation_create(SculptSession *ss, - Brush *brush, - const float cloth_mass, - const float cloth_damping, - const bool use_collisions) -{ - const int totverts = SCULPT_vertex_count_get(ss); - SculptClothSimulation *cloth_sim; - - cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints"); - - cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) * - CLOTH_LENGTH_CONSTRAINTS_BLOCK, - "cloth length constraints"); - cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; - - cloth_sim->acceleration = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim acceleration"); - cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos"); - cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos"); - cloth_sim->last_iteration_pos = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim last iteration pos"); - cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos"); - cloth_sim->length_constraint_tweak = MEM_calloc_arrayN( - totverts, sizeof(float), "cloth sim length tweak"); - - /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation - * positions. */ - if (brush && SCULPT_is_cloth_deform_brush(brush)) { - cloth_sim->deformation_pos = MEM_calloc_arrayN( - totverts, sizeof(float[3]), "cloth sim deformation positions"); - } - - cloth_sim->mass = cloth_mass; - cloth_sim->damping = cloth_damping; - - if (use_collisions) { - cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph); - } - - return cloth_sim; -} - typedef struct ClothBrushCollision { CollisionModifierData *col_data; struct IsectRayPrecalc isect_precalc; @@ -699,43 +688,6 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( BKE_pbvh_vertex_iter_end; } -static void cloth_brush_build_nodes_constraints( - Sculpt *sd, - Object *ob, - PBVHNode **nodes, - int totnode, - SculptClothSimulation *cloth_sim, - /* Cannot be const, because it is assigned to a non-const variable. - * NOLINTNEXTLINE: readability-non-const-parameter. */ - float initial_location[3], - const float radius) -{ - Brush *brush = BKE_paint_brush(&sd->paint); - - /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of - * storing the constraints per node. */ - /* Currently all constrains are added to the same global array which can't be accessed from - * different threads. */ - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, false, totnode); - - cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); - - SculptThreadedTaskData build_constraints_data = { - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .cloth_sim = cloth_sim, - .cloth_sim_initial_location = initial_location, - .cloth_sim_radius = radius, - }; - BLI_task_parallel_range( - 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); - - BLI_edgeset_free(cloth_sim->created_length_constraints); -} - static void cloth_brush_satisfy_constraints(SculptSession *ss, Brush *brush, SculptClothSimulation *cloth_sim) @@ -784,19 +736,27 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, cloth_sim->init_pos[v2]) : 1.0f; + float deformation_strength = 1.0f; + if (constraint->type == SCULPT_CLOTH_CONSTRAINT_DEFORMATION) { + deformation_strength = (cloth_sim->deformation_strength[v1] + + cloth_sim->deformation_strength[v2]) * + 0.5f; + } + madd_v3_v3fl(cloth_sim->pos[v1], correction_vector_half, - 1.0f * mask_v1 * sim_factor_v1 * constraint->strength); + 1.0f * mask_v1 * sim_factor_v1 * constraint->strength * deformation_strength); if (v1 != v2) { madd_v3_v3fl(cloth_sim->pos[v2], correction_vector_half, - -1.0f * mask_v2 * sim_factor_v2 * constraint->strength); + -1.0f * mask_v2 * sim_factor_v2 * constraint->strength * + deformation_strength); } } } } -static void cloth_brush_do_simulation_step( +void SCULPT_cloth_brush_do_simulation_step( Sculpt *sd, Object *ob, SculptClothSimulation *cloth_sim, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; @@ -890,6 +850,15 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod } } + if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) { + /* Set the deformation strength to 0. Snake hook will initialize the strength in the required + * area. */ + const int totverts = SCULPT_vertex_count_get(ss); + for (int i = 0; i < totverts; i++) { + ss->cache->cloth_sim->deformation_strength[i] = 0.0f; + } + } + TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); BLI_task_parallel_range( @@ -897,13 +866,116 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod } /* Public functions. */ +SculptClothSimulation *SCULPT_cloth_brush_simulation_create(SculptSession *ss, + Brush *brush, + const float cloth_mass, + const float cloth_damping, + const bool use_collisions) +{ + const int totverts = SCULPT_vertex_count_get(ss); + SculptClothSimulation *cloth_sim; + + cloth_sim = MEM_callocN(sizeof(SculptClothSimulation), "cloth constraints"); + + cloth_sim->length_constraints = MEM_callocN(sizeof(SculptClothLengthConstraint) * + CLOTH_LENGTH_CONSTRAINTS_BLOCK, + "cloth length constraints"); + cloth_sim->capacity_length_constraints = CLOTH_LENGTH_CONSTRAINTS_BLOCK; + + cloth_sim->acceleration = MEM_calloc_arrayN( + totverts, sizeof(float[3]), "cloth sim acceleration"); + cloth_sim->pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim pos"); + cloth_sim->prev_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim prev pos"); + cloth_sim->last_iteration_pos = MEM_calloc_arrayN( + totverts, sizeof(float[3]), "cloth sim last iteration pos"); + cloth_sim->init_pos = MEM_calloc_arrayN(totverts, sizeof(float[3]), "cloth sim init pos"); + cloth_sim->length_constraint_tweak = MEM_calloc_arrayN( + totverts, sizeof(float), "cloth sim length tweak"); + + /* Brush can be NULL for tools that need the solver but don't rely on constraint to deformation + * positions. */ + if (brush && SCULPT_is_cloth_deform_brush(brush)) { + cloth_sim->deformation_pos = MEM_calloc_arrayN( + totverts, sizeof(float[3]), "cloth sim deformation positions"); + cloth_sim->deformation_strength = MEM_calloc_arrayN( + totverts, sizeof(float), "cloth sim deformation strength"); + } + + cloth_sim->mass = cloth_mass; + cloth_sim->damping = cloth_damping; + + if (use_collisions) { + cloth_sim->collider_list = cloth_brush_collider_cache_create(ss->depsgraph); + } + + return cloth_sim; +} + +void SCULPT_cloth_brush_build_nodes_constraints( + Sculpt *sd, + Object *ob, + PBVHNode **nodes, + int totnode, + SculptClothSimulation *cloth_sim, + /* Cannot be const, because it is assigned to a non-const variable. + * NOLINTNEXTLINE: readability-non-const-parameter. */ + float initial_location[3], + const float radius) +{ + Brush *brush = BKE_paint_brush(&sd->paint); + + /* TODO: Multi-threaded needs to be disabled for this task until implementing the optimization of + * storing the constraints per node. */ + /* Currently all constrains are added to the same global array which can't be accessed from + * different threads. */ + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, false, totnode); + + cloth_sim->created_length_constraints = BLI_edgeset_new("created length constraints"); + + SculptThreadedTaskData build_constraints_data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + .cloth_sim = cloth_sim, + .cloth_sim_initial_location = initial_location, + .cloth_sim_radius = radius, + }; + BLI_task_parallel_range( + 0, totnode, &build_constraints_data, do_cloth_brush_build_constraints_task_cb_ex, &settings); + + BLI_edgeset_free(cloth_sim->created_length_constraints); +} + +void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation *cloth_sim) +{ + const int totverts = SCULPT_vertex_count_get(ss); + const bool has_deformation_pos = cloth_sim->deformation_pos != NULL; + for (int i = 0; i < totverts; i++) { + copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); + if (has_deformation_pos) { + copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i)); + cloth_sim->deformation_strength[i] = 1.0f; + } + } +} + +void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSimulation *cloth_sim) +{ + const int totverts = SCULPT_vertex_count_get(ss); + for (int i = 0; i < totverts; i++) { + copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); + } +} /* Main Brush Function. */ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - const int totverts = SCULPT_vertex_count_get(ss); /* In the first brush step of each symmetry pass, build the constraints for the vertices in all * nodes inside the simulation's limits. */ @@ -914,42 +986,32 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode /* The simulation structure only needs to be created on the first symmetry pass. */ if (SCULPT_stroke_is_first_brush_step(ss->cache) || !ss->cache->cloth_sim) { - const bool is_cloth_deform_brush = SCULPT_is_cloth_deform_brush(brush); - ss->cache->cloth_sim = cloth_brush_simulation_create( + ss->cache->cloth_sim = SCULPT_cloth_brush_simulation_create( ss, brush, brush->cloth_mass, brush->cloth_damping, (brush->flag2 & BRUSH_CLOTH_USE_COLLISION)); - for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(ss->cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(ss->cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); - if (is_cloth_deform_brush) { - copy_v3_v3(ss->cache->cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i)); - } - } + SCULPT_cloth_brush_simulation_init(ss, ss->cache->cloth_sim); } /* Build the constraints. */ const float radius = ss->cache->initial_radius; const float limit = radius + (radius * brush->cloth_sim_limit); - cloth_brush_build_nodes_constraints( + SCULPT_cloth_brush_build_nodes_constraints( sd, ob, nodes, totnode, ss->cache->cloth_sim, ss->cache->location, limit); return; } /* Store the initial state in the simulation. */ - for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); - } + SCULPT_cloth_brush_store_simulation_state(ss, ss->cache->cloth_sim); /* Apply forces to the vertices. */ cloth_brush_apply_brush_foces(sd, ob, nodes, totnode); /* Update and write the simulation to the nodes. */ - cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); + SCULPT_cloth_brush_do_simulation_step(sd, ob, ss->cache->cloth_sim, nodes, totnode); } void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) @@ -962,6 +1024,7 @@ void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim) MEM_SAFE_FREE(cloth_sim->length_constraint_tweak); MEM_SAFE_FREE(cloth_sim->deformation_pos); MEM_SAFE_FREE(cloth_sim->init_pos); + MEM_SAFE_FREE(cloth_sim->deformation_strength); if (cloth_sim->collider_list) { BKE_collider_cache_free(&cloth_sim->collider_list); } @@ -1043,11 +1106,39 @@ static EnumPropertyItem prop_cloth_filter_type[] = { {CLOTH_FILTER_GRAVITY, "GRAVITY", 0, "Gravity", "Applies gravity to the simulation"}, {CLOTH_FILTER_INFLATE, "INFLATE", 0, "Inflate", "Inflates the cloth"}, {CLOTH_FILTER_EXPAND, "EXPAND", 0, "Expand", "Expands the cloth's dimensions"}, - {CLOTH_FILTER_PINCH, - "PINCH", + {CLOTH_FILTER_PINCH, "PINCH", 0, "Pinch", "Pulls the cloth to the cursor's start position"}, + {0, NULL, 0, NULL, NULL}, +}; + +static EnumPropertyItem prop_cloth_filter_orientation_items[] = { + {SCULPT_FILTER_ORIENTATION_LOCAL, + "LOCAL", + 0, + "Local", + "Use the local axis to limit the force and set the gravity direction"}, + {SCULPT_FILTER_ORIENTATION_WORLD, + "WORLD", + 0, + "World", + "Use the global axis to limit the force and set the gravity direction"}, + {SCULPT_FILTER_ORIENTATION_VIEW, + "VIEW", 0, - "Pinch", - "Pinches the cloth to the point were the cursor was when the filter started"}, + "View", + "Use the view axis to limit the force and set the gravity direction"}, + {0, NULL, 0, NULL, NULL}, +}; + +typedef enum eClothFilterForceAxis { + CLOTH_FILTER_FORCE_X = 1 << 0, + CLOTH_FILTER_FORCE_Y = 1 << 1, + CLOTH_FILTER_FORCE_Z = 1 << 2, +} eClothFilterForceAxis; + +static EnumPropertyItem prop_cloth_filter_force_axis_items[] = { + {CLOTH_FILTER_FORCE_X, "X", 0, "X", "Apply force in the X axis"}, + {CLOTH_FILTER_FORCE_Y, "Y", 0, "Y", "Apply force in the Y axis"}, + {CLOTH_FILTER_FORCE_Z, "Z", 0, "Z", "Apply force in the Z axis"}, {0, NULL, 0, NULL, NULL}, }; @@ -1087,7 +1178,15 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, switch (filter_type) { case CLOTH_FILTER_GRAVITY: - force[2] = -data->filter_strength * fade; + if (ss->filter_cache->orientation == SCULPT_FILTER_ORIENTATION_VIEW) { + /* When using the view orientation apply gravity in the -Y axis, this way objects will + * fall down instead of backwards. */ + force[1] = -data->filter_strength * fade; + } + else { + force[2] = -data->filter_strength * fade; + } + SCULPT_filter_to_object_space(force, ss->filter_cache); break; case CLOTH_FILTER_INFLATE: { float normal[3]; @@ -1105,6 +1204,14 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, break; } + SCULPT_filter_to_orientation_space(force, ss->filter_cache); + for (int axis = 0; axis < 3; axis++) { + if (!ss->filter_cache->enabled_force_axis[axis]) { + force[axis] = 0.0f; + } + } + SCULPT_filter_to_object_space(force, ss->filter_cache); + add_v3_v3(force, sculpt_gravity); cloth_brush_apply_force_to_vertex(ss, cloth_sim, force, vd.index); @@ -1161,7 +1268,7 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent 0, ss->filter_cache->totnode, &data, cloth_filter_apply_forces_task_cb, &settings); /* Update and write the simulation to the nodes. */ - cloth_brush_do_simulation_step( + SCULPT_cloth_brush_do_simulation_step( sd, ob, ss->filter_cache->cloth_sim, ss->filter_cache->nodes, ss->filter_cache->totnode); if (ss->deform_modifiers_active || ss->shapekey_active) { @@ -1191,31 +1298,26 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); SCULPT_undo_push_begin("Cloth filter"); - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); const float cloth_mass = RNA_float_get(op->ptr, "cloth_mass"); const float cloth_damping = RNA_float_get(op->ptr, "cloth_damping"); const bool use_collisions = RNA_boolean_get(op->ptr, "use_collisions"); - ss->filter_cache->cloth_sim = cloth_brush_simulation_create( + ss->filter_cache->cloth_sim = SCULPT_cloth_brush_simulation_create( ss, NULL, cloth_mass, cloth_damping, use_collisions); copy_v3_v3(ss->filter_cache->cloth_sim_pinch_point, SCULPT_active_vertex_co_get(ss)); - const int totverts = SCULPT_vertex_count_get(ss); - for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->filter_cache->cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(ss->filter_cache->cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(ss->filter_cache->cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); - } + SCULPT_cloth_brush_simulation_init(ss, ss->filter_cache->cloth_sim); float origin[3] = {0.0f, 0.0f, 0.0f}; - cloth_brush_build_nodes_constraints(sd, - ob, - ss->filter_cache->nodes, - ss->filter_cache->totnode, - ss->filter_cache->cloth_sim, - origin, - FLT_MAX); + SCULPT_cloth_brush_build_nodes_constraints(sd, + ob, + ss->filter_cache->nodes, + ss->filter_cache->totnode, + ss->filter_cache->cloth_sim, + origin, + FLT_MAX); const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); if (use_face_sets) { @@ -1225,6 +1327,14 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE; } + const int force_axis = RNA_enum_get(op->ptr, "force_axis"); + ss->filter_cache->enabled_force_axis[0] = force_axis & CLOTH_FILTER_FORCE_X; + ss->filter_cache->enabled_force_axis[1] = force_axis & CLOTH_FILTER_FORCE_Y; + ss->filter_cache->enabled_force_axis[2] = force_axis & CLOTH_FILTER_FORCE_Z; + + SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation"); + ss->filter_cache->orientation = orientation; + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -1252,6 +1362,18 @@ void SCULPT_OT_cloth_filter(struct wmOperatorType *ot) "Operation that is going to be applied to the mesh"); RNA_def_float( ot->srna, "strength", 1.0f, -10.0f, 10.0f, "Strength", "Filter Strength", -10.0f, 10.0f); + RNA_def_enum_flag(ot->srna, + "force_axis", + prop_cloth_filter_force_axis_items, + CLOTH_FILTER_FORCE_X | CLOTH_FILTER_FORCE_Y | CLOTH_FILTER_FORCE_Z, + "Force axis", + "Apply the force in the selected axis"); + RNA_def_enum(ot->srna, + "orientation", + prop_cloth_filter_orientation_items, + SCULPT_FILTER_ORIENTATION_LOCAL, + "Orientation", + "Orientation of the axis to limit the filter force"); RNA_def_float(ot->srna, "cloth_mass", 1.0f, diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index 2afa3556dd9..b9265380a35 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -71,6 +71,37 @@ #include <math.h> #include <stdlib.h> +/* Utils. */ +int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh) +{ + int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS); + if (!face_sets) { + return SCULPT_FACE_SET_NONE; + } + + int next_face_set_id = 0; + for (int i = 0; i < mesh->totpoly; i++) { + next_face_set_id = max_ii(next_face_set_id, abs(face_sets[i])); + } + next_face_set_id++; + + return next_face_set_id; +} + +void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id) +{ + int *face_sets = CustomData_get_layer(&mesh->pdata, CD_SCULPT_FACE_SETS); + if (!face_sets) { + return; + } + + for (int i = 0; i < mesh->totpoly; i++) { + if (face_sets[i] == SCULPT_FACE_SET_NONE) { + face_sets[i] = new_id; + } + } +} + /* Draw Face Sets Brush. */ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, @@ -901,6 +932,25 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int sculpt_face_sets_change_visibility_invoke(bContext *C, + wmOperator *op, + const wmEvent *event) +{ + Object *ob = CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + + /* Update the active vertex and Face Set using the cursor position to avoid relying on the paint + * cursor updates. */ + SculptCursorGeometryInfo sgi; + float mouse[2]; + mouse[0] = event->mval[0]; + mouse[1] = event->mval[1]; + SCULPT_vertex_random_access_ensure(ss); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + + return sculpt_face_sets_change_visibility_exec(C, op); +} + void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot) { /* Identifiers. */ @@ -910,6 +960,7 @@ void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot) /* Api callbacks. */ ot->exec = sculpt_face_sets_change_visibility_exec; + ot->invoke = sculpt_face_sets_change_visibility_invoke; ot->poll = SCULPT_mode_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 576536cac03..c5acf736f3e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -289,7 +289,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; } - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COLOR); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COLOR); WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index f9ae91fce7f..619a1b975b6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -50,6 +50,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_view3d.h" #include "paint_intern.h" #include "sculpt_intern.h" @@ -63,6 +64,39 @@ #include <math.h> #include <stdlib.h> +/* Filter orientation utils. */ +void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache) +{ + switch (filter_cache->orientation) { + case SCULPT_FILTER_ORIENTATION_LOCAL: + /* Do nothing, Sculpt Mode already works in object space. */ + break; + case SCULPT_FILTER_ORIENTATION_WORLD: + mul_mat3_m4_v3(filter_cache->obmat, r_v); + break; + case SCULPT_FILTER_ORIENTATION_VIEW: + mul_mat3_m4_v3(filter_cache->obmat, r_v); + mul_mat3_m4_v3(filter_cache->viewmat, r_v); + break; + } +} + +void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache) +{ + switch (filter_cache->orientation) { + case SCULPT_FILTER_ORIENTATION_LOCAL: + /* Do nothing, Sculpt Mode already works in object space. */ + break; + case SCULPT_FILTER_ORIENTATION_WORLD: + mul_mat3_m4_v3(filter_cache->obmat_inv, r_v); + break; + case SCULPT_FILTER_ORIENTATION_VIEW: + mul_mat3_m4_v3(filter_cache->viewmat_inv, r_v); + mul_mat3_m4_v3(filter_cache->obmat_inv, r_v); + break; + } +} + static void filter_cache_init_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) @@ -73,7 +107,7 @@ static void filter_cache_init_task_cb(void *__restrict userdata, SCULPT_undo_push_node(data->ob, node, data->filter_undo_type); } -void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) +void SCULPT_filter_cache_init(bContext *C, Object *ob, Sculpt *sd, const int undo_type) { SculptSession *ss = ob->sculpt; PBVH *pbvh = ob->sculpt->pbvh; @@ -117,6 +151,16 @@ void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type) BKE_pbvh_parallel_range_settings(&settings, true, ss->filter_cache->totnode); BLI_task_parallel_range( 0, ss->filter_cache->totnode, &data, filter_cache_init_task_cb, &settings); + + /* Setup orientation matrices. */ + copy_m4_m4(ss->filter_cache->obmat, ob->obmat); + invert_m4_m4(ss->filter_cache->obmat_inv, ob->obmat); + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ViewContext vc; + ED_view3d_viewcontext_init(C, &vc, depsgraph); + copy_m4_m4(ss->filter_cache->viewmat, vc.rv3d->viewmat); + copy_m4_m4(ss->filter_cache->viewmat_inv, vc.rv3d->viewinv); } void SCULPT_filter_cache_free(SculptSession *ss) @@ -132,11 +176,12 @@ void SCULPT_filter_cache_free(SculptSession *ss) MEM_SAFE_FREE(ss->filter_cache->automask); MEM_SAFE_FREE(ss->filter_cache->surface_smooth_laplacian_disp); MEM_SAFE_FREE(ss->filter_cache->sharpen_factor); - MEM_SAFE_FREE(ss->filter_cache->sharpen_detail_directions); + MEM_SAFE_FREE(ss->filter_cache->detail_directions); + MEM_SAFE_FREE(ss->filter_cache->limit_surface_co); MEM_SAFE_FREE(ss->filter_cache); } -typedef enum eSculptMeshFilterTypes { +typedef enum eSculptMeshFilterType { MESH_FILTER_SMOOTH = 0, MESH_FILTER_SCALE = 1, MESH_FILTER_INFLATE = 2, @@ -146,7 +191,9 @@ typedef enum eSculptMeshFilterTypes { MESH_FILTER_RELAX_FACE_SETS = 6, MESH_FILTER_SURFACE_SMOOTH = 7, MESH_FILTER_SHARPEN = 8, -} eSculptMeshFilterTypes; + MESH_FILTER_ENHANCE_DETAILS = 9, + MESH_FILTER_ERASE_DISPLACEMENT = 10, +} eSculptMeshFilterType; static EnumPropertyItem prop_mesh_filter_types[] = { {MESH_FILTER_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth mesh"}, @@ -166,6 +213,16 @@ static EnumPropertyItem prop_mesh_filter_types[] = { "Surface Smooth", "Smooth the surface of the mesh, preserving the volume"}, {MESH_FILTER_SHARPEN, "SHARPEN", 0, "Sharpen", "Sharpen the cavities of the mesh"}, + {MESH_FILTER_ENHANCE_DETAILS, + "ENHANCE_DETAILS", + 0, + "Enhance Details", + "Enhance the high frequency surface detail"}, + {MESH_FILTER_ERASE_DISPLACEMENT, + "ERASE_DISCPLACEMENT", + 0, + "Erase Displacement", + "Deletes the displacement of the Multires Modifier"}, {0, NULL, 0, NULL, NULL}, }; @@ -182,13 +239,33 @@ static EnumPropertyItem prop_mesh_filter_deform_axis_items[] = { {0, NULL, 0, NULL, NULL}, }; -static bool sculpt_mesh_filter_needs_pmap(int filter_type, bool use_face_sets) +static EnumPropertyItem prop_mesh_filter_orientation_items[] = { + {SCULPT_FILTER_ORIENTATION_LOCAL, + "LOCAL", + 0, + "Local", + "Use the local axis to limit the displacement"}, + {SCULPT_FILTER_ORIENTATION_WORLD, + "WORLD", + 0, + "World", + "Use the global axis to limit the displacement"}, + {SCULPT_FILTER_ORIENTATION_VIEW, + "VIEW", + 0, + "View", + "Use the view axis to limit the displacement"}, + {0, NULL, 0, NULL, NULL}, +}; + +static bool sculpt_mesh_filter_needs_pmap(eSculptMeshFilterType filter_type, bool use_face_sets) { return use_face_sets || ELEM(filter_type, MESH_FILTER_SMOOTH, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS, MESH_FILTER_SURFACE_SMOOTH, + MESH_FILTER_ENHANCE_DETAILS, MESH_FILTER_SHARPEN); } @@ -200,7 +277,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; - const int filter_type = data->filter_type; + const eSculptMeshFilterType filter_type = data->filter_type; SculptOrigVertData orig_data; SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[i]); @@ -306,7 +383,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, const uint *hash_co = (const uint *)orig_co; const uint hash = BLI_hash_int_2d(hash_co[0], hash_co[1]) ^ BLI_hash_int_2d(hash_co[2], ss->filter_cache->random_seed); - mul_v3_fl(normal, hash * (1.0f / 0xFFFFFFFF) - 0.5f); + mul_v3_fl(normal, hash * (1.0f / (float)0xFFFFFFFF) - 0.5f); mul_v3_v3fl(disp, normal, fade); break; } @@ -362,7 +439,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, if (ss->filter_cache->sharpen_intensify_detail_strength > 0.0f) { float detail_strength[3]; normal_short_to_float_v3(detail_strength, orig_data.no); - copy_v3_v3(detail_strength, ss->filter_cache->sharpen_detail_directions[vd.index]); + copy_v3_v3(detail_strength, ss->filter_cache->detail_directions[vd.index]); madd_v3_v3fl(disp, detail_strength, -ss->filter_cache->sharpen_intensify_detail_strength * @@ -370,13 +447,25 @@ static void mesh_filter_task_cb(void *__restrict userdata, } break; } + + case MESH_FILTER_ENHANCE_DETAILS: { + mul_v3_v3fl(disp, ss->filter_cache->detail_directions[vd.index], -fabsf(fade)); + } break; + case MESH_FILTER_ERASE_DISPLACEMENT: { + fade = clamp_f(fade, 0.0f, 1.0f); + sub_v3_v3v3(disp, ss->filter_cache->limit_surface_co[vd.index], orig_co); + mul_v3_fl(disp, fade); + break; + } } + SCULPT_filter_to_orientation_space(disp, ss->filter_cache); for (int it = 0; it < 3; it++) { if (!ss->filter_cache->enabled_axis[it]) { disp[it] = 0.0f; } } + SCULPT_filter_to_object_space(disp, ss->filter_cache); if (ELEM(filter_type, MESH_FILTER_SURFACE_SMOOTH, MESH_FILTER_SHARPEN)) { madd_v3_v3v3fl(final_pos, vd.co, disp, clamp_f(fade, 0.0f, 1.0f)); @@ -394,32 +483,83 @@ static void mesh_filter_task_cb(void *__restrict userdata, BKE_pbvh_node_mark_update(node); } -static void mesh_filter_sharpen_init_factors(SculptSession *ss) +static void mesh_filter_enhance_details_init_directions(SculptSession *ss) { const int totvert = SCULPT_vertex_count_get(ss); + FilterCache *filter_cache = ss->filter_cache; + + filter_cache->detail_directions = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "detail directions"); for (int i = 0; i < totvert; i++) { float avg[3]; SCULPT_neighbor_coords_average(ss, avg, i); - sub_v3_v3v3(ss->filter_cache->sharpen_detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); - ss->filter_cache->sharpen_factor[i] = len_v3(ss->filter_cache->sharpen_detail_directions[i]); + sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + } +} + +static void mesh_filter_surface_smooth_init(SculptSession *ss, + const float shape_preservation, + const float current_vertex_displacement) +{ + const int totvert = SCULPT_vertex_count_get(ss); + FilterCache *filter_cache = ss->filter_cache; + + filter_cache->surface_smooth_laplacian_disp = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "surface smooth displacement"); + filter_cache->surface_smooth_shape_preservation = shape_preservation; + filter_cache->surface_smooth_current_vertex = current_vertex_displacement; +} + +static void mesh_filter_init_limit_surface_co(SculptSession *ss) +{ + const int totvert = SCULPT_vertex_count_get(ss); + FilterCache *filter_cache = ss->filter_cache; + + filter_cache->limit_surface_co = MEM_malloc_arrayN( + sizeof(float[3]), totvert, "limit surface co"); + for (int i = 0; i < totvert; i++) { + SCULPT_vertex_limit_surface_get(ss, i, filter_cache->limit_surface_co[i]); + } +} + +static void mesh_filter_sharpen_init(SculptSession *ss, + const float smooth_ratio, + const float intensify_detail_strength, + const int curvature_smooth_iterations) +{ + const int totvert = SCULPT_vertex_count_get(ss); + FilterCache *filter_cache = ss->filter_cache; + + filter_cache->sharpen_smooth_ratio = smooth_ratio; + filter_cache->sharpen_intensify_detail_strength = intensify_detail_strength; + filter_cache->sharpen_curvature_smooth_iterations = curvature_smooth_iterations; + filter_cache->sharpen_factor = MEM_malloc_arrayN(sizeof(float), totvert, "sharpen factor"); + filter_cache->detail_directions = MEM_malloc_arrayN( + totvert, sizeof(float[3]), "sharpen detail direction"); + + for (int i = 0; i < totvert; i++) { + float avg[3]; + SCULPT_neighbor_coords_average(ss, avg, i); + sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + filter_cache->sharpen_factor[i] = len_v3(filter_cache->detail_directions[i]); } float max_factor = 0.0f; for (int i = 0; i < totvert; i++) { - if (ss->filter_cache->sharpen_factor[i] > max_factor) { - max_factor = ss->filter_cache->sharpen_factor[i]; + if (filter_cache->sharpen_factor[i] > max_factor) { + max_factor = filter_cache->sharpen_factor[i]; } } max_factor = 1.0f / max_factor; for (int i = 0; i < totvert; i++) { - ss->filter_cache->sharpen_factor[i] *= max_factor; - ss->filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - ss->filter_cache->sharpen_factor[i]); + filter_cache->sharpen_factor[i] *= max_factor; + filter_cache->sharpen_factor[i] = 1.0f - pow2f(1.0f - filter_cache->sharpen_factor[i]); } /* Smooth the calculated factors and directions to remove high frecuency detail. */ for (int smooth_iterations = 0; - smooth_iterations < ss->filter_cache->sharpen_curvature_smooth_iterations; + smooth_iterations < filter_cache->sharpen_curvature_smooth_iterations; smooth_iterations++) { for (int i = 0; i < totvert; i++) { float direction_avg[3] = {0.0f, 0.0f, 0.0f}; @@ -428,15 +568,15 @@ static void mesh_filter_sharpen_init_factors(SculptSession *ss) SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { - add_v3_v3(direction_avg, ss->filter_cache->sharpen_detail_directions[ni.index]); - sharpen_avg += ss->filter_cache->sharpen_factor[ni.index]; + add_v3_v3(direction_avg, filter_cache->detail_directions[ni.index]); + sharpen_avg += filter_cache->sharpen_factor[ni.index]; total++; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); if (total > 0) { - mul_v3_v3fl(ss->filter_cache->sharpen_detail_directions[i], direction_avg, 1.0f / total); - ss->filter_cache->sharpen_factor[i] = sharpen_avg / total; + mul_v3_v3fl(filter_cache->detail_directions[i], direction_avg, 1.0f / total); + filter_cache->sharpen_factor[i] = sharpen_avg / total; } } } @@ -481,7 +621,7 @@ static int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent * Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - int filter_type = RNA_enum_get(op->ptr, "type"); + eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type"); float filter_strength = RNA_float_get(op->ptr, "strength"); const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); @@ -545,17 +685,21 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - int filter_type = RNA_enum_get(op->ptr, "type"); SculptSession *ss = ob->sculpt; - PBVH *pbvh = ob->sculpt->pbvh; - int deform_axis = RNA_enum_get(op->ptr, "deform_axis"); + const eMeshFilterDeformAxis deform_axis = RNA_enum_get(op->ptr, "deform_axis"); + const eSculptMeshFilterType filter_type = RNA_enum_get(op->ptr, "type"); + const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); + const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets); + if (deform_axis == 0) { + /* All axis are disabled, so the filter is not going to produce any deformation. */ return OPERATOR_CANCELLED; } - if (RNA_boolean_get(op->ptr, "use_face_sets")) { - /* Update the active vertex */ + if (use_face_sets) { + /* Update the active face set manually as the paint cursor is not enabled when using the Mesh + * Filter Tool. */ float mouse[2]; SculptCursorGeometryInfo sgi; mouse[0] = event->mval[0]; @@ -563,63 +707,57 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); } - const bool use_face_sets = RNA_boolean_get(op->ptr, "use_face_sets"); - SCULPT_vertex_random_access_ensure(ss); - - const bool needs_topology_info = sculpt_mesh_filter_needs_pmap(filter_type, use_face_sets); BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, false); if (needs_topology_info) { SCULPT_boundary_info_ensure(ob); } - const int totvert = SCULPT_vertex_count_get(ss); - if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_topology_info && !ob->sculpt->pmap) { - return OPERATOR_CANCELLED; - } - - SCULPT_undo_push_begin("Mesh filter"); - - if (ELEM(filter_type, MESH_FILTER_RELAX, MESH_FILTER_RELAX_FACE_SETS)) { - SCULPT_boundary_info_ensure(ob); - } - - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); - - if (use_face_sets) { - ss->filter_cache->active_face_set = SCULPT_active_face_set_get(ss); - } - else { - ss->filter_cache->active_face_set = SCULPT_FACE_SET_NONE; - } - - if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SURFACE_SMOOTH) { - ss->filter_cache->surface_smooth_laplacian_disp = MEM_mallocN(sizeof(float[3]) * totvert, - "surface smooth disp"); - ss->filter_cache->surface_smooth_shape_preservation = RNA_float_get( - op->ptr, "surface_smooth_shape_preservation"); - ss->filter_cache->surface_smooth_current_vertex = RNA_float_get( - op->ptr, "surface_smooth_current_vertex"); - } + SCULPT_undo_push_begin("Mesh Filter"); - if (RNA_enum_get(op->ptr, "type") == MESH_FILTER_SHARPEN) { - ss->filter_cache->sharpen_smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio"); - ss->filter_cache->sharpen_intensify_detail_strength = RNA_float_get( - op->ptr, "sharpen_intensify_detail_strength"); - ss->filter_cache->sharpen_curvature_smooth_iterations = RNA_int_get( - op->ptr, "sharpen_curvature_smooth_iterations"); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); - ss->filter_cache->sharpen_factor = MEM_mallocN(sizeof(float) * totvert, "sharpen factor"); - ss->filter_cache->sharpen_detail_directions = MEM_malloc_arrayN( - totvert, sizeof(float[3]), "sharpen detail direction"); + FilterCache *filter_cache = ss->filter_cache; + filter_cache->active_face_set = use_face_sets ? SCULPT_active_face_set_get(ss) : + SCULPT_FACE_SET_NONE; - mesh_filter_sharpen_init_factors(ss); + switch (filter_type) { + case MESH_FILTER_SURFACE_SMOOTH: { + const float shape_preservation = RNA_float_get(op->ptr, "surface_smooth_shape_preservation"); + const float current_vertex_displacement = RNA_float_get(op->ptr, + "surface_smooth_current_vertex"); + mesh_filter_surface_smooth_init(ss, shape_preservation, current_vertex_displacement); + break; + } + case MESH_FILTER_SHARPEN: { + const float smooth_ratio = RNA_float_get(op->ptr, "sharpen_smooth_ratio"); + const float intensify_detail_strength = RNA_float_get(op->ptr, + "sharpen_intensify_detail_strength"); + const int curvature_smooth_iterations = RNA_int_get(op->ptr, + "sharpen_curvature_smooth_iterations"); + mesh_filter_sharpen_init( + ss, smooth_ratio, intensify_detail_strength, curvature_smooth_iterations); + break; + } + case MESH_FILTER_ENHANCE_DETAILS: { + mesh_filter_enhance_details_init_directions(ss); + break; + } + case MESH_FILTER_ERASE_DISPLACEMENT: { + mesh_filter_init_limit_surface_co(ss); + break; + } + default: + break; } ss->filter_cache->enabled_axis[0] = deform_axis & MESH_FILTER_DEFORM_X; ss->filter_cache->enabled_axis[1] = deform_axis & MESH_FILTER_DEFORM_Y; ss->filter_cache->enabled_axis[2] = deform_axis & MESH_FILTER_DEFORM_Z; + SculptFilterOrientation orientation = RNA_enum_get(op->ptr, "orientation"); + ss->filter_cache->orientation = orientation; + WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; } @@ -653,6 +791,12 @@ void SCULPT_OT_mesh_filter(struct wmOperatorType *ot) MESH_FILTER_DEFORM_X | MESH_FILTER_DEFORM_Y | MESH_FILTER_DEFORM_Z, "Deform axis", "Apply the deformation in the selected axis"); + RNA_def_enum(ot->srna, + "orientation", + prop_mesh_filter_orientation_items, + SCULPT_FILTER_ORIENTATION_LOCAL, + "Orientation", + "Orientation of the axis to limit the filter displacement"); ot->prop = RNA_def_boolean(ot->srna, "use_face_sets", false, diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index b11a7005fb5..47a375a2318 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -100,10 +100,16 @@ const float *SCULPT_vertex_color_get(SculptSession *ss, int index); const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index); void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]); -/* Returs the info of the limit surface when Multires is available, otherwise it returns the +/* Returns the info of the limit surface when Multires is available, otherwise it returns the * current coordinate of the vertex. */ void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]); +/* Returns the pointer to the coordinates that should be edited from a brush tool iterator + * depending on the given deformation target. */ +float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, + const int deform_target, + PBVHVertexIter *iter); + #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 typedef struct SculptVertexNeighborIter { /* Storage */ @@ -337,7 +343,7 @@ float *SCULPT_boundary_automasking_init(Object *ob, float *automask_factor); /* Filters. */ -void SCULPT_filter_cache_init(Object *ob, Sculpt *sd, const int undo_type); +void SCULPT_filter_cache_init(struct bContext *C, Object *ob, Sculpt *sd, const int undo_type); void SCULPT_filter_cache_free(SculptSession *ss); void SCULPT_mask_filter_smooth_apply( @@ -350,8 +356,33 @@ void SCULPT_do_cloth_brush(struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, int totnode); + void SCULPT_cloth_simulation_free(struct SculptClothSimulation *cloth_sim); +struct SculptClothSimulation *SCULPT_cloth_brush_simulation_create(struct SculptSession *ss, + struct Brush *brush, + const float cloth_mass, + const float cloth_damping, + const bool use_collisions); +void SCULPT_cloth_brush_simulation_init(struct SculptSession *ss, + struct SculptClothSimulation *cloth_sim); +void SCULPT_cloth_brush_store_simulation_state(struct SculptSession *ss, + struct SculptClothSimulation *cloth_sim); + +void SCULPT_cloth_brush_do_simulation_step(struct Sculpt *sd, + struct Object *ob, + struct SculptClothSimulation *cloth_sim, + struct PBVHNode **nodes, + int totnode); + +void SCULPT_cloth_brush_build_nodes_constraints(struct Sculpt *sd, + struct Object *ob, + struct PBVHNode **nodes, + int totnode, + struct SculptClothSimulation *cloth_sim, + float initial_location[3], + const float radius); + void SCULPT_cloth_simulation_limits_draw(const uint gpuattr, const struct Brush *brush, const float location[3], @@ -367,8 +398,13 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) { - return brush->sculpt_tool == SCULPT_TOOL_CLOTH && - brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB; + return (brush->sculpt_tool == SCULPT_TOOL_CLOTH && ELEM(brush->cloth_deform_type, + BRUSH_CLOTH_DEFORM_GRAB, + BRUSH_CLOTH_DEFORM_SNAKE_HOOK)) || + /* All brushes that are not the cloth brush deform the simulation using softbody + constriants instead of applying forces. */ + (brush->sculpt_tool != SCULPT_TOOL_CLOTH && + brush->deform_target == BRUSH_DEFORM_TARGET_CLOTH_SIM); } /* Pose Brush. */ @@ -398,9 +434,10 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain); /* Boundary Brush. */ struct SculptBoundary *SCULPT_boundary_data_init(Object *object, + Brush *brush, const int initial_vertex, const float radius); -void SCULPT_boundary_data_free(struct SculptBoundary *bdata); +void SCULPT_boundary_data_free(struct SculptBoundary *boundary); void SCULPT_do_boundary_brush(struct Sculpt *sd, struct Object *ob, struct PBVHNode **nodes, @@ -864,6 +901,9 @@ typedef struct StrokeCache { /* Pose brush */ struct SculptPoseIKChain *pose_ik_chain; + /* Enhance Details. */ + float (*detail_directions)[3]; + /* Clay Thumb brush */ /* Angle of the front tilting plane of the brush to simulate clay accumulation. */ float clay_thumb_front_angle; @@ -879,7 +919,7 @@ typedef struct StrokeCache { float true_initial_normal[3]; /* Boundary brush */ - struct SculptBoundary *bdata[PAINT_SYMM_AREAS]; + struct SculptBoundary *boundaries[PAINT_SYMM_AREAS]; /* Surface Smooth Brush */ /* Stores the displacement produced by the laplacian step of HC smooth. */ @@ -919,8 +959,19 @@ typedef struct StrokeCache { } StrokeCache; +/* Sculpt Filters */ +typedef enum SculptFilterOrientation { + SCULPT_FILTER_ORIENTATION_LOCAL = 0, + SCULPT_FILTER_ORIENTATION_WORLD = 1, + SCULPT_FILTER_ORIENTATION_VIEW = 2, +} SculptFilterOrientation; + +void SCULPT_filter_to_orientation_space(float r_v[3], struct FilterCache *filter_cache); +void SCULPT_filter_to_object_space(float r_v[3], struct FilterCache *filter_cache); + typedef struct FilterCache { bool enabled_axis[3]; + bool enabled_force_axis[3]; int random_seed; /* Used for alternating between filter operations in filters that need to apply different ones to @@ -937,7 +988,17 @@ typedef struct FilterCache { float sharpen_intensify_detail_strength; int sharpen_curvature_smooth_iterations; float *sharpen_factor; - float (*sharpen_detail_directions)[3]; + float (*detail_directions)[3]; + + /* Filter orientaiton. */ + SculptFilterOrientation orientation; + float obmat[4][4]; + float obmat_inv[4][4]; + float viewmat[4][4]; + float viewmat_inv[4][4]; + + /* Displacement eraser. */ + float (*limit_surface_co)[3]; /* unmasked nodes */ PBVHNode **nodes; diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index 4d41d069155..e53e33c1186 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -165,6 +165,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, SculptSession *ss = data->ob->sculpt; SculptPoseIKChain *ik_chain = ss->cache->pose_ik_chain; SculptPoseIKChainSegment *segments = ik_chain->segments; + const Brush *brush = data->brush; PBVHVertexIter vd; float disp[3], new_co[3]; @@ -206,7 +207,9 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, /* Apply the accumulated displacement to the vertex. */ add_v3_v3v3(final_pos, orig_data.co, total_disp); - copy_v3_v3(vd.co, final_pos); + + float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); + copy_v3_v3(target_co, final_pos); if (vd.mvert) { vd.mvert->flag |= ME_VERT_PBVH_UPDATE; diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index 2b93298ac4a..87ee7480c92 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -66,25 +66,40 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], { float avg[3] = {0.0f, 0.0f, 0.0f}; int total = 0; - - if (SCULPT_vertex_is_boundary(ss, index)) { - copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); - return; - } + int neighbor_count = 0; + const bool is_boundary = SCULPT_vertex_is_boundary(ss, index); SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { - add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); - total++; + neighbor_count++; + if (is_boundary) { + /* Boundary vertices use only other boundary vertices. */ + if (SCULPT_vertex_is_boundary(ss, ni.index)) { + add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); + total++; + } + } + else { + /* Interior vertices use all neighbors. */ + add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); + total++; + } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); - if (total > 0) { - mul_v3_v3fl(result, avg, 1.0f / total); + /* Do not modify corner vertices. */ + if (neighbor_count <= 2) { + copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); + return; } - else { + + /* Avoid division by 0 when there are no neighbors. */ + if (total == 0) { copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); + return; } + + mul_v3_v3fl(result, avg, 1.0f / total); } /* For bmesh: Average surrounding verts based on an orthogonality measure. @@ -195,6 +210,85 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index } } +static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict tls) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + Sculpt *sd = data->sd; + const Brush *brush = data->brush; + + PBVHVertexIter vd; + + float bstrength = ss->cache->bstrength; + CLAMP(bstrength, -1.0f, 1.0f); + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, data->brush->falloff_shape); + + const int thread_id = BLI_task_parallel_thread_id(tls); + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + float disp[3]; + madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); + SCULPT_clip(sd, ss, vd.co, disp); + + if (vd.mvert) { + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + } + BKE_pbvh_vertex_iter_end; +} + +static void SCULPT_enhance_details_brush(Sculpt *sd, + Object *ob, + PBVHNode **nodes, + const int totnode) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + SCULPT_vertex_random_access_ensure(ss); + SCULPT_boundary_info_ensure(ob); + + if (SCULPT_stroke_is_first_brush_step(ss->cache)) { + const int totvert = SCULPT_vertex_count_get(ss); + ss->cache->detail_directions = MEM_malloc_arrayN( + totvert, 3 * sizeof(float), "details directions"); + + for (int i = 0; i < totvert; i++) { + float avg[3]; + SCULPT_neighbor_coords_average(ss, avg, i); + sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + } + } + + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + }; + + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BLI_task_parallel_range(0, totnode, &data, do_enhance_details_brush_task_cb_ex, &settings); +} + static void do_smooth_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) @@ -237,7 +331,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, } else { float avg[3], val[3]; - SCULPT_neighbor_coords_average(ss, avg, vd.index); + SCULPT_neighbor_coords_average_interior(ss, avg, vd.index); sub_v3_v3v3(val, avg, vd.co); madd_v3_v3v3fl(val, vd.co, val, fade); SCULPT_clip(sd, ss, vd.co, val); @@ -300,7 +394,14 @@ void SCULPT_smooth(Sculpt *sd, void SCULPT_do_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; - SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false); + if (ss->cache->bstrength <= 0.0f) { + /* Invert mode, intensify details. */ + SCULPT_enhance_details_brush(sd, ob, nodes, totnode); + } + else { + /* Regular mode, smooth. */ + SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false); + } } /* HC Smooth Algorithm. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c index 4c54a0465b9..b52b04eba3a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.c @@ -76,7 +76,7 @@ void ED_sculpt_init_transform(struct bContext *C) ss->pivot_rot[3] = 1.0f; SCULPT_vertex_random_access_ensure(ss); - SCULPT_filter_cache_init(ob, sd, SCULPT_UNDO_COORDS); + SCULPT_filter_cache_init(C, ob, sd, SCULPT_UNDO_COORDS); } static void sculpt_transform_task_cb(void *__restrict userdata, @@ -326,6 +326,12 @@ static int sculpt_set_pivot_position_exec(bContext *C, wmOperator *op) MEM_SAFE_FREE(nodes); } + /* Update the viewport navigation rotation origin. */ + UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; + copy_v3_v3(ups->average_stroke_accum, ss->pivot_pos); + ups->average_stroke_counter = 1; + ups->last_stroke_valid = true; + ED_region_tag_redraw(region); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data); diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 050dca07c34..d4f5f066d48 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -257,10 +257,10 @@ static void sound_update_animation_flags(Scene *scene) } scene->id.tag |= LIB_TAG_DOIT; - SEQ_BEGIN (scene->ed, seq) { + SEQ_ALL_BEGIN (scene->ed, seq) { BKE_sequencer_recursive_apply(seq, sound_update_animation_flags_fn, scene); } - SEQ_END; + SEQ_ALL_END; fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); if (fcu || driven) { @@ -306,7 +306,6 @@ static void SOUND_OT_update_animation_flags(wmOperatorType *ot) static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) { - Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); /* NOTE: We will be forcefully evaluating dependency graph at every frame, so no need to ensure * current scene state is evaluated as it will be lost anyway. */ @@ -318,11 +317,11 @@ static int sound_bake_animation_exec(bContext *C, wmOperator *UNUSED(op)) for (cfra = (scene->r.sfra > 0) ? (scene->r.sfra - 1) : 0; cfra <= scene->r.efra + 1; cfra++) { scene->r.cfra = cfra; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); } scene->r.cfra = oldfra; - BKE_scene_graph_update_for_newframe(depsgraph, bmain); + BKE_scene_graph_update_for_newframe(depsgraph); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index ada4243ab4e..8634e5a5f29 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -169,7 +169,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* first backdrop strips */ float ymax = ACHANNEL_FIRST_TOP(ac); @@ -276,7 +276,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region } } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* black line marking 'current frame' for Time-Slide transform mode */ if (saction->flag & SACTION_MOVING) { @@ -558,7 +558,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Iterate over pointcaches on the active object, and draw each one's range. */ float y_offset = 0.0f; @@ -577,7 +577,7 @@ void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene) y_offset += cache_draw_height; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); BLI_freelistN(&pidlist); diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index db55eff8284..cd4197d1df8 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -191,7 +191,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); @@ -278,7 +277,6 @@ static void action_channel_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 25ff6bbd098..75d91174470 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -54,4 +54,9 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() +if(WITH_EXPERIMENTAL_FEATURES) + add_definitions(-DWITH_PARTICLE_NODES) + add_definitions(-DWITH_HAIR_NODES) +endif() + blender_add_lib(bf_editor_space_buttons "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 5885d3dcbb0..e567b3ca54c 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -249,12 +249,16 @@ static bool buttons_context_path_data(ButsContextPath *path, int type) if (RNA_struct_is_a(ptr->type, &RNA_GreasePencil) && (type == -1 || type == OB_GPENCIL)) { return true; } +#ifdef WITH_HAIR_NODES if (RNA_struct_is_a(ptr->type, &RNA_Hair) && (type == -1 || type == OB_HAIR)) { return true; } +#endif +#ifdef WITH_PARTICLE_NODES if (RNA_struct_is_a(ptr->type, &RNA_PointCloud) && (type == -1 || type == OB_POINTCLOUD)) { return true; } +#endif if (RNA_struct_is_a(ptr->type, &RNA_Volume) && (type == -1 || type == OB_VOLUME)) { return true; } @@ -791,8 +795,12 @@ const char *buttons_context_dir[] = { "line_style", "collection", "gpencil", +#ifdef WITH_HAIR_NODES "hair", +#endif +#ifdef WITH_PARTICLE_NODES "pointcloud", +#endif "volume", NULL, }; @@ -871,14 +879,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r set_pointer_type(path, result, &RNA_LightProbe); return 1; } +#ifdef WITH_HAIR_NODES if (CTX_data_equals(member, "hair")) { set_pointer_type(path, result, &RNA_Hair); return 1; } +#endif +#ifdef WITH_PARTICLE_NODES if (CTX_data_equals(member, "pointcloud")) { set_pointer_type(path, result, &RNA_PointCloud); return 1; } +#endif if (CTX_data_equals(member, "volume")) { set_pointer_type(path, result, &RNA_Volume); return 1; diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index dc34e56dc92..d7cf2e4d544 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -292,9 +292,7 @@ static void buttons_main_region_layout_properties(const bContext *C, break; } - const bool vertical = true; - ED_region_panels_layout_ex( - C, region, ®ion->type->paneltypes, contexts, sbuts->mainb, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, contexts, NULL); } static void buttons_main_region_layout(const bContext *C, ARegion *region) diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index c7328ae9f8f..8aaf3faffec 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -142,7 +142,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) strip[3] = 0.5f; selected_strip[3] = 1.0f; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); clip_draw_dopesheet_background(region, clip, pos_id); @@ -288,7 +288,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) immUnbindProgram(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -389,7 +389,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock"); BLI_assert(chan_prop_lock); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (channel = dopesheet->channels.first; channel; channel = channel->next) { float yminc = (float)(y - CHANNEL_HEIGHT_HALF); float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF); @@ -426,7 +426,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) /* adjust y-position for next one */ y -= CHANNEL_STEP; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); UI_block_end(C, block); UI_block_draw(C, block); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 07bdd337269..17539b2c423 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -153,9 +153,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* cache background */ ED_region_cache_draw_background(region); @@ -245,7 +243,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *region, MovieClip *clip } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* current frame */ x = (sc->user.framenr - sfra) / (efra - sfra + 1) * region->winx; @@ -330,9 +328,7 @@ static void draw_movieclip_buffer(const bContext *C, /* checkerboard for case alpha */ if (ibuf->planes == 32) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); imm_draw_box_checker_2d(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); } @@ -346,7 +342,7 @@ static void draw_movieclip_buffer(const bContext *C, ED_draw_imbuf_ctx(C, ibuf, x, y, use_filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y); if (ibuf->planes == 32) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (sc->flag & SC_SHOW_METADATA) { @@ -1212,9 +1208,7 @@ static void draw_plane_marker_image(Scene *scene, if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) { transparent = true; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } GPUTexture *texture = GPU_texture_create_nD(ibuf->x, @@ -1266,7 +1260,7 @@ static void draw_plane_marker_image(Scene *scene, GPU_texture_free(texture); if (transparent) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 277930495bd..4cf3e3e0798 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -192,7 +192,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint } /* Draw graph lines. */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); clip_graph_tracking_values_iterate(sc, (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0, (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0, @@ -200,7 +200,7 @@ static void draw_tracks_motion_and_error_curves(View2D *v2d, SpaceClip *sc, uint tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* Selected knot handles on top of curves. */ if (draw_knots) { diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 03f791ad70d..bcbf843f51c 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -415,9 +415,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) UI_view2d_view_ortho(v2d); /* currently clip editor supposes that editing clip length is equal to scene frame range */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -426,7 +424,7 @@ void clip_draw_sfra_efra(View2D *v2d, Scene *scene) immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax); immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUniformThemeColorShade(TH_BACK, -60); diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index d27b80efd40..18df8774e09 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -926,7 +926,6 @@ static void clip_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); /* data... */ movieclip_main_area_set_view2d(C, region); @@ -1054,7 +1053,6 @@ static void graph_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); @@ -1099,7 +1097,6 @@ static void dopesheet_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); @@ -1172,7 +1169,6 @@ static void clip_channels_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index 3a0125356f7..4b554e0c5c0 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -215,7 +215,6 @@ static void console_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); /* worlks best with no view2d matrix set */ UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 083d41747b3..7039eba7db1 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -267,7 +267,7 @@ static void file_draw_preview(uiBlock *block, xco = sx + (int)dx; yco = sy - layout->prv_h + (int)dy; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* the large image */ @@ -290,8 +290,7 @@ static void file_draw_preview(uiBlock *block, if (!is_icon && typeflags & FILE_TYPE_BLENDERLIB) { /* Datablock preview images use premultiplied alpha. */ - GPU_blend_set_func_separate( - GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA_PREMULT); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); @@ -309,8 +308,7 @@ static void file_draw_preview(uiBlock *block, 1.0f, col); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (icon && is_icon) { /* Small icon in the middle of large image, scaled to fit container and UI scale */ @@ -391,7 +389,7 @@ static void file_draw_preview(uiBlock *block, UI_but_drag_set_image(but, BLI_strdup(path), icon, imb, scale, true); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) @@ -443,7 +441,9 @@ static void draw_background(FileLayout *layout, View2D *v2d) uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - immUniformThemeColorShade(TH_BACK, -7); + float col_alternating[4]; + UI_GetThemeColor4fv(TH_ROW_ALTERNATE, col_alternating); + immUniformThemeColorBlend(TH_BACK, TH_ROW_ALTERNATE, col_alternating[3]); /* alternating flat shade background */ for (i = 2; (i <= layout->rows + 1); i += 2) { diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index e9ffd4583d7..8c4b2a1b8a6 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1722,7 +1722,11 @@ void FILE_OT_execute(struct wmOperatorType *ot) /* api callbacks */ ot->invoke = file_exec_invoke; ot->exec = file_exec; - ot->poll = file_operator_poll; + /* Important since handler is on window level. + * + * Avoid using #file_operator_poll since this is also used for entering directories + * which is used even when the file manager doesn't have an operator. */ + ot->poll = ED_operator_file_active; /* properties */ prop = RNA_def_boolean(ot->srna, @@ -2293,7 +2297,7 @@ static void file_expand_directory(bContext *C) } #else { - get_default_root(sfile->params->dir); + BLI_windows_get_default_root_dir(sfile->params->dir); } /* change "C:" --> "C:\", [#28102] */ else if ((isalpha(sfile->params->dir[0]) && (sfile->params->dir[1] == ':')) && diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 67ea22a7ef5..0ade50814e0 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1127,7 +1127,7 @@ static void parent_dir_until_exists_or_default_root(char *dir) { if (!BLI_path_parent_dir_until_exists(dir)) { #ifdef WIN32 - get_default_root(dir); + BLI_windows_get_default_root_dir(dir); #else strcpy(dir, "/"); #endif diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f520f91b89b..61d6d8bf678 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -449,7 +449,6 @@ static void file_main_region_draw(const bContext *C, ARegion *region) FileSelectParams *params = ED_fileselect_get_params(sfile); View2D *v2d = ®ion->v2d; - float col[3]; /* Needed, because filelist is not initialized on loading */ if (!sfile->files || filelist_empty(sfile->files)) { @@ -457,9 +456,7 @@ static void file_main_region_draw(const bContext *C, ARegion *region) } /* clear and setup matrix */ - UI_GetThemeColor3fv(TH_BACK, col); - GPU_clear_color(col[0], col[1], col[2], 1.0f); - GPU_clear(GPU_COLOR_BIT); + UI_ThemeClearColor(TH_BACK); /* Allow dynamically sliders to be set, saves notifiers etc. */ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index c358ba278e5..2a3985fdaa4 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -333,7 +333,7 @@ static void draw_fcurve_vertices(ARegion *region, uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); /* draw the two handles first (if they're shown, the curve doesn't @@ -346,7 +346,7 @@ static void draw_fcurve_vertices(ARegion *region, draw_fcurve_keyframe_vertices(fcu, v2d, !(fcu->flag & FCURVE_PROTECTED), pos); GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Handles ---------------- */ @@ -387,7 +387,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immBeginAtMost(GPU_PRIM_LINES, 4 * 2 * fcu->totvert); @@ -464,7 +464,7 @@ static void draw_fcurve_handles(SpaceGraph *sipo, FCurve *fcu) immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } @@ -517,7 +517,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu) if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -529,7 +529,7 @@ static void draw_fcurve_samples(SpaceGraph *sipo, ARegion *region, FCurve *fcu) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } @@ -945,7 +945,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1006,7 +1006,7 @@ static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAn if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* 2) draw handles and vertices as appropriate based on active @@ -1203,7 +1203,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(true); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1235,7 +1235,7 @@ void graph_draw_ghost_curves(bAnimContext *ac, SpaceGraph *sipo, ARegion *region if ((sipo->flag & SIPO_BEAUTYDRAW_OFF) == 0) { GPU_line_smooth(false); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* This is called twice from space_graph.c -> graph_main_region_draw() @@ -1322,9 +1322,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) float ymax = ACHANNEL_FIRST_TOP(ac); /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (ale = anim_data.first; ale; ale = ale->next, ymax -= ACHANNEL_STEP(ac), channel_index++) { float ymin = ymax - ACHANNEL_HEIGHT(ac); @@ -1342,7 +1340,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region) UI_block_end(C, block); UI_block_draw(C, block); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* free tempolary channels */ diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index a4f76384cc6..a1e75e2b9b2 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -200,12 +200,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) Scene *scene = CTX_data_scene(C); bAnimContext ac; View2D *v2d = ®ion->v2d; - float col[3]; /* clear and setup matrix */ - UI_GetThemeColor3fv(TH_BACK, col); - GPU_clear_color(col[0], col[1], col[2], 1.0f); - GPU_clear(GPU_COLOR_BIT); + UI_ThemeClearColor(TH_BACK); UI_view2d_view_ortho(v2d); @@ -249,7 +246,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) /* Draw a green line to indicate the cursor value */ immUniformThemeColorShadeAlpha(TH_CFRAME, -10, -50); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(2.0); immBegin(GPU_PRIM_LINES, 2); @@ -257,7 +254,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) immVertex2f(pos, v2d->cur.xmax, y); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* current frame or vertical component of vertical component of the cursor */ @@ -268,7 +265,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) /* to help differentiate this from the current frame, * draw slightly darker like the horizontal one */ immUniformThemeColorShadeAlpha(TH_CFRAME, -40, -50); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_width(2.0); immBegin(GPU_PRIM_LINES, 2); @@ -276,7 +273,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *region) immVertex2f(pos, x, v2d->cur.ymax); immEnd(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -358,12 +355,9 @@ static void graph_channel_region_draw(const bContext *C, ARegion *region) { bAnimContext ac; View2D *v2d = ®ion->v2d; - float col[3]; /* clear and setup matrix */ - UI_GetThemeColor3fv(TH_BACK, col); - GPU_clear_color(col[0], col[1], col[2], 1.0f); - GPU_clear(GPU_COLOR_BIT); + UI_ThemeClearColor(TH_BACK); UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index f70589ac5f1..058436a46bf 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -175,9 +175,7 @@ void ED_image_draw_info(Scene *scene, float hue = 0, sat = 0, val = 0, lum = 0, u = 0, v = 0; float col[4], finalcol[4]; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -189,7 +187,7 @@ void ED_image_draw_info(Scene *scene, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BLF_size(blf_mono_font, 11 * U.pixelsize, U.dpi); @@ -350,7 +348,7 @@ void ED_image_draw_info(Scene *scene, copy_v4_v4(finalcol, col); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); dx += 0.25f * UI_UNIT_X; BLI_rcti_init(&color_rect, @@ -389,10 +387,10 @@ void ED_image_draw_info(Scene *scene, immRecti(pos, color_quater_x, color_quater_y, color_rect_half.xmax, color_rect_half.ymax); immRecti(pos, color_rect_half.xmin, color_rect_half.ymin, color_quater_x, color_quater_y); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor3fvAlpha(finalcol, fp ? fp[3] : (cp[3] / 255.0f)); immRecti(pos, color_rect.xmin, color_rect.ymin, color_rect.xmax, color_rect.ymax); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { immUniformColor3fv(finalcol); @@ -525,7 +523,7 @@ static void sima_draw_zbuffloat_pixels(Scene *scene, GPU_shader_uniform_vector( state.shader, GPU_shader_get_uniform(state.shader, "shuffle"), 4, 1, red); - immDrawPixelsTex(&state, x1, y1, rectx, recty, GL_R16F, false, rectf, zoomx, zoomy, NULL); + immDrawPixelsTex(&state, x1, y1, rectx, recty, GPU_R16F, false, rectf, zoomx, zoomy, NULL); MEM_freeN(rectf); } @@ -540,9 +538,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab int x, y; UI_view2d_view_to_region(®ion->v2d, fx, fy, &x, &y); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); int textwidth = BLF_width(blf_mono_font, label, strlen(label)) + 10; float stepx = BLI_rcti_size_x(®ion->v2d.mask) / BLI_rctf_size_x(®ion->v2d.cur); @@ -560,7 +556,7 @@ static void draw_udim_label(ARegion *region, float fx, float fy, const char *lab BLF_position(blf_mono_font, (int)(x + 10), (int)(y + 10), 0); BLF_draw_ascii(blf_mono_font, label, strlen(label)); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_image_buffer(const bContext *C, @@ -602,9 +598,7 @@ static void draw_image_buffer(const bContext *C, if (sima_flag & SI_USE_ALPHA) { imm_draw_box_checker_2d(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* If RGBA display with color management */ @@ -662,7 +656,7 @@ static void draw_image_buffer(const bContext *C, } if (sima_flag & SI_USE_ALPHA) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -771,15 +765,13 @@ static void draw_image_paint_helpers( return; } - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex( &state, x, y, ibuf->x, ibuf->y, GPU_RGBA8, false, display_buffer, zoomx, zoomy, col); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); BKE_image_release_ibuf(brush->clone.image, ibuf, NULL); IMB_display_buffer_release(cache_handle); @@ -1058,9 +1050,7 @@ void draw_image_cache(const bContext *C, ARegion *region) const rcti *rect_visible = ED_region_visible_rect(region); const int region_bottom = rect_visible->ymin; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* Draw cache background. */ ED_region_cache_draw_background(region); @@ -1076,7 +1066,7 @@ void draw_image_cache(const bContext *C, ARegion *region) region, num_segments, points, sfra + sima->iuser.offset, efra + sima->iuser.offset); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* Draw current frame. */ x = (cfra - sfra) / (efra - sfra + 1) * region->winx; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index c01bc01588e..a806e3e25d1 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -642,7 +642,6 @@ static void image_main_region_draw(const bContext *C, ARegion *region) // View2DScrollers *scrollers; float col[3]; - GPU_batch_presets_reset(); GPUViewport *viewport = WM_draw_region_get_viewport(region); GPUFrameBuffer *framebuffer_default, *framebuffer_overlay; @@ -651,7 +650,6 @@ static void image_main_region_draw(const bContext *C, ARegion *region) GPU_framebuffer_bind(framebuffer_default); GPU_clear_color(0.0f, 0.0f, 0.0f, 0.0f); - GPU_clear(GPU_COLOR_BIT); GPU_framebuffer_bind(framebuffer_overlay); @@ -662,8 +660,7 @@ static void image_main_region_draw(const bContext *C, ARegion *region) UI_GetThemeColor3fv(TH_BACK, col); srgb_to_linearrgb_v3_v3(col, col); GPU_clear_color(col[0], col[1], col[2], 1.0f); - GPU_clear(GPU_COLOR_BIT); - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); image_user_refresh_scene(C, sima); @@ -837,9 +834,7 @@ static void image_buttons_region_layout(const bContext *C, ARegion *region) break; } - const bool vertical = true; - ED_region_panels_layout_ex( - C, region, ®ion->type->paneltypes, contexts_base, -1, vertical, NULL); + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, contexts_base, NULL); } static void image_buttons_region_draw(const bContext *C, ARegion *region) diff --git a/source/blender/editors/space_info/info_draw.c b/source/blender/editors/space_info/info_draw.c index 72533b88406..595da97c75a 100644 --- a/source/blender/editors/space_info/info_draw.c +++ b/source/blender/editors/space_info/info_draw.c @@ -147,7 +147,6 @@ static int report_textview_begin(TextViewContext *tvc) tvc->iter = reports->list.last; UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); tvc->iter_tmp = 0; if (tvc->iter && report_textview_skip__internal(tvc)) { diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 4e91da01cc9..301e88b0904 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -426,7 +426,7 @@ static bool format_stats(Main *bmain, if (wm->is_interface_locked) { return false; } - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); + Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer); stats_update(depsgraph, view_layer); } @@ -547,19 +547,20 @@ static void get_stats_string( info + *ofs, len - *ofs, TIP_(" | Objects:%s/%s"), stats_fmt->totobjsel, stats_fmt->totobj); } -const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) +static const char *info_statusbar_string(Main *bmain, + Scene *scene, + ViewLayer *view_layer, + char statusbar_flag) { char formatted_mem[15]; size_t ofs = 0; - char *info = screen->statusbar_info; - int len = sizeof(screen->statusbar_info); + static char info[256]; + int len = sizeof(info); info[0] = '\0'; /* Scene statistics. */ - if (U.statusbar_flag & STATUSBAR_SHOW_STATS) { - ViewLayer *view_layer = CTX_data_view_layer(C); - Scene *scene = CTX_data_scene(C); + if (statusbar_flag & STATUSBAR_SHOW_STATS) { SceneStatsFmt stats_fmt; if (format_stats(bmain, scene, view_layer, &stats_fmt)) { get_stats_string(info + ofs, len, &ofs, view_layer, &stats_fmt); @@ -567,7 +568,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Memory status. */ - if (U.statusbar_flag & STATUSBAR_SHOW_MEMORY) { + if (statusbar_flag & STATUSBAR_SHOW_MEMORY) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -577,7 +578,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* GPU VRAM status. */ - if ((U.statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { + if ((statusbar_flag & STATUSBAR_SHOW_VRAM) && (GPU_mem_stats_supported())) { int gpu_free_mem_kb, gpu_tot_mem_kb; GPU_mem_stats_get(&gpu_tot_mem_kb, &gpu_free_mem_kb); float gpu_total_gb = gpu_tot_mem_kb / 1048576.0f; @@ -599,7 +600,7 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) } /* Blender version. */ - if (U.statusbar_flag & STATUSBAR_SHOW_VERSION) { + if (statusbar_flag & STATUSBAR_SHOW_VERSION) { if (info[0]) { ofs += BLI_snprintf(info + ofs, len - ofs, " | "); } @@ -609,6 +610,20 @@ const char *ED_info_statusbar_string(Main *bmain, bScreen *screen, bContext *C) return info; } +const char *ED_info_statusbar_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + return info_statusbar_string(bmain, scene, view_layer, U.statusbar_flag); +} + +const char *ED_info_statistics_string(Main *bmain, Scene *scene, ViewLayer *view_layer) +{ + const eUserpref_StatusBar_Flag statistics_status_bar_flag = STATUSBAR_SHOW_STATS | + STATUSBAR_SHOW_MEMORY | + STATUSBAR_SHOW_VERSION; + + return info_statusbar_string(bmain, scene, view_layer, statistics_status_bar_flag); +} + static void stats_row(int col1, const char *key, int col2, diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index b9153ec0cbd..8d3f21aefeb 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -142,7 +142,6 @@ static void info_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); /* quick way to avoid drawing if not bug enough */ if (region->winy < 16) { diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 93a79d9a2bc..4d9a4fb2706 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -84,9 +84,7 @@ static void textview_draw_sel(const char *str, const int sta = BLI_str_utf8_offset_to_column(str, max_ii(sel[0], 0)); const int end = BLI_str_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw)); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); @@ -97,7 +95,7 @@ static void textview_draw_sel(const char *str, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -240,7 +238,7 @@ static bool textview_draw_string(TextViewDrawState *tds, int vpadding = (tds->lheight + (tds->row_vpadding * 2) - UI_DPI_ICON_SIZE) / 2; int hpadding = tds->draw_rect->xmin - (UI_DPI_ICON_SIZE * 1.3f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_icon_draw_ex(hpadding, line_top - UI_DPI_ICON_SIZE - vpadding, icon, @@ -249,7 +247,7 @@ static bool textview_draw_string(TextViewDrawState *tds, 0.0f, icon_fg, false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } tds->xy[1] += tds->row_vpadding; diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 97939a93d01..b0d5360e29b 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -321,7 +321,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin /* draw with AA'd line */ GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* influence -------------------------- */ if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) { @@ -374,7 +374,7 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uin /* turn off AA'd lines */ GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* helper call to setup dashed-lines for strip outlines */ @@ -434,9 +434,7 @@ static void nla_draw_strip(SpaceNla *snla, */ if ((strip->extendmode != NLASTRIP_EXTEND_NOTHING) && (non_solo == 0)) { /* enable transparency... */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); switch (strip->extendmode) { /* since this does both sides, @@ -468,7 +466,7 @@ static void nla_draw_strip(SpaceNla *snla, break; } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw 'inside' of strip itself */ @@ -487,9 +485,9 @@ static void nla_draw_strip(SpaceNla *snla, /* strip is in disabled track - make less visible */ immUniformColor3fvAlpha(color, 0.1f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos, strip->start, yminc, strip->end, ymaxc); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* draw strip's control 'curves' @@ -746,9 +744,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region) /* just draw a semi-shaded rect spanning the width of the viewable area if there's data, * and a second darker rect within which we draw keyframe indicator dots if there's data */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* get colors for drawing */ float color[4]; @@ -790,7 +786,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region) nla_action_draw_keyframes( v2d, adt, ale->data, ycenter, ymin + NLACHANNEL_SKIP, ymax - NLACHANNEL_SKIP); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); break; } } @@ -854,9 +850,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region) float ymax = NLACHANNEL_FIRST_TOP(ac); /* set blending again, as may not be set in previous step */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* loop through channels, and set up drawing depending on their type */ for (ale = anim_data.first; ale; @@ -876,7 +870,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *region) UI_block_end(C, block); UI_block_draw(C, block); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* free temporary channels */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index bc9bd0e18f2..dc8f616c5e6 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -1847,11 +1847,7 @@ static int nlaedit_sync_actlen_exec(bContext *C, wmOperator *op) continue; } - /* recalculate the length of the action */ - calc_action_range(strip->act, &strip->actstart, &strip->actend, 0); - - /* adjust the strip extents in response to this */ - BKE_nlastrip_recalculate_bounds(strip); + BKE_nlastrip_recalculate_bounds_sync_action(strip); ale->update |= ANIM_UPDATE_DEPS; } diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 7bbfe451eed..7a0cd35ece1 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -194,7 +194,6 @@ static void nla_channel_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); @@ -238,7 +237,6 @@ static void nla_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 37daa881317..5866b5cc12f 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -456,7 +456,6 @@ static void node_draw_frame(const bContext *C, bNodeInstanceKey UNUSED(key)) { rctf *rct = &node->totr; - int color_id = node_get_colorid(node); float color[4]; float alpha; @@ -499,8 +498,6 @@ static void node_draw_frame(const bContext *C, /* label */ node_draw_frame_label(ntree, node, snode->aspect); - UI_ThemeClearColor(color_id); - UI_block_end(C, node->block); UI_block_draw(C, node->block); node->block = NULL; @@ -602,7 +599,7 @@ static void node_draw_reroute(const bContext *C, /* outline active and selected emphasis */ if (node->flag & SELECT) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); /* using different shades of TH_TEXT_HI for the empasis, like triangle */ if (node->flag & NODE_ACTIVE) { @@ -614,7 +611,7 @@ static void node_draw_reroute(const bContext *C, UI_draw_roundbox_4fv(false, rct->xmin, rct->ymin, rct->xmax, rct->ymax, size, debug_color); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } #endif @@ -3688,13 +3685,11 @@ void draw_nodespace_back_pix(const bContext *C, GPU_shader_unbind(); } else if (snode->flag & SNODE_USE_ALPHA) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else { ED_draw_imbuf_ctx(C, ibuf, x, y, false, snode->zoom, snode->zoom); @@ -4013,7 +4008,7 @@ static void nodelink_batch_draw(SpaceNode *snode) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); float colors[6][4] = {{0.0f}}; UI_GetThemeColor4fv(TH_WIRE_INNER, colors[nodelink_get_color_id(TH_WIRE_INNER)]); @@ -4026,14 +4021,14 @@ static void nodelink_batch_draw(SpaceNode *snode) GPU_vertbuf_use(g_batch_link.inst_vbo); /* force update. */ GPU_batch_program_set_builtin(g_batch_link.batch, GPU_SHADER_2D_NODELINK_INST); - GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, (float *)colors); + GPU_batch_uniform_4fv_array(g_batch_link.batch, "colors", 6, colors); GPU_batch_uniform_1f(g_batch_link.batch, "expandSize", snode->aspect * LINK_WIDTH); GPU_batch_uniform_1f(g_batch_link.batch, "arrowSize", ARROW_SIZE); GPU_batch_draw(g_batch_link.batch); nodelink_batch_reset(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void nodelink_batch_start(SpaceNode *UNUSED(snode)) @@ -4108,8 +4103,8 @@ void node_draw_link_bezier( GPUBatch *batch = g_batch_link.batch_single; GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_NODELINK); - GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, (float *)vec); - GPU_batch_uniform_4fv_array(batch, "colors", 3, (float *)colors); + GPU_batch_uniform_2fv_array(batch, "bezierPts", 4, vec); + GPU_batch_uniform_4fv_array(batch, "colors", 3, colors); GPU_batch_uniform_1f(batch, "expandSize", snode->aspect * LINK_WIDTH); GPU_batch_uniform_1f(batch, "arrowSize", ARROW_SIZE); GPU_batch_uniform_1i(batch, "doArrow", drawarrow); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 3fd0b0a5a58..56e53e79a8d 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -52,6 +52,7 @@ #include "GPU_immediate_util.h" #include "GPU_matrix.h" #include "GPU_state.h" +#include "GPU_viewport.h" #include "WM_api.h" #include "WM_types.h" @@ -690,13 +691,13 @@ static void node_draw_mute_line(View2D *v2d, SpaceNode *snode, bNode *node) { bNodeLink *link; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); for (link = node->internal_links.first; link; link = link->next) { node_draw_link_bezier(v2d, snode, link, TH_REDALERT, TH_REDALERT, -1); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* flags used in gpu_shader_keyframe_diamond_frag.glsl */ @@ -834,8 +835,8 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ uint outline_col_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - gpuPushAttr(GPU_BLEND_BIT); - GPU_blend(true); + eGPUBlend state = GPU_blend_get(); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); @@ -859,53 +860,27 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ immUnbindProgram(); GPU_program_point_size(false); - gpuPopAttr(); + + /* Restore. */ + GPU_blend(state); } /* ************** Socket callbacks *********** */ -static void node_draw_preview_background(float tile, rctf *rect) +static void node_draw_preview_background(rctf *rect) { - float x, y; - GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + immBindBuiltinProgram(GPU_SHADER_2D_CHECKER); - /* draw checkerboard backdrop to show alpha */ - immUniformColor3ub(120, 120, 120); + /* Drawing the checkerboard. */ + const float checker_dark = UI_ALPHA_CHECKER_DARK / 255.0f; + const float checker_light = UI_ALPHA_CHECKER_LIGHT / 255.0f; + immUniform4f("color1", checker_dark, checker_dark, checker_dark, 1.0f); + immUniform4f("color2", checker_light, checker_light, checker_light, 1.0f); + immUniform1i("size", 8); immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax); - immUniformColor3ub(160, 160, 160); - - for (y = rect->ymin; y < rect->ymax; y += tile * 2) { - for (x = rect->xmin; x < rect->xmax; x += tile * 2) { - float tilex = tile, tiley = tile; - - if (x + tile > rect->xmax) { - tilex = rect->xmax - x; - } - if (y + tile > rect->ymax) { - tiley = rect->ymax - y; - } - - immRectf(pos, x, y, x + tilex, y + tiley); - } - } - for (y = rect->ymin + tile; y < rect->ymax; y += tile * 2) { - for (x = rect->xmin + tile; x < rect->xmax; x += tile * 2) { - float tilex = tile, tiley = tile; - - if (x + tile > rect->xmax) { - tilex = rect->xmax - x; - } - if (y + tile > rect->ymax) { - tiley = rect->ymax - y; - } - - immRectf(pos, x, y, x + tilex, y + tiley); - } - } immUnbindProgram(); } @@ -934,12 +909,11 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) scale = yscale; } - node_draw_preview_background(BLI_rctf_size_x(prv) / 10.0f, &draw_rect); + node_draw_preview_background(&draw_rect); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* premul graphics */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); immDrawPixelsTex(&state, @@ -954,7 +928,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) scale, NULL); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -978,23 +952,8 @@ static void node_toggle_button_cb(struct bContext *C, void *node_argv, void *op_ void node_draw_shadow(SpaceNode *snode, bNode *node, float radius, float alpha) { rctf *rct = &node->totr; - UI_draw_roundbox_corner_set(UI_CNR_ALL); - if (node->parent == NULL) { - ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); - } - else { - const float margin = 3.0f; - - const float color[4] = {0.0f, 0.0f, 0.0f, 0.33f}; - UI_draw_roundbox_aa(true, - rct->xmin - margin, - rct->ymin - margin, - rct->xmax + margin, - rct->ymax + margin, - radius + margin, - color); - } + ui_draw_dropshadow(rct, radius, snode->aspect, alpha, node->flag & SELECT); } void node_draw_sockets(View2D *v2d, @@ -1024,7 +983,7 @@ void node_draw_sockets(View2D *v2d, uint outline_col_id = GPU_vertformat_attr_add( format, "outlineColor", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); immUniform1f("outline_scale", 0.7f); @@ -1158,7 +1117,7 @@ void node_draw_sockets(View2D *v2d, immUnbindProgram(); GPU_program_point_size(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void node_draw_basis(const bContext *C, @@ -1384,8 +1343,6 @@ static void node_draw_basis(const bContext *C, } } - UI_ThemeClearColor(color_id); - UI_block_end(C, node->block); UI_block_draw(C, node->block); node->block = NULL; @@ -1434,7 +1391,7 @@ static void node_draw_hidden(const bContext *C, /* custom color inline */ if (node->flag & NODE_CUSTOM_COLOR) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); UI_draw_roundbox_3fv_alpha(false, @@ -1447,7 +1404,7 @@ static void node_draw_hidden(const bContext *C, 1.0f); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* title */ @@ -1681,7 +1638,7 @@ void node_draw_nodetree(const bContext *C, } /* node lines */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); nodelink_batch_start(snode); for (link = ntree->links.first; link; link = link->next) { if (!nodeLinkIsHidden(link)) { @@ -1689,7 +1646,7 @@ void node_draw_nodetree(const bContext *C, } } nodelink_batch_end(snode); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* draw foreground nodes, last nodes in front */ for (a = 0, node = ntree->nodes.first; node; node = node->next, a++) { @@ -1750,12 +1707,12 @@ static void draw_group_overlay(const bContext *C, ARegion *region) float color[4]; /* shade node groups to separate them visually */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_GetThemeColorShadeAlpha4fv(TH_NODE_GROUP, 0, 0, color); UI_draw_roundbox_corner_set(UI_CNR_NONE); UI_draw_roundbox_4fv(true, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 0, color); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* set the block bounds to clip mouse events from underlying nodes */ block = UI_block_begin(C, region, "node tree bounds block", UI_EMBOSS); @@ -1770,10 +1727,16 @@ void drawnodespace(const bContext *C, ARegion *region) SpaceNode *snode = CTX_wm_space_node(C); View2D *v2d = ®ion->v2d; - UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); UI_view2d_view_ortho(v2d); + UI_ThemeClearColor(TH_BACK); + GPU_depth_test(GPU_DEPTH_NONE); + GPU_scissor_test(true); /* XXX snode->cursor set in coordspace for placing new nodes, used for drawing noodles too */ UI_view2d_region_to_view(®ion->v2d, @@ -1789,8 +1752,7 @@ void drawnodespace(const bContext *C, ARegion *region) ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW); /* only set once */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); /* nodes */ snode_set_context(C); @@ -1876,7 +1838,7 @@ void drawnodespace(const bContext *C, ARegion *region) } /* temporary links */ - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); for (nldrag = snode->linkdrag.first; nldrag; nldrag = nldrag->next) { for (linkdata = nldrag->links.first; linkdata; linkdata = linkdata->next) { @@ -1884,7 +1846,7 @@ void drawnodespace(const bContext *C, ARegion *region) } } GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); if (snode->flag & SNODE_SHOW_GPENCIL) { /* draw grease-pencil ('canvas' strokes) */ diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c88b6a1b297..ef931dd9bb8 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -207,12 +207,11 @@ static void compo_initjob(void *cjv) ViewLayer *view_layer = cj->view_layer; cj->compositor_depsgraph = DEG_graph_new(bmain, scene, view_layer, DAG_EVAL_RENDER); - DEG_graph_build_for_compositor_preview( - cj->compositor_depsgraph, bmain, scene, view_layer, cj->ntree); + DEG_graph_build_for_compositor_preview(cj->compositor_depsgraph, cj->ntree); /* NOTE: Don't update animation to preserve unkeyed changes, this means can not use * evaluate_on_framechange. */ - DEG_evaluate_on_refresh(bmain, cj->compositor_depsgraph); + DEG_evaluate_on_refresh(cj->compositor_depsgraph); bNodeTree *ntree_eval = (bNodeTree *)DEG_get_evaluated_id(cj->compositor_depsgraph, &cj->ntree->id); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 4f15cec8c84..654bb94cc78 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -281,7 +281,9 @@ static void node_socket_add_replace(const bContext *C, /* also preserve mapping for texture nodes */ if (node_from->typeinfo->nclass == NODE_CLASS_TEXTURE && - node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE) { + node_prev->typeinfo->nclass == NODE_CLASS_TEXTURE && + /* White noise texture node does not have NodeTexBase. */ + node_from->storage != NULL && node_prev->storage != NULL) { memcpy(node_from->storage, node_prev->storage, sizeof(NodeTexBase)); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 28e233b6dd2..fbef3aa07d7 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -182,7 +182,7 @@ static void restrictbutton_bone_visibility_fn(bContext *C, void *poin, void *UNU { Bone *bone = (Bone *)poin; - if (CTX_wm_window(C)->eventstate->ctrl) { + if (CTX_wm_window(C)->eventstate->shift) { restrictbutton_recursive_bone(bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0); } } @@ -194,7 +194,7 @@ static void restrictbutton_bone_select_fn(bContext *C, void *UNUSED(poin), void bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - if (CTX_wm_window(C)->eventstate->ctrl) { + if (CTX_wm_window(C)->eventstate->shift) { restrictbutton_recursive_bone(bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0); } @@ -209,7 +209,7 @@ static void restrictbutton_ebone_select_fn(bContext *C, void *UNUSED(poin), void ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - if (CTX_wm_window(C)->eventstate->ctrl) { + if (CTX_wm_window(C)->eventstate->shift) { restrictbutton_recursive_ebone( C, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0); } @@ -224,7 +224,7 @@ static void restrictbutton_ebone_visibility_fn(bContext *C, void *UNUSED(poin), ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - if (CTX_wm_window(C)->eventstate->ctrl) { + if (CTX_wm_window(C)->eventstate->shift) { restrictbutton_recursive_ebone(C, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0); } @@ -1300,7 +1300,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, 0, -1, -1, - TIP_("Restrict visibility in the 3D View")); + TIP_("Restrict visibility in the 3D View\n" + "* Shift to set children")); UI_but_func_set(bt, restrictbutton_bone_visibility_fn, bone, NULL); UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE); @@ -1321,7 +1322,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, 0, 0, 0, - TIP_("Restrict selection in the 3D View")); + TIP_("Restrict selection in the 3D View\n" + "* Shift to set children")); UI_but_func_set(bt, restrictbutton_bone_select_fn, ob->data, bone); UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE); @@ -1345,7 +1347,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, 0, 0, 0, - TIP_("Restrict visibility in the 3D View")); + TIP_("Restrict visibility in the 3D View\n" + "* Shift to set children")); UI_but_func_set(bt, restrictbutton_ebone_visibility_fn, NULL, ebone); UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE); @@ -1366,7 +1369,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, 0, 0, 0, - TIP_("Restrict selection in the 3D View")); + TIP_("Restrict selection in the 3D View\n" + "* Shift to set children")); UI_but_func_set(bt, restrictbutton_ebone_select_fn, NULL, ebone); UI_but_flag_enable(bt, UI_BUT_DRAG_LOCK); UI_but_drawflag_enable(bt, UI_BUT_ICON_REVERSE); @@ -2188,7 +2192,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) GpencilModifierData *md = BLI_findlink(&ob->greasepencil_modifiers, tselem->nr); switch ((GpencilModifierType)md->type) { case eGpencilModifierType_Noise: - data.icon = ICON_RNDCURVE; + data.icon = ICON_MOD_NOISE; break; case eGpencilModifierType_Subdiv: data.icon = ICON_MOD_SUBSURF; @@ -2232,6 +2236,15 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) case eGpencilModifierType_Armature: data.icon = ICON_MOD_ARMATURE; break; + case eGpencilModifierType_Multiply: + data.icon = ICON_GP_MULTIFRAME_EDITING; + break; + case eGpencilModifierType_Time: + data.icon = ICON_MOD_TIME; + break; + case eGpencilModifierType_Texture: + data.icon = ICON_TEXTURE; + break; /* Default */ default: @@ -2354,6 +2367,11 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) data.icon = ICON_OUTLINER_DATA_GP_LAYER; break; } + case TSE_GPENCIL_EFFECT_BASE: + case TSE_GPENCIL_EFFECT: + data.drag_id = tselem->id; + data.icon = ICON_SHADERFX; + break; default: data.icon = ICON_DOT; break; @@ -2729,7 +2747,7 @@ static void outliner_draw_iconrow_number(const uiFontStyle *fstyle, number_text, text_col); UI_fontstyle_set(fstyle); - GPU_blend(true); /* Roundbox and text drawing disables. */ + GPU_blend(GPU_BLEND_ALPHA); /* Roundbox and text drawing disables. */ } static void outliner_icon_background_colors(float icon_color[4], float icon_border[4]) @@ -2743,6 +2761,23 @@ static void outliner_icon_background_colors(float icon_color[4], float icon_bord icon_border[3] = 0.2f; } +/* Draw a rounded rectangle behind icons of active elements. */ +static void outliner_draw_active_indicator(const float minx, + const float miny, + const float maxx, + const float maxy, + const float icon_color[4], + const float icon_border[4]) +{ + const float ufac = UI_UNIT_X / 20.0f; + const float radius = UI_UNIT_Y / 4.0f; + + UI_draw_roundbox_corner_set(UI_CNR_ALL); + UI_draw_roundbox_aa(true, minx, miny + ufac, maxx, maxy - ufac, radius, icon_color); + UI_draw_roundbox_aa(false, minx, miny + ufac, maxx, maxy - ufac, radius, icon_border); + GPU_blend(GPU_BLEND_ALPHA); /* Roundbox disables. */ +} + static void outliner_draw_iconrow_doit(uiBlock *block, TreeElement *te, const uiFontStyle *fstyle, @@ -2756,31 +2791,19 @@ static void outliner_draw_iconrow_doit(uiBlock *block, TreeStoreElem *tselem = TREESTORE(te); if (active != OL_DRAWSEL_NONE) { - float ufac = UI_UNIT_X / 20.0f; float icon_color[4], icon_border[4]; outliner_icon_background_colors(icon_color, icon_border); if (active == OL_DRAWSEL_ACTIVE) { UI_GetThemeColor4fv(TH_EDITED_OBJECT, icon_color); icon_border[3] = 0.3f; } - UI_draw_roundbox_corner_set(UI_CNR_ALL); - - UI_draw_roundbox_aa(true, - (float)*offsx, - (float)ys + ufac, - (float)*offsx + UI_UNIT_X, - (float)ys + UI_UNIT_Y - ufac, - (float)UI_UNIT_Y / 4.0f, - icon_color); - /* border around it */ - UI_draw_roundbox_aa(false, - (float)*offsx, - (float)ys + ufac, - (float)*offsx + UI_UNIT_X, - (float)ys + UI_UNIT_Y - ufac, - (float)UI_UNIT_Y / 4.0f, - icon_border); - GPU_blend(true); /* Roundbox disables. */ + + outliner_draw_active_indicator((float)*offsx, + (float)ys, + (float)*offsx + UI_UNIT_X, + (float)ys + UI_UNIT_Y, + icon_color, + icon_border); } if (tselem->flag & TSE_HIGHLIGHTED) { @@ -2981,7 +3004,7 @@ static void outliner_draw_tree_element(bContext *C, xmax -= restrict_column_width + UI_UNIT_X; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* colors for active/selected data */ if (tselem->type == 0) { @@ -3052,23 +3075,12 @@ static void outliner_draw_tree_element(bContext *C, /* active circle */ if (active != OL_DRAWSEL_NONE) { - UI_draw_roundbox_corner_set(UI_CNR_ALL); - UI_draw_roundbox_aa(true, - (float)startx + offsx + UI_UNIT_X, - (float)*starty + ufac, - (float)startx + offsx + 2.0f * UI_UNIT_X, - (float)*starty + UI_UNIT_Y - ufac, - UI_UNIT_Y / 4.0f, - icon_bgcolor); - /* border around it */ - UI_draw_roundbox_aa(false, - (float)startx + offsx + UI_UNIT_X, - (float)*starty + ufac, - (float)startx + offsx + 2.0f * UI_UNIT_X, - (float)*starty + UI_UNIT_Y - ufac, - UI_UNIT_Y / 4.0f, - icon_border); - GPU_blend(true); /* roundbox disables it */ + outliner_draw_active_indicator((float)startx + offsx + UI_UNIT_X, + (float)*starty, + (float)startx + offsx + 2.0f * UI_UNIT_X, + (float)*starty + UI_UNIT_Y, + icon_bgcolor, + icon_border); te->flag |= TE_ACTIVE; /* For lookup in display hierarchies. */ } @@ -3116,7 +3128,7 @@ static void outliner_draw_tree_element(bContext *C, offsx += UI_UNIT_X + 4 * ufac; } } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* name */ if ((tselem->flag & TSE_TEXTBUT) == 0) { @@ -3140,7 +3152,7 @@ static void outliner_draw_tree_element(bContext *C, else if (tselem->type != TSE_R_LAYER) { int tempx = startx + offsx; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); MergedIconRow merged = {{0}}; outliner_draw_iconrow(C, @@ -3156,7 +3168,7 @@ static void outliner_draw_tree_element(bContext *C, alpha_fac, &merged); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -3315,9 +3327,9 @@ static void outliner_draw_hierarchy_lines(SpaceOutliner *space_outliner, UI_GetThemeColorBlend3ubv(TH_BACK, TH_TEXT, 0.4f, col); col[3] = 255; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); outliner_draw_hierarchy_lines_recursive(pos, space_outliner, lb, startx, col, false, starty); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } @@ -3464,7 +3476,7 @@ static void outliner_draw_highlights(ARegion *region, UI_GetThemeColor4fv(TH_MATCH, col_searchmatch); col_searchmatch[3] = 0.5f; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -3479,7 +3491,7 @@ static void outliner_draw_highlights(ARegion *region, startx, starty); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void outliner_draw_tree(bContext *C, @@ -3493,8 +3505,7 @@ static void outliner_draw_tree(bContext *C, const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; int starty, startx; - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); /* Only once. */ + GPU_blend(GPU_BLEND_ALPHA); /* Only once. */ if (space_outliner->outlinevis == SO_DATA_API) { /* struct marks */ @@ -3508,12 +3519,12 @@ static void outliner_draw_tree(bContext *C, outliner_draw_highlights(region, space_outliner, startx, &starty); /* set scissor so tree elements or lines can't overlap restriction icons */ - float scissor[4] = {0}; + int scissor[4] = {0}; if (restrict_column_width > 0.0f) { int mask_x = BLI_rcti_size_x(®ion->v2d.mask) - (int)restrict_column_width + 1; CLAMP_MIN(mask_x, 0); - GPU_scissor_get_f(scissor); + GPU_scissor_get(scissor); GPU_scissor(0, 0, mask_x, region->winy); } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index cd2fcd8e2cf..ad7346a5651 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -150,9 +150,22 @@ void OUTLINER_OT_highlight_update(wmOperatorType *ot) * \{ */ /* Open or close a tree element, optionally toggling all children recursively */ -void outliner_item_openclose(TreeElement *te, bool open, bool toggle_all) -{ +void outliner_item_openclose(SpaceOutliner *space_outliner, + TreeElement *te, + bool open, + bool toggle_all) +{ + /* Prevent opening leaf elements in the tree unless in the Data API display mode because in that + * mode subtrees are empty unless expanded. */ + if (space_outliner->outlinevis != SO_DATA_API && BLI_listbase_is_empty(&te->subtree)) { + return; + } + + /* Don't allow collapsing the scene collection. */ TreeStoreElem *tselem = TREESTORE(te); + if (tselem->type == TSE_VIEW_COLLECTION_BASE) { + return; + } if (open) { tselem->flag &= ~TSE_CLOSED; @@ -191,15 +204,9 @@ static int outliner_item_openclose_modal(bContext *C, wmOperator *op, const wmEv /* Only toggle openclose on the same level as the first clicked element */ if (te->xs == data->x_location) { - outliner_item_openclose(te, data->open, false); + outliner_item_openclose(space_outliner, te, data->open, false); - /* Avoid rebuild if possible. */ - if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) { - ED_region_tag_redraw(region); - } - else { - ED_region_tag_redraw_no_rebuild(region); - } + outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region); } } @@ -238,14 +245,8 @@ static int outliner_item_openclose_invoke(bContext *C, wmOperator *op, const wmE const bool open = (tselem->flag & TSE_CLOSED) || (toggle_all && (outliner_flag_is_any_test(&te->subtree, TSE_CLOSED, 1))); - outliner_item_openclose(te, open, toggle_all); - /* Avoid rebuild if possible. */ - if (outliner_element_needs_rebuild_on_open_change(TREESTORE(te))) { - ED_region_tag_redraw(region); - } - else { - ED_region_tag_redraw_no_rebuild(region); - } + outliner_item_openclose(space_outliner, te, open, toggle_all); + outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region); /* Only toggle once for single click toggling */ if (event->type == LEFTMOUSE) { diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 33dbbb274c0..bd283777397 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -237,7 +237,7 @@ void outliner_build_tree(struct Main *mainvar, struct SpaceOutliner *space_outliner, struct ARegion *region); -bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem); +bool outliner_mode_requires_always_rebuild(const struct SpaceOutliner *space_outliner); typedef struct IDsSelectedData { struct ListBase selected_array; @@ -374,7 +374,10 @@ void item_object_mode_exit_fn(struct bContext *C, void outliner_set_coordinates(struct ARegion *region, struct SpaceOutliner *space_outliner); -void outliner_item_openclose(TreeElement *te, bool open, bool toggle_all); +void outliner_item_openclose(struct SpaceOutliner *space_outliner, + TreeElement *te, + bool open, + bool toggle_all); /* outliner_dragdrop.c */ void outliner_dropboxes(void); @@ -515,6 +518,8 @@ float outliner_restrict_columns_width(const struct SpaceOutliner *space_outliner TreeElement *outliner_find_element_with_flag(const ListBase *lb, short flag); bool outliner_is_element_visible(const TreeElement *te); void outliner_scroll_view(struct ARegion *region, int delta_y); +void outliner_tag_redraw_avoid_rebuild_on_open_change(const struct SpaceOutliner *space_outliner, + struct ARegion *region); /* outliner_sync.c ---------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 1ac1b46f0d1..266ea293d43 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -46,6 +46,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_paint.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_sequencer.h" #include "BKE_workspace.h" @@ -193,12 +194,17 @@ static void do_outliner_item_posemode_toggle( } else { bool ok = false; - if (ob->mode & OB_MODE_POSE) { + + if (ID_IS_LINKED(ob)) { + BKE_report(CTX_wm_reports(C), RPT_WARNING, "Cannot pose libdata"); + } + else if (ob->mode & OB_MODE_POSE) { ok = ED_object_posemode_exit_ex(bmain, ob); } else { ok = ED_object_posemode_enter_ex(bmain, ob); } + if (ok) { ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT); @@ -1000,7 +1006,9 @@ static eOLDrawState tree_element_active_master_collection(bContext *C, ViewLayer *view_layer = CTX_data_view_layer(C); LayerCollection *layer_collection = view_layer->layer_collections.first; BKE_layer_collection_activate(view_layer, layer_collection); - WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work + * when only the active collection changes. */ + WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL); } return OL_DRAWSEL_NONE; @@ -1022,7 +1030,9 @@ static eOLDrawState tree_element_active_layer_collection(bContext *C, LayerCollection *layer_collection = te->directdata; ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection); BKE_layer_collection_activate(view_layer, layer_collection); - WM_main_add_notifier(NC_SCENE | ND_LAYER, NULL); + /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work + * when only the active collection changes. */ + WM_main_add_notifier(NC_SCENE | ND_LAYER | NS_LAYER_COLLECTION | NA_ACTIVATED, NULL); } return OL_DRAWSEL_NONE; @@ -1507,7 +1517,7 @@ static int outliner_box_select_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - ED_region_tag_redraw(region); + ED_region_tag_redraw_no_rebuild(region); ED_outliner_select_sync_from_outliner(C, space_outliner); @@ -1630,6 +1640,40 @@ static TreeElement *outliner_find_next_element(SpaceOutliner *space_outliner, Tr return te; } +static TreeElement *outliner_walk_left(SpaceOutliner *space_outliner, + TreeElement *te, + bool toggle_all) +{ + TreeStoreElem *tselem = TREESTORE(te); + + if (TSELEM_OPEN(tselem, space_outliner)) { + outliner_item_openclose(space_outliner, te, false, toggle_all); + } + /* Only walk up a level if the element is closed and not toggling expand */ + else if (!toggle_all && te->parent) { + te = te->parent; + } + + return te; +} + +static TreeElement *outliner_walk_right(SpaceOutliner *space_outliner, + TreeElement *te, + bool toggle_all) +{ + TreeStoreElem *tselem = TREESTORE(te); + + /* Only walk down a level if the element is open and not toggling expand */ + if (!toggle_all && TSELEM_OPEN(tselem, space_outliner) && !BLI_listbase_is_empty(&te->subtree)) { + te = te->subtree.first; + } + else { + outliner_item_openclose(space_outliner, te, true, toggle_all); + } + + return te; +} + static TreeElement *do_outliner_select_walk(SpaceOutliner *space_outliner, TreeElement *te, const int direction, @@ -1646,10 +1690,10 @@ static TreeElement *do_outliner_select_walk(SpaceOutliner *space_outliner, te = outliner_find_next_element(space_outliner, te); break; case UI_SELECT_WALK_LEFT: - outliner_item_openclose(te, false, toggle_all); + te = outliner_walk_left(space_outliner, te, toggle_all); break; case UI_SELECT_WALK_RIGHT: - outliner_item_openclose(te, true, toggle_all); + te = outliner_walk_right(space_outliner, te, toggle_all); break; } @@ -1729,7 +1773,7 @@ static int outliner_walk_select_invoke(bContext *C, wmOperator *op, const wmEven outliner_walk_scroll(region, active_te); ED_outliner_select_sync_from_outliner(C, space_outliner); - ED_region_tag_redraw(region); + outliner_tag_redraw_avoid_rebuild_on_open_change(space_outliner, region); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 6532ff189b5..2a13f9d6a66 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -792,10 +792,11 @@ static void id_override_library_create_fn(bContext *C, } else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) { BKE_lib_override_library_create_from_id(bmain, id_root, true); - } - BKE_main_id_clear_newpoins(bmain); - BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + /* Cleanup. */ + BKE_main_id_clear_newpoins(bmain); + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + } } } @@ -827,6 +828,68 @@ static void id_override_library_reset_fn(bContext *C, } } +static void id_override_library_resync_fn(bContext *C, + ReportList *UNUSED(reports), + Scene *scene, + TreeElement *te, + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *UNUSED(user_data)) +{ + BLI_assert(TSE_IS_REAL_ID(tselem)); + ID *id_root = tselem->id; + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + Main *bmain = CTX_data_main(C); + + id_root->tag |= LIB_TAG_DOIT; + + /* Tag all linked parents in tree hierarchy to be also overridden. */ + while ((te = te->parent) != NULL) { + if (!TSE_IS_REAL_ID(te->store_elem)) { + continue; + } + if (!ID_IS_OVERRIDE_LIBRARY_REAL(te->store_elem->id)) { + break; + } + te->store_elem->id->tag |= LIB_TAG_DOIT; + } + + BKE_lib_override_library_resync(bmain, scene, CTX_data_view_layer(C), id_root); + } +} + +static void id_override_library_delete_fn(bContext *C, + ReportList *UNUSED(reports), + Scene *UNUSED(scene), + TreeElement *te, + TreeStoreElem *UNUSED(tsep), + TreeStoreElem *tselem, + void *UNUSED(user_data)) +{ + BLI_assert(TSE_IS_REAL_ID(tselem)); + ID *id_root = tselem->id; + + if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { + Main *bmain = CTX_data_main(C); + + id_root->tag |= LIB_TAG_DOIT; + + /* Tag all linked parents in tree hierarchy to be also overridden. */ + while ((te = te->parent) != NULL) { + if (!TSE_IS_REAL_ID(te->store_elem)) { + continue; + } + if (!ID_IS_OVERRIDE_LIBRARY_REAL(te->store_elem->id)) { + break; + } + te->store_elem->id->tag |= LIB_TAG_DOIT; + } + + BKE_lib_override_library_delete(bmain, id_root); + } +} + static void id_fake_user_set_fn(bContext *UNUSED(C), ReportList *UNUSED(reports), Scene *UNUSED(scene), @@ -1567,6 +1630,7 @@ static int outliner_delete_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); ED_outliner_select_sync_from_object_tag(C); return OPERATOR_FINISHED; @@ -1607,6 +1671,8 @@ typedef enum eOutlinerIdOpTypes { OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET, OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY, + OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY, OUTLINER_IDOP_SINGLE, OUTLINER_IDOP_DELETE, OUTLINER_IDOP_REMAP, @@ -1653,6 +1719,18 @@ static const EnumPropertyItem prop_id_op_types[] = { 0, "Reset Library Override Hierarchy", "Reset this local override to its linked values, as well as its hierarchy of dependencies"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY, + "OVERRIDE_LIBRARY_RESYNC_HIERARCHY", + 0, + "Resync Library Override Hierarchy", + "Rebuild this local override from its linked reference, as well as its hierarchy of " + "dependencies"}, + {OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY, + "OVERRIDE_LIBRARY_DELETE_HIERARCHY", + 0, + "Delete Library Override Hierarchy", + "Delete this local override (including its hierarchy of override dependencies) and relink " + "its usages to the linked data-blocks"}, {0, "", 0, NULL, NULL}, {OUTLINER_IDOP_COPY, "COPY", ICON_COPYDOWN, "Copy", ""}, {OUTLINER_IDOP_PASTE, "PASTE", ICON_PASTEDOWN, "Paste", ""}, @@ -1683,6 +1761,10 @@ static bool outliner_id_operation_item_poll(bContext *C, case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: return true; + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY: + return true; + case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: + return true; case OUTLINER_IDOP_SINGLE: if (!space_outliner || ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) { return true; @@ -1818,7 +1900,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; } case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE: { - /* make local */ outliner_do_libdata_operation(C, op->reports, scene, @@ -1830,7 +1911,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; } case OUTLINER_IDOP_OVERRIDE_LIBRARY_CREATE_HIERARCHY: { - /* make local */ outliner_do_libdata_operation(C, op->reports, scene, @@ -1842,7 +1922,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; } case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET: { - /* make local */ outliner_do_libdata_operation(C, op->reports, scene, @@ -1854,7 +1933,6 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; } case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESET_HIERARCHY: { - /* make local */ outliner_do_libdata_operation(C, op->reports, scene, @@ -1865,6 +1943,28 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Reset Overridden Data Hierarchy"); break; } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_RESYNC_HIERARCHY: { + outliner_do_libdata_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + id_override_library_resync_fn, + &(OutlinerLibOverrideData){.do_hierarchy = true}); + ED_undo_push(C, "Resync Overridden Data Hierarchy"); + break; + } + case OUTLINER_IDOP_OVERRIDE_LIBRARY_DELETE_HIERARCHY: { + outliner_do_libdata_operation(C, + op->reports, + scene, + space_outliner, + &space_outliner->tree, + id_override_library_delete_fn, + &(OutlinerLibOverrideData){.do_hierarchy = true}); + ED_undo_push(C, "Delete Overridden Data Hierarchy"); + break; + } case OUTLINER_IDOP_SINGLE: { /* make single user */ switch (idlevel) { diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 60058c82283..22a7019ab91 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -32,6 +32,7 @@ #include "DNA_camera_types.h" #include "DNA_collection_types.h" #include "DNA_constraint_types.h" +#include "DNA_gpencil_modifier_types.h" #include "DNA_gpencil_types.h" #include "DNA_hair_types.h" #include "DNA_key_types.h" @@ -46,6 +47,7 @@ #include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_simulation_types.h" #include "DNA_speaker_types.h" #include "DNA_volume_types.h" @@ -244,14 +246,12 @@ static TreeElement *outliner_add_element(SpaceOutliner *space_outliner, /* -------------------------------------------------------- */ /** - * Check if an element type needs a full rebuild if the open/collapsed state changes. - * These element types don't add children if collapsed. - * - * This current check isn't great really. A per element-type flag would be preferable. + * Check if a display mode needs a full rebuild if the open/collapsed state changes. + * Element types in these modes don't actually add children if collapsed, so the rebuild is needed. */ -bool outliner_element_needs_rebuild_on_open_change(const TreeStoreElem *tselem) +bool outliner_mode_requires_always_rebuild(const SpaceOutliner *space_outliner) { - return ELEM(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_KEYMAP); + return ELEM(space_outliner->outlinevis, SO_DATA_API); } /* special handling of hierarchical non-lib data */ @@ -552,6 +552,70 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner, } } + /* Grease Pencil modifiers. */ + if (!BLI_listbase_is_empty(&ob->greasepencil_modifiers)) { + TreeElement *ten_mod = outliner_add_element( + space_outliner, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0); + + ten_mod->name = IFACE_("Modifiers"); + int index; + LISTBASE_FOREACH_INDEX (GpencilModifierData *, md, &ob->greasepencil_modifiers, index) { + TreeElement *ten = outliner_add_element( + space_outliner, &ten_mod->subtree, ob, ten_mod, TSE_MODIFIER, index); + ten->name = md->name; + ten->directdata = md; + + if (md->type == eGpencilModifierType_Armature) { + outliner_add_element(space_outliner, + &ten->subtree, + ((ArmatureGpencilModifierData *)md)->object, + ten, + TSE_LINKED_OB, + 0); + } + else if (md->type == eGpencilModifierType_Hook) { + outliner_add_element(space_outliner, + &ten->subtree, + ((HookGpencilModifierData *)md)->object, + ten, + TSE_LINKED_OB, + 0); + } + else if (md->type == eGpencilModifierType_Lattice) { + outliner_add_element(space_outliner, + &ten->subtree, + ((LatticeGpencilModifierData *)md)->object, + ten, + TSE_LINKED_OB, + 0); + } + } + } + + /* Grease Pencil effects. */ + if (!BLI_listbase_is_empty(&ob->shader_fx)) { + TreeElement *ten_fx = outliner_add_element( + space_outliner, &te->subtree, ob, te, TSE_GPENCIL_EFFECT_BASE, 0); + + ten_fx->name = IFACE_("Effects"); + int index; + LISTBASE_FOREACH_INDEX (ShaderFxData *, fx, &ob->shader_fx, index) { + TreeElement *ten = outliner_add_element( + space_outliner, &ten_fx->subtree, ob, ten_fx, TSE_GPENCIL_EFFECT, index); + ten->name = fx->name; + ten->directdata = fx; + + if (fx->type == eShaderFxType_Swirl) { + outliner_add_element(space_outliner, + &ten->subtree, + ((SwirlShaderFxData *)fx)->object, + ten, + TSE_LINKED_OB, + 0); + } + } + } + /* vertex groups */ if (ob->defbase.first) { bDeformGroup *defgroup; diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c index 1da44b5e51e..25dc7bc271e 100644 --- a/source/blender/editors/space_outliner/outliner_utils.c +++ b/source/blender/editors/space_outliner/outliner_utils.c @@ -37,6 +37,7 @@ #include "ED_armature.h" #include "ED_outliner.h" +#include "ED_screen.h" #include "UI_interface.h" #include "UI_view2d.h" @@ -455,6 +456,23 @@ void outliner_scroll_view(ARegion *region, int delta_y) } } +/** + * The outliner should generally use #ED_region_tag_redraw_no_rebuild() to avoid unnecessary tree + * rebuilds. If elements are open or closed, we may still have to rebuild. + * Upon changing the open/closed state, call this to avoid rebuilds if possible. + */ +void outliner_tag_redraw_avoid_rebuild_on_open_change(const SpaceOutliner *space_outliner, + ARegion *region) +{ + /* Avoid rebuild if possible. */ + if (outliner_mode_requires_always_rebuild(space_outliner)) { + ED_region_tag_redraw(region); + } + else { + ED_region_tag_redraw_no_rebuild(region); + } +} + /* Get base of object under cursor. Used for eyedropper tool */ Base *ED_outliner_give_base_under_cursor(bContext *C, const int mval[2]) { diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index b14afed81dd..6a63c3c65c3 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -87,7 +87,6 @@ static void outliner_main_region_draw(const bContext *C, ARegion *region) /* clear */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); draw_outliner(C); @@ -114,6 +113,8 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win), switch (wmn->data) { case ND_OB_ACTIVE: case ND_OB_SELECT: + ED_region_tag_redraw_no_rebuild(region); + break; case ND_OB_VISIBLE: case ND_OB_RENDER: case ND_MODE: @@ -121,15 +122,23 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win), case ND_FRAME: case ND_RENDER_OPTIONS: case ND_SEQUENCER: - case ND_LAYER: case ND_LAYER_CONTENT: case ND_WORLD: case ND_SCENEBROWSE: ED_region_tag_redraw(region); break; + case ND_LAYER: + /* Avoid rebuild if only the active collection changes */ + if ((wmn->subtype == NS_LAYER_COLLECTION) && (wmn->action == NA_ACTIVATED)) { + ED_region_tag_redraw_no_rebuild(region); + break; + } + + ED_region_tag_redraw(region); + break; } - if (wmn->action & NA_EDITED) { - ED_region_tag_redraw(region); + if (wmn->action == NA_EDITED) { + ED_region_tag_redraw_no_rebuild(region); } break; case NC_OBJECT: @@ -181,7 +190,7 @@ static void outliner_main_region_listener(wmWindow *UNUSED(win), case NC_MATERIAL: switch (wmn->data) { case ND_SHADING_LINKS: - ED_region_tag_redraw(region); + ED_region_tag_redraw_no_rebuild(region); break; } break; diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index e9ed1cec228..f739bfe367e 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -42,7 +42,7 @@ #include "script_intern.h" // own include #ifdef WITH_PYTHON -# include "BPY_extern.h" /* BPY_script_exec */ +# include "BPY_extern_run.h" #endif static int run_pyfile_exec(bContext *C, wmOperator *op) @@ -50,7 +50,7 @@ static int run_pyfile_exec(bContext *C, wmOperator *op) char path[512]; RNA_string_get(op->ptr, "filepath", path); #ifdef WITH_PYTHON - if (BPY_execute_filepath(C, path, op->reports)) { + if (BPY_run_filepath(C, path, op->reports)) { ARegion *region = CTX_wm_region(C); ED_region_tag_redraw(region); return OPERATOR_FINISHED; @@ -120,7 +120,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) /* TODO, this crashes on netrender and keying sets, need to look into why * disable for now unless running in debug mode */ WM_cursor_wait(1); - BPY_execute_string( + BPY_run_string_eval( C, (const char *[]){"bpy", NULL}, "bpy.utils.load_scripts(reload_scripts=True)"); WM_cursor_wait(0); WM_event_add_notifier(C, NC_WINDOW, NULL); diff --git a/source/blender/editors/space_script/space_script.c b/source/blender/editors/space_script/space_script.c index 4d0c2b658c6..3c3f7dc1e8e 100644 --- a/source/blender/editors/space_script/space_script.c +++ b/source/blender/editors/space_script/space_script.c @@ -127,7 +127,6 @@ static void script_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index dce8aa16985..79f30423bf2 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -78,6 +78,7 @@ static void metadata_panel_context_draw(const bContext *C, Panel *panel) struct Main *bmain = CTX_data_main(C); struct Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C); struct Scene *scene = CTX_data_scene(C); + ARegion *region = CTX_wm_region(C); SpaceSeq *space_sequencer = CTX_wm_space_seq(C); /* NOTE: We can only reliably show metadata for the original (current) * frame when split view is used. */ @@ -88,7 +89,8 @@ static void metadata_panel_context_draw(const bContext *C, Panel *panel) } /* NOTE: We disable multiview for drawing, since we don't know what is the * from the panel (is kind of all the views?). */ - ImBuf *ibuf = sequencer_ibuf_get(bmain, depsgraph, scene, space_sequencer, scene->r.cfra, 0, ""); + ImBuf *ibuf = sequencer_ibuf_get( + bmain, region, depsgraph, scene, space_sequencer, scene->r.cfra, 0, ""); if (ibuf != NULL) { ED_region_image_metadata_panel_draw(ibuf, panel->layout); IMB_freeImBuf(ibuf); diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 0f4690c11d5..cdc7ada8c84 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -56,6 +56,7 @@ #include "GPU_matrix.h" #include "GPU_state.h" #include "GPU_vertex_buffer.h" +#include "GPU_viewport.h" #include "ED_anim_api.h" #include "ED_gpencil.h" @@ -88,11 +89,12 @@ #define SEQ_SCROLLER_TEXT_OFFSET 8 #define MUTE_ALPHA 120 -/* Note, Don't use SEQ_BEGIN/SEQ_END while drawing! +/* Note, Don't use SEQ_ALL_BEGIN/SEQ_ALL_END while drawing! * it messes up transform. */ -#undef SEQ_BEGIN -#undef SEQP_BEGIN -#undef SEQ_END +#undef SEQ_ALL_BEGIN +#undef SEQ_ALL_END +#undef SEQ_CURRENT_BEGIN +#undef SEQ_CURRENT_END static Sequence *special_seq_update = NULL; @@ -294,7 +296,7 @@ static void draw_seq_waveform(View2D *v2d, /* Fcurve lookup is quite expensive, so do this after precondition. */ FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); @@ -350,13 +352,13 @@ static void draw_seq_waveform(View2D *v2d, immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2) { - /* Don't use SEQ_BEGIN/SEQ_END here, + /* Don't use SEQ_ALL_BEGIN/SEQ_ALL_END here, * because it changes seq->depth, which is needed for transform. */ Sequence *seq; uchar col[4]; @@ -381,9 +383,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, offset = 0; } - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); for (seq = seqbase->first; seq; seq = seq->next) { chan_min = min_ii(chan_min, seq->machine); @@ -443,7 +443,7 @@ static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Get handle width in pixels. */ @@ -489,10 +489,9 @@ static void draw_seq_handle(View2D *v2d, } if (!(seq->type & SEQ_TYPE_EFFECT) || BKE_sequence_effect_get_num_inputs(seq->type) == 0) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (seq->flag & whichsel) { if (seq_active) { @@ -511,7 +510,7 @@ static void draw_seq_handle(View2D *v2d, } immRectf(pos, rx1, y1, rx2, y2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Draw numbers for start and end of the strip next to its handles. */ @@ -753,9 +752,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa y1 = seq->machine + SEQ_STRIP_OFSBOTTOM; y2 = seq->machine + SEQ_STRIP_OFSTOP; - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); color3ubv_from_seq(scene, seq, col); if (seq->flag & SELECT) { @@ -781,7 +778,7 @@ static void draw_sequence_extensions(Scene *scene, Sequence *seq, uint pos, floa imm_draw_box_wire_2d( pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1) @@ -791,7 +788,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, rgb_float_to_uchar(col, colvars->col); if (seq->flag & SEQ_MUTE) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); col[3] = MUTE_ALPHA; } else { @@ -812,7 +809,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, immEnd(); if (seq->flag & SEQ_MUTE) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -843,9 +840,7 @@ static void draw_seq_background(Scene *scene, } if (seq->flag & SEQ_MUTE) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); col[3] = MUTE_ALPHA; } @@ -910,13 +905,13 @@ static void draw_seq_background(Scene *scene, } if (seq->flag & SEQ_MUTE) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } static void draw_seq_locked(float x1, float y1, float x2, float y2) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_DIAG_STRIPES); @@ -930,12 +925,12 @@ static void draw_seq_locked(float x1, float y1, float x2, float y2) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -943,7 +938,7 @@ static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y) immRectf(pos, x1, y2, x2, text_margin_y); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void calculate_seq_text_offsets( @@ -1056,13 +1051,13 @@ static void draw_seq_fcurve( GPU_vertbuf_data_len_set(vbo, vert_count); GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR); GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (vert_count > 0) { GPU_batch_draw(batch); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_batch_discard(batch); } } @@ -1180,7 +1175,7 @@ static void draw_effect_inputs_highlight(Sequence *seq) Sequence *seq1 = seq->seq1; Sequence *seq2 = seq->seq2; Sequence *seq3 = seq->seq3; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1207,7 +1202,7 @@ static void draw_effect_inputs_highlight(Sequence *seq) seq3->machine + SEQ_STRIP_OFSTOP); } immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } void sequencer_special_update_set(Sequence *seq) @@ -1235,7 +1230,14 @@ void ED_sequencer_special_preview_clear(void) sequencer_special_update_set(NULL); } +/** + * Rendering using opengl will change the current viewport/context. + * This is why we need the ARegion, to set back the render area. + * TODO do not rely on such hack and just update the ibuf ouside of + * the UI drawing code. + **/ ImBuf *sequencer_ibuf_get(struct Main *bmain, + ARegion *region, struct Depsgraph *depsgraph, Scene *scene, SpaceSeq *sseq, @@ -1271,9 +1273,16 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, * by Escape pressed somewhere in the past. */ G.is_break = false; - /* Rendering can change OGL context. Save & Restore framebuffer. */ + GPUViewport *viewport = WM_draw_region_get_bound_viewport(region); GPUFrameBuffer *fb = GPU_framebuffer_active_get(); - GPU_framebuffer_restore(); + if (viewport) { + /* Unbind viewport to release the DRW context. */ + GPU_viewport_unbind(viewport); + } + else { + /* Rendering can change OGL context. Save & Restore framebuffer. */ + GPU_framebuffer_restore(); + } if (special_seq_update) { ibuf = BKE_sequencer_give_ibuf_direct(&context, cfra + frame_ofs, special_seq_update); @@ -1282,7 +1291,12 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, ibuf = BKE_sequencer_give_ibuf(&context, cfra + frame_ofs, sseq->chanshown); } - if (fb) { + if (viewport) { + /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same viewport. */ + int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0; + GPU_viewport_bind(viewport, view, ®ion->winrct); + } + else if (fb) { GPU_framebuffer_bind(fb); } @@ -1534,11 +1548,7 @@ static void sequencer_stop_running_jobs(const bContext *C, Scene *scene) static void sequencer_preview_clear(void) { - float col[3]; - - UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); - GPU_clear_color(col[0], col[1], col[2], 0.0); - GPU_clear(GPU_COLOR_BIT); + UI_ThemeClearColor(TH_SEQ_PREVIEW); } static void sequencer_preview_get_rect(rctf *preview, @@ -1594,9 +1604,7 @@ static void sequencer_draw_display_buffer(const bContext *C, void *display_buffer; if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); } /* Format needs to be created prior to any immBindShader call. @@ -1681,7 +1689,7 @@ static void sequencer_draw_display_buffer(const bContext *C, } if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } if (draw_backdrop) { @@ -1775,6 +1783,16 @@ void sequencer_draw_preview(const bContext *C, return; } + /* Get image. */ + ibuf = sequencer_ibuf_get( + bmain, region, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]); + + /* Setup offscreen buffers. */ + GPUViewport *viewport = WM_draw_region_get_viewport(region); + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + GPU_depth_test(GPU_DEPTH_NONE); + if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) { sequencer_preview_clear(); return; @@ -1794,9 +1812,6 @@ void sequencer_draw_preview(const bContext *C, imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); } } - /* Get image. */ - ibuf = sequencer_ibuf_get( - bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]); if (ibuf) { scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop); @@ -1928,7 +1943,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) else if (last_seq->type == SEQ_TYPE_MULTICAM) { int channel = last_seq->multicam_source; if (channel != 0) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1937,7 +1952,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immRectf(pos, v2d->cur.xmin, channel, v2d->cur.xmax, channel + 1); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -1945,7 +1960,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) /* Draw highlight if "solo preview" is used. */ if (special_seq_update) { const Sequence *seq = special_seq_update; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -1959,7 +1974,7 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1969,7 +1984,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) const int frame_sta = scene->r.sfra; const int frame_end = scene->r.efra + 1; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2030,7 +2045,7 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } typedef struct CacheDrawData { @@ -2154,7 +2169,7 @@ static void draw_cache_view(const bContext *C) return; } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); @@ -2241,7 +2256,7 @@ static void draw_cache_view(const bContext *C) draw_cache_view_batch( userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* Draw sequencer timeline. */ @@ -2256,6 +2271,11 @@ void draw_timeline_seq(const bContext *C, ARegion *region) seq_prefetch_wm_notify(C, scene); + GPUViewport *viewport = WM_draw_region_get_viewport(region); + GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport); + GPU_framebuffer_bind_no_srgb(framebuffer_overlay); + GPU_depth_test(GPU_DEPTH_NONE); + UI_GetThemeColor3fv(TH_BACK, col); if (ed && ed->metastack.first) { GPU_clear_color(col[0], col[1], col[2] - 0.1f, 0.0f); @@ -2263,7 +2283,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region) else { GPU_clear_color(col[0], col[1], col[2], 0.0f); } - GPU_clear(GPU_COLOR_BIT); UI_view2d_view_ortho(v2d); /* Get timeline boundbox, needed for the scrollers. */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 99d4c2d9f1a..f175c2a7419 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -58,6 +58,7 @@ #include "ED_sequencer.h" #include "UI_interface.h" +#include "UI_resources.h" #include "UI_view2d.h" #include "DEG_depsgraph.h" @@ -216,7 +217,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); bool selected = false; /* Check for no selected strips */ - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_META) || (seq->flag & SELECT) == 0) { continue; @@ -239,7 +240,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) BKE_reportf(reports, RPT_WARNING, "Overwrite is not checked for %s, skipping", seq->name); } } - SEQ_END; + SEQ_CURRENT_END; if (!selected) { BKE_reportf(reports, RPT_WARNING, "Select movie or image strips"); @@ -482,10 +483,10 @@ void ED_sequencer_deselect_all(Scene *scene) return; } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { seq->flag &= ~SEQ_ALLSEL; } - SEQ_END; + SEQ_CURRENT_END; } void recurs_sel_seq(Sequence *seqm) @@ -1030,7 +1031,7 @@ static void set_filter_seq(Scene *scene) return; } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->flag & SELECT) { if (seq->type == SEQ_TYPE_MOVIE) { seq->flag |= SEQ_FILTERY; @@ -1039,7 +1040,7 @@ static void set_filter_seq(Scene *scene) } } } - SEQ_END; + SEQ_CURRENT_END; } #endif @@ -1065,7 +1066,7 @@ static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene) return; } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->flag & SELECT) { if (STREQLEN(seq->strip->dir, from, strlen(from))) { printf("found %s\n", seq->strip->dir); @@ -1080,7 +1081,7 @@ static void UNUSED_FUNCTION(seq_remap_paths)(Scene *scene) } } } - SEQ_END; + SEQ_CURRENT_END; } /** \} */ @@ -1308,7 +1309,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) } /* Test for effects and overlap. - * Don't use SEQP_BEGIN since that would be recursive. */ + * Don't use SEQ_CURRENT_BEGIN since that would be recursive. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) { seq->flag &= ~SEQ_OVERLAP; @@ -2294,25 +2295,25 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) Sequence *seq; if (ignore_selection) { if (use_cursor_position) { - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->enddisp == split_frame && seq->machine == split_channel) { seq_selected = seq->flag & SEQ_ALLSEL; } } - SEQ_END; + SEQ_CURRENT_END; if (!seq_selected) { - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->startdisp == split_frame && seq->machine == split_channel) { seq->flag &= ~SEQ_ALLSEL; } } - SEQ_END; + SEQ_CURRENT_END; } } } else { if (split_side != SEQ_SIDE_BOTH) { - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (split_side == SEQ_SIDE_LEFT) { if (seq->startdisp >= split_frame) { seq->flag &= ~SEQ_ALLSEL; @@ -2324,15 +2325,15 @@ static int sequencer_split_exec(bContext *C, wmOperator *op) } } } - SEQ_END; + SEQ_CURRENT_END; } } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->seq1 || seq->seq2 || seq->seq3) { BKE_sequence_calc(scene, seq); } } - SEQ_END; + SEQ_CURRENT_END; BKE_sequencer_sort(scene); } @@ -2376,6 +2377,28 @@ static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *ev return sequencer_split_exec(C, op); } +static void sequencer_split_ui(bContext *UNUSED(C), wmOperator *op) +{ + uiLayout *layout = op->layout; + uiLayoutSetPropSep(layout, true); + uiLayoutSetPropDecorate(layout, false); + + PointerRNA ptr; + RNA_pointer_create(NULL, op->type->srna, op->properties, &ptr); + + uiLayout *row = uiLayoutRow(layout, false); + uiItemR(row, &ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, &ptr, "frame", 0, NULL, ICON_NONE); + uiItemR(layout, &ptr, "side", 0, NULL, ICON_NONE); + + uiItemS(layout); + + uiItemR(layout, &ptr, "use_cursor_position", 0, NULL, ICON_NONE); + if (RNA_boolean_get(&ptr, "use_cursor_position")) { + uiItemR(layout, &ptr, "channel", 0, NULL, ICON_NONE); + } +} + void SEQUENCER_OT_split(struct wmOperatorType *ot) { /* Identifiers. */ @@ -2387,6 +2410,7 @@ void SEQUENCER_OT_split(struct wmOperatorType *ot) ot->invoke = sequencer_split_invoke; ot->exec = sequencer_split_exec; ot->poll = sequencer_edit_poll; + ot->ui = sequencer_split_ui; /* Flags. */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2521,12 +2545,12 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) BKE_sequencer_prefetch_stop(scene); - SEQP_BEGIN (scene->ed, seq) { + SEQ_CURRENT_BEGIN (scene->ed, seq) { if (seq->flag & SELECT) { BKE_sequencer_flag_for_removal(scene, ed->seqbasep, seq); } } - SEQ_END; + SEQ_CURRENT_END; BKE_sequencer_remove_flagged_sequences(scene, ed->seqbasep); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); @@ -2642,6 +2666,8 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* Poll checks this is valid. */ + BKE_sequencer_prefetch_stop(scene); + while (seq) { if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { Sequence *seq_next; @@ -2837,6 +2863,8 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + /* Remove all selected from main list, and put in meta. */ seqm = BKE_sequence_alloc(ed->seqbasep, 1, 1, SEQ_TYPE_META); /* Channel number set later. */ @@ -2922,6 +2950,8 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } + BKE_sequencer_prefetch_stop(scene); + for (seq = last_seq->seqbase.first; seq != NULL; seq = seq->next) { BKE_sequence_invalidate_cache_composite(scene, seq); } @@ -2946,7 +2976,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0); /* Test for effects and overlap - * don't use SEQP_BEGIN since that would be recursive. */ + * don't use SEQ_CURRENT_BEGIN since that would be recursive. */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { seq->flag &= ~SEQ_OVERLAP; @@ -3470,7 +3500,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) file_list = BLI_gset_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, "file list"); - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if ((seq->flag & SELECT)) { ListBase queue = {NULL, NULL}; LinkData *link; @@ -3487,7 +3517,7 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); } } - SEQ_END; + SEQ_CURRENT_END; BLI_gset_free(file_list, MEM_freeN); @@ -3538,7 +3568,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) turnon = false; } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if ((seq->flag & SELECT)) { if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_META)) { BKE_sequencer_proxy_set(seq, turnon); @@ -3583,7 +3613,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) } } } - SEQ_END; + SEQ_CURRENT_END; WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -3960,12 +3990,12 @@ static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - SEQ_BEGIN (ed, seq) { + SEQ_ALL_BEGIN (ed, seq) { if (seq->type == SEQ_TYPE_TEXT) { BLI_addtail(&text_seq, MEM_dupallocN(seq)); } } - SEQ_END; + SEQ_ALL_END; if (BLI_listbase_is_empty(&text_seq)) { BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export"); diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 1d168866e7c..df36453bd2e 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -60,6 +60,7 @@ float sequence_handle_size_get_clamped(struct Sequence *seq, const float pixelx) /* void seq_reset_imageofs(struct SpaceSeq *sseq); */ struct ImBuf *sequencer_ibuf_get(struct Main *bmain, + struct ARegion *region, struct Depsgraph *depsgraph, struct Scene *scene, struct SpaceSeq *sseq, diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index e0f7179c3f9..50f2a5084ef 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -232,7 +232,7 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - SEQP_BEGIN (ed, seq_iter) { + SEQ_CURRENT_BEGIN (ed, seq_iter) { if (seq_iter->flag & SELECT) { if (seq_iter == seq) { continue; @@ -254,7 +254,7 @@ static int strip_modifier_copy_exec(bContext *C, wmOperator *op) BKE_sequence_modifier_list_copy(seq_iter, seq); } } - SEQ_END; + SEQ_CURRENT_END; BKE_sequence_invalidate_cache_preprocessed(scene, seq); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 85b70354ab3..955b4dba5e8 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -415,14 +415,14 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) const float x = UI_view2d_region_to_view_x(v2d, mval[0]); - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (((x < CFRA) && (seq->enddisp <= CFRA)) || ((x >= CFRA) && (seq->startdisp >= CFRA))) { /* Select left or right. */ seq->flag |= SELECT; recurs_sel_seq(seq); } } - SEQ_END; + SEQ_CURRENT_END; { SpaceSeq *sseq = CTX_wm_space_seq(C); @@ -975,7 +975,7 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) ED_sequencer_deselect_all(scene); } const int cfra = CFRA; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { bool test = false; switch (side) { case -1: @@ -994,7 +994,7 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) recurs_sel_seq(seq); } } - SEQ_END; + SEQ_CURRENT_END; ED_outliner_select_sync_from_sequence_tag(C); @@ -1282,13 +1282,13 @@ static bool select_grouped_type(Editing *ed, Sequence *actseq, const int channel Sequence *seq; bool changed = false; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == actseq->type) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; return changed; } @@ -1299,13 +1299,13 @@ static bool select_grouped_type_basic(Editing *ed, Sequence *actseq, const int c bool changed = false; const bool is_sound = SEQ_IS_SOUND(actseq); - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq))) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; return changed; } @@ -1316,14 +1316,14 @@ static bool select_grouped_type_effect(Editing *ed, Sequence *actseq, const int bool changed = false; const bool is_effect = SEQ_IS_EFFECT(actseq); - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && (is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq))) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; return changed; } @@ -1339,45 +1339,45 @@ static bool select_grouped_data(Editing *ed, Sequence *actseq, const int channel } if (SEQ_HAS_PATH(actseq) && dir) { - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && SEQ_HAS_PATH(seq) && seq->strip && STREQ(seq->strip->dir, dir)) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_SCENE) { Scene *sce = actseq->scene; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_MOVIECLIP) { MovieClip *clip = actseq->clip; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; } else if (actseq->type == SEQ_TYPE_MASK) { struct Mask *mask = actseq->mask; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; } return changed; @@ -1394,15 +1394,15 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann effects[i] = false; } - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && (seq->type & SEQ_TYPE_EFFECT) && ELEM(actseq, seq->seq1, seq->seq2, seq->seq3)) { effects[seq->type] = true; } } - SEQ_END; + SEQ_CURRENT_END; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (SEQ_CHANNEL_CHECK(seq, channel) && effects[seq->type]) { if (seq->seq1) { seq->seq1->flag |= SELECT; @@ -1416,7 +1416,7 @@ static bool select_grouped_effect(Editing *ed, Sequence *actseq, const int chann changed = true; } } - SEQ_END; + SEQ_CURRENT_END; return changed; } @@ -1426,13 +1426,13 @@ static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq) Sequence *seq; bool changed = false; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { if (seq->startdisp < actseq->enddisp && seq->enddisp > actseq->startdisp) { seq->flag |= SELECT; changed = true; } } - SEQ_END; + SEQ_CURRENT_END; return changed; } @@ -1447,10 +1447,10 @@ static bool select_grouped_effect_link(Editing *ed, Sequence *actseq, const int int machine = actseq->machine; SeqIterator iter; - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { seq->tmp = NULL; } - SEQ_END; + SEQ_CURRENT_END; actseq->tmp = POINTER_FROM_INT(true); @@ -1523,11 +1523,11 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) bool changed = false; if (!extend) { - SEQP_BEGIN (ed, seq) { + SEQ_CURRENT_BEGIN (ed, seq) { seq->flag &= ~SELECT; changed = true; } - SEQ_END; + SEQ_CURRENT_END; } switch (type) { diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index c1dac30bcb6..491c475b596 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -144,17 +144,17 @@ void SEQUENCER_OT_view_frame(wmOperatorType *ot) static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op)) { + SpaceSeq *sseq = CTX_wm_space_seq(C); bScreen *screen = CTX_wm_screen(C); ScrArea *area = CTX_wm_area(C); #if 0 ARegion *region = CTX_wm_region(C); - SpaceSeq *sseq = area->spacedata.first; Scene *scene = CTX_data_scene(C); #endif View2D *v2d = UI_view2d_fromcontext(C); v2d->cur = v2d->tot; - UI_view2d_curRect_validate(v2d); + UI_view2d_curRect_changed(C, v2d); UI_view2d_sync(screen, area, v2d, V2D_LOCK_COPY); #if 0 @@ -186,6 +186,8 @@ static int sequencer_view_all_preview_exec(bContext *C, wmOperator *UNUSED(op)) } #endif + sseq->flag |= SEQ_ZOOM_TO_FIT; + ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; } @@ -228,6 +230,8 @@ static int sequencer_view_zoom_ratio_exec(bContext *C, wmOperator *op) ED_region_tag_redraw(CTX_wm_region(C)); + UI_view2d_curRect_changed(C, v2d); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index b8bb3e4d43b..4a6bd0de60c 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -96,7 +96,8 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce sseq->chanshown = 0; sseq->view = SEQ_VIEW_SEQUENCE; sseq->mainb = SEQ_DRAW_IMG_IMBUF; - sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES; + sseq->flag = SEQ_SHOW_GPENCIL | SEQ_USE_ALPHA | SEQ_SHOW_MARKERS | SEQ_SHOW_FCURVES | + SEQ_ZOOM_TO_FIT; /* Tool header. */ region = MEM_callocN(sizeof(ARegion), "tool header for sequencer"); @@ -679,6 +680,22 @@ static void sequencer_preview_region_init(wmWindowManager *wm, ARegion *region) WM_event_add_keymap_handler_v2d_mask(®ion->handlers, keymap); } +static void sequencer_preview_region_layout(const bContext *C, ARegion *region) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + + if (sseq->flag & SEQ_ZOOM_TO_FIT) { + View2D *v2d = ®ion->v2d; + v2d->cur = v2d->tot; + } +} + +static void sequencer_preview_region_view2d_changed(const bContext *C, ARegion *UNUSED(region)) +{ + SpaceSeq *sseq = CTX_wm_space_seq(C); + sseq->flag &= ~SEQ_ZOOM_TO_FIT; +} + static void sequencer_preview_region_draw(const bContext *C, ARegion *region) { ScrArea *area = CTX_wm_area(C); @@ -881,6 +898,8 @@ void ED_spacetype_sequencer(void) art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer region"); art->regionid = RGN_TYPE_PREVIEW; art->init = sequencer_preview_region_init; + art->layout = sequencer_preview_region_layout; + art->on_view2d_changed = sequencer_preview_region_view2d_changed; art->draw = sequencer_preview_region_draw; art->listener = sequencer_preview_region_listener; art->keymapflag = ED_KEYMAP_TOOL | ED_KEYMAP_GIZMO | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index f6d00ec94bf..300f63761c0 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -296,7 +296,6 @@ static void text_main_region_draw(const bContext *C, ARegion *region) /* clear and setup matrix */ UI_ThemeClearColor(TH_BACK); - GPU_clear(GPU_COLOR_BIT); // UI_view2d_view_ortho(v2d); diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index e9ac6946032..ec5175eae51 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1353,11 +1353,9 @@ static void draw_text_decoration(SpaceText *st, ARegion *region) UI_GetThemeColor4fv(TH_TEXT, highlight_color); highlight_color[3] = 0.1f; immUniformColor4fv(highlight_color); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRecti(pos, 0, y1, region->winx, y2); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -1662,25 +1660,16 @@ void draw_text_main(SpaceText *st, ARegion *region) } if (st->showlinenrs && !wrap_skip) { - /* draw line number */ - if (tmp == text->curl) { - UI_FontThemeColor(tdc.font_id, TH_HILITE); - } - else { - UI_FontThemeColor(tdc.font_id, TH_LINENUMBERS); - } - + /* Draw line number. */ + UI_FontThemeColor(tdc.font_id, (tmp == text->curl) ? TH_HILITE : TH_LINENUMBERS); BLI_snprintf(linenr, sizeof(linenr), "%*d", st->runtime.line_number_display_digits, i + linecount + 1); - /* itoa(i + linecount + 1, linenr, 10); */ /* not ansi-c :/ */ text_font_draw(&tdc, TXT_NUMCOL_PAD * st->runtime.cwidth_px, y, linenr); - - if (tmp == text->curl) { - UI_FontThemeColor(tdc.font_id, TH_TEXT); - } + /* Change back to text color. */ + UI_FontThemeColor(tdc.font_id, TH_TEXT); } if (st->wordwrap) { @@ -1708,9 +1697,9 @@ void draw_text_main(SpaceText *st, ARegion *region) UI_GetThemeColor4fv(TH_TEXT, margin_color); margin_color[3] = 0.2f; immUniformColor4fv(margin_color); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRecti(pos, margin_column_x, 0, margin_column_x + U.pixelsize, region->winy); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); immUnbindProgram(); } } diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 201f9dae5d5..688dce3c54e 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -55,6 +55,7 @@ #ifdef WITH_PYTHON # include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "text_format.h" @@ -756,7 +757,7 @@ static int text_run_script(bContext *C, ReportList *reports) void *curl_prev = text->curl; int curc_prev = text->curc; - if (BPY_execute_text(C, text, reports, !is_live)) { + if (BPY_run_text(C, text, reports, !is_live)) { if (is_live) { /* for nice live updates */ WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL); diff --git a/source/blender/editors/space_userpref/space_userpref.c b/source/blender/editors/space_userpref/space_userpref.c index 0242bb4fe24..3efdee9cec9 100644 --- a/source/blender/editors/space_userpref/space_userpref.c +++ b/source/blender/editors/space_userpref/space_userpref.c @@ -141,8 +141,7 @@ static void userpref_main_region_layout(const bContext *C, ARegion *region) BLI_str_tolower_ascii(id_lower, strlen(id_lower)); } - ED_region_panels_layout_ex( - C, region, ®ion->type->paneltypes, contexts, U.space_data.section_active, true, NULL); + ED_region_panels_layout_ex(C, region, ®ion->type->paneltypes, contexts, NULL); } static void userpref_operatortypes(void) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 1ffa653372c..6969ecf197e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -131,9 +131,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, /* Just to create the data to pass to immediate mode, grr! */ const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP); if (facemap_data) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const MVert *mvert = me->mvert; const MPoly *mpoly = me->mpoly; @@ -209,6 +207,6 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, GPU_batch_discard(draw_batch); GPU_vertbuf_discard(vbo_pos); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index e5ba27cef07..de0b420a3b5 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1323,9 +1323,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C, paneltypes = &art->paneltypes; } - const bool vertical = true; - ED_region_panels_layout_ex( - C, region, paneltypes, contexts_base, -1, vertical, category_override); + ED_region_panels_layout_ex(C, region, paneltypes, contexts_base, category_override); } static void view3d_buttons_region_layout(const bContext *C, ARegion *region) @@ -1453,7 +1451,7 @@ static void view3d_tools_region_init(wmWindowManager *wm, ARegion *region) static void view3d_tools_region_draw(const bContext *C, ARegion *region) { - ED_region_panels_ex(C, region, (const char *[]){CTX_data_mode_string(C), NULL}, -1, true); + ED_region_panels_ex(C, region, (const char *[]){CTX_data_mode_string(C), NULL}); } /* area (not region) level listener */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0442a0f35c9..c4da39bca2f 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -588,9 +588,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, float alpha = 1.0f; if (ca->passepartalpha != 1.0f) { - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); alpha = ca->passepartalpha; } @@ -609,7 +607,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, immRectf(shdr_pos, x1i, y1i, x2i, 0.0f); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUniformThemeColor3(TH_BACK); @@ -668,7 +666,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, /* safety border */ if (ca) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformThemeColorAlpha(TH_VIEW_OVERLAY, 0.75f); if (ca->dtx & CAM_DTX_CENTER) { @@ -780,7 +778,7 @@ static void drawviewborder(Scene *scene, Depsgraph *depsgraph, ARegion *region, imm_draw_box_wire_2d(shdr_pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -1027,9 +1025,7 @@ static void draw_view_axis(RegionView3D *rv3d, const rcti *rect) /* draw axis lines */ GPU_line_width(2.0f); GPU_line_smooth(true); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPUVertFormat *format = immVertexFormat(); uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -1072,9 +1068,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d) negate_v3_v3(o, rv3d->ofs); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_depth_mask(false); /* don't overwrite zbuf */ GPUVertFormat *format = immVertexFormat(); @@ -1164,7 +1158,7 @@ static void draw_rotation_guide(const RegionView3D *rv3d) immEnd(); immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_depth_mask(true); } #endif /* WITH_INPUT_NDOF */ @@ -1623,12 +1617,8 @@ void view3d_main_region_draw(const bContext *C, ARegion *region) BKE_image_free_old_gputextures(bmain); GPU_pass_cache_garbage_collect(); - /* XXX This is in order to draw UI batches with the DRW - * old context since we now use it for drawing the entire area. */ - gpu_batch_presets_reset(); - /* No depth test for drawing action zones afterwards. */ - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); v3d->flag |= V3D_INVALID_BACKBUF; } @@ -2163,7 +2153,7 @@ static void view3d_opengl_read_Z_pixels(GPUViewport *viewport, rcti *rect, void { DefaultTextureList *dtxl = (DefaultTextureList *)GPU_viewport_texture_list_get(viewport); - GPUFrameBuffer *tmp_fb = GPU_framebuffer_create(); + GPUFrameBuffer *tmp_fb = GPU_framebuffer_create(__func__); GPU_framebuffer_texture_attach(tmp_fb, dtxl->depth, 0, 0); GPU_framebuffer_bind(tmp_fb); @@ -2329,14 +2319,14 @@ void ED_view3d_draw_depth_gpencil(Depsgraph *depsgraph, Scene *scene, ARegion *r /* Setup view matrix. */ ED_view3d_draw_setup_view(NULL, NULL, depsgraph, scene, region, v3d, NULL, NULL, NULL); - GPU_clear(GPU_DEPTH_BIT); + GPU_clear_depth(1.0f); - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); GPUViewport *viewport = WM_draw_region_get_viewport(region); DRW_draw_depth_loop_gpencil(depsgraph, region, v3d, viewport); - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } /* *********************** customdata **************** */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ac9d12cdd58..5912bea4919 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -822,7 +822,7 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2]) float xaxis[3]; /* Radians per-pixel. */ - const float sensitivity = U.view_rotate_sensitivity_turntable / U.pixelsize; + const float sensitivity = U.view_rotate_sensitivity_turntable / U.dpi_fac; /* Get the 3x3 matrix and its inverse from the quaternion */ quat_to_mat3(m, vod->curr.viewquat); @@ -2015,7 +2015,7 @@ static void view_zoom_to_window_xy_3d(ARegion *region, float dfac, const int zoo } static float viewzoom_scale_value(const rcti *winrct, - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_invert_force, const int xy_curr[2], @@ -2038,7 +2038,7 @@ static float viewzoom_scale_value(const rcti *winrct, fac = (float)(xy_init[1] - xy_curr[1]); } - fac /= U.pixelsize; + fac /= U.dpi_fac; if (zoom_invert != zoom_invert_force) { fac = -fac; @@ -2055,8 +2055,8 @@ static float viewzoom_scale_value(const rcti *winrct, BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct), }; - float len_new = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_curr) / U.pixelsize); - float len_old = (5 * U.pixelsize) + ((float)len_v2v2_int(ctr, xy_init) / U.pixelsize); + float len_new = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_curr) / U.dpi_fac); + float len_old = (5 * U.dpi_fac) + ((float)len_v2v2_int(ctr, xy_init) / U.dpi_fac); /* intentionally ignore 'zoom_invert' for scale */ if (zoom_invert_force) { @@ -2066,16 +2066,16 @@ static float viewzoom_scale_value(const rcti *winrct, zfac = val_orig * (len_old / max_ff(len_new, 1.0f)) / val; } else { /* USER_ZOOM_DOLLY */ - float len_new = 5 * U.pixelsize; - float len_old = 5 * U.pixelsize; + float len_new = 5 * U.dpi_fac; + float len_old = 5 * U.dpi_fac; if (U.uiflag & USER_ZOOM_HORIZ) { - len_new += (winrct->xmax - (xy_curr[0])) / U.pixelsize; - len_old += (winrct->xmax - (xy_init[0])) / U.pixelsize; + len_new += (winrct->xmax - (xy_curr[0])) / U.dpi_fac; + len_old += (winrct->xmax - (xy_init[0])) / U.dpi_fac; } else { - len_new += (winrct->ymax - (xy_curr[1])) / U.pixelsize; - len_old += (winrct->ymax - (xy_init[1])) / U.pixelsize; + len_new += (winrct->ymax - (xy_curr[1])) / U.dpi_fac; + len_old += (winrct->ymax - (xy_init[1])) / U.dpi_fac; } if (zoom_invert != zoom_invert_force) { @@ -2089,7 +2089,7 @@ static float viewzoom_scale_value(const rcti *winrct, } static float viewzoom_scale_value_offset(const rcti *winrct, - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_invert_force, const int xy_curr[2], @@ -2120,7 +2120,7 @@ static float viewzoom_scale_value_offset(const rcti *winrct, static void viewzoom_apply_camera(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2155,7 +2155,7 @@ static void viewzoom_apply_camera(ViewOpsData *vod, static void viewzoom_apply_3d(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2197,7 +2197,7 @@ static void viewzoom_apply_3d(ViewOpsData *vod, static void viewzoom_apply(ViewOpsData *vod, const int xy[2], - const short viewzoom, + const eViewZoom_Style viewzoom, const bool zoom_invert, const bool zoom_to_pos) { @@ -2248,7 +2248,7 @@ static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event) const bool use_cursor_init = RNA_boolean_get(op->ptr, "use_cursor_init"); viewzoom_apply(vod, &event->x, - U.viewzoom, + (eViewZoom_Style)U.viewzoom, (U.uiflag & USER_ZOOM_INVERT) != 0, (use_cursor_init && (U.uiflag & USER_ZOOM_TO_MOUSEPOS))); if (ED_screen_animation_playing(CTX_wm_manager(C))) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c index 3ce4c8dc9a8..d3294e4e5a9 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_navigate_type.c @@ -241,6 +241,8 @@ static void axis_geom_draw(const wmGizmo *gz, const float axis_depth_bias = 0.01f; const float sphere_scale = 1.15f; + /* TODO(fclem) Is there a way to get the widget radius? */ + const float widget_pix_size = 40.0f * U.dpi_fac; #ifdef USE_AXIS_FONT struct { @@ -277,10 +279,22 @@ static void axis_geom_draw(const wmGizmo *gz, GPU_matrix_ortho_set_z(-clip_range, clip_range); } + UI_draw_roundbox_corner_set(UI_CNR_ALL); + GPU_polygon_smooth(false); + /* Circle defining active area. */ if (is_active) { - immUniformColor4fv(color); - imm_draw_circle_fill_3d(pos_id, 0, 0, 1.0f, DIAL_RESOLUTION); + immUnbindProgram(); + + float rad = widget_pix_size; + GPU_matrix_push(); + GPU_matrix_scale_1f(1.0f / rad); + + UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, color); + + GPU_matrix_pop(); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); } GPU_matrix_push(); @@ -343,6 +357,8 @@ static void axis_geom_draw(const wmGizmo *gz, float v_start[3]; immUnbindProgram(); + GPU_blend(GPU_BLEND_ALPHA); + immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); immUniform2fv("viewportSize", &viewport[2]); immUniform1f("lineWidth", 2.0f * U.pixelsize); @@ -370,6 +386,34 @@ static void axis_geom_draw(const wmGizmo *gz, } /* Axis Ball. */ +#ifdef USE_AXIS_FONT + if (select == false) { + immUnbindProgram(); + + GPU_matrix_push(); + GPU_matrix_translate_3fv(v_final); + GPU_matrix_mul(font.matrix); + + float rad = widget_pix_size * (is_pos ? AXIS_HANDLE_SIZE_FG : AXIS_HANDLE_SIZE_BG); + + /* Black outlines for negative axis balls, otherwise they can be hard to see since + * they use a faded color which can be similar to the circle backdrop in tone. */ + if (is_active && !is_highlight && !is_pos && !select && !(axis_align == axis)) { + static const float axis_black_faded[4] = {0.0f, 0.0f, 0.0f, 0.2f}; + float outline = rad * sphere_scale; + UI_draw_roundbox_4fv( + true, -outline, -outline, outline, outline, outline, axis_black_faded); + } + + const float *col = is_pos_color ? color_current : color_current_fade; + UI_draw_roundbox_4fv(true, -rad, -rad, rad, rad, rad, col); + + GPU_matrix_pop(); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + } + else +#endif { GPU_matrix_push(); GPU_matrix_translate_3fv(v_final); @@ -388,6 +432,7 @@ static void axis_geom_draw(const wmGizmo *gz, GPU_matrix_scale_1f(1.0 / sphere_scale); } + GPU_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR); GPU_batch_uniform_4fv(sphere, "color", is_pos_color ? color_current : color_current_fade); GPU_batch_draw(sphere); GPU_matrix_pop(); @@ -407,7 +452,7 @@ static void axis_geom_draw(const wmGizmo *gz, BLF_width_and_height(font.id, axis_str, 2, &offset[0], &offset[1]); BLF_position(font.id, roundf(offset[0] * -0.5f), roundf(offset[1] * -0.5f), 0); BLF_draw_ascii(font.id, axis_str, 2); - GPU_blend(true); /* XXX, blf disables */ + GPU_blend(GPU_BLEND_ALPHA); /* XXX, blf disables */ GPU_matrix_pop(); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -465,9 +510,9 @@ static void axis3d_draw_intern(const bContext *C, UNUSED_VARS(C); #endif - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); axis_geom_draw(gz, color, select, &draw_info); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); GPU_matrix_pop(); } @@ -478,9 +523,9 @@ static void gizmo_axis_draw(const bContext *C, wmGizmo *gz) (void)is_modal; - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); axis3d_draw_intern(C, gz, false, is_highlight); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static int gizmo_axis_test_select(bContext *UNUSED(C), wmGizmo *gz, const int mval[2]) diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index 7799aba5c19..5aba1fecc53 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -607,7 +607,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) GPU_matrix_projection_set(rv3d->winmat); GPU_matrix_set(rv3d->viewmat); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); const uint shdr_pos_3d = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -735,7 +735,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) rot_90_vec_b[1] = dir_ruler[0]; normalize_v2(rot_90_vec_b); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); if (proj_ok[1] && is_act && (ruler_item->flag & RULERITEM_USE_ANGLE_ACTIVE)) { GPU_line_width(3.0f); @@ -781,7 +781,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* text */ @@ -800,13 +800,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) /* draw text (bg) */ if (proj_ok[1]) { immUniformColor4fv(color_back); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos_2d, posit[0] - bg_margin, posit[1] - bg_margin, posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); @@ -831,7 +831,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) normalize_v2(rot_90_vec); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniformColor3ubv(color_wire); @@ -855,7 +855,7 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) immEnd(); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } /* text */ @@ -877,13 +877,13 @@ static void gizmo_ruler_draw(const bContext *C, wmGizmo *gz) /* draw text (bg) */ if (proj_ok[0] && proj_ok[2]) { immUniformColor4fv(color_back); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immRectf(shdr_pos_2d, posit[0] - bg_margin, posit[1] - bg_margin, posit[0] + bg_margin + numstr_size[0], posit[1] + bg_margin + numstr_size[1]); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } immUnbindProgram(); diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index a828dbc2ee0..6c2f4df7004 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -258,12 +258,10 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float GPU_vertbuf_attr_set(vert, pos, i, coords[i]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINE_LOOP, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); - GPU_batch_bind(batch); - GPU_batch_uniform_4fv(batch, "color", color); float viewport[4]; @@ -273,10 +271,8 @@ static void draw_line_loop(const float coords[][3], int coords_len, const float GPU_batch_draw(batch); - GPU_batch_program_use_end(batch); - GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_line_pairs(const float coords_a[][3], @@ -295,12 +291,10 @@ static void draw_line_pairs(const float coords_a[][3], GPU_vertbuf_attr_set(vert, pos, (i * 2) + 1, coords_b[i]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); - GPU_batch_bind(batch); - GPU_batch_uniform_4fv(batch, "color", color); float viewport[4]; @@ -310,10 +304,8 @@ static void draw_line_pairs(const float coords_a[][3], GPU_batch_draw(batch); - GPU_batch_program_use_end(batch); - GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void draw_line_bounds(const BoundBox *bounds, const float color[4]) @@ -347,12 +339,10 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4]) GPU_vertbuf_attr_set(vert, pos, j++, bounds->vec[edges[i][1]]); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_LINES, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); - GPU_batch_bind(batch); - GPU_batch_uniform_4fv(batch, "color", color); float viewport[4]; @@ -362,10 +352,8 @@ static void draw_line_bounds(const BoundBox *bounds, const float color[4]) GPU_batch_draw(batch); - GPU_batch_program_use_end(batch); - GPU_batch_discard(batch); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static bool calc_bbox(struct InteractivePlaceData *ipd, BoundBox *bounds) @@ -598,23 +586,23 @@ static void draw_primitive_view(const struct bContext *C, ARegion *UNUSED(region UI_GetThemeColor3fv(TH_GIZMO_PRIMARY, color); const bool use_depth = !XRAY_ENABLED(ipd->v3d); - const bool depth_test_enabled = GPU_depth_test_enabled(); + const eGPUDepthTest depth_test_enabled = GPU_depth_test_get(); if (use_depth) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); color[3] = 0.15f; draw_primitive_view_impl(C, ipd, color); } if (use_depth) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } color[3] = 1.0f; draw_primitive_view_impl(C, ipd, color); if (use_depth) { if (depth_test_enabled == false) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } } } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 9490c807989..f99301371d4 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -970,7 +970,7 @@ static bool do_lasso_select_curve(ViewContext *vc, /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } if (data.is_changed) { @@ -2772,7 +2772,7 @@ static bool do_nurbs_box_select(ViewContext *vc, rcti *rect, const eSelectOp sel /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } BKE_curve_nurb_vert_active_validate(vc->obedit->data); @@ -3693,7 +3693,6 @@ static bool nurbscurve_circle_select(ViewContext *vc, const bool select = (sel_op != SEL_OP_SUB); const bool deselect_all = (sel_op == SEL_OP_SET); CircleSelectUserData data; - bool changed = false; view3d_userdata_circleselect_init(&data, vc, select, mval, rad); @@ -3711,12 +3710,12 @@ static bool nurbscurve_circle_select(ViewContext *vc, /* Deselect items that were not added to selection (indicated by temp flag). */ if (deselect_all) { - BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); + data.is_changed |= BKE_nurbList_flag_set_from_flag(nurbs, BEZT_FLAG_TEMP_TAG, SELECT); } BKE_curve_nurb_vert_active_validate(vc->obedit->data); - return changed || data.is_changed; + return data.is_changed; } static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2]) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index ff9673a4262..d015b5dcc89 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1100,7 +1100,7 @@ int view3d_opengl_select(ViewContext *vc, wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, &rect); if (!XRAY_ACTIVE(v3d)) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } /* If in xray mode, we select the wires in priority. */ @@ -1165,7 +1165,7 @@ int view3d_opengl_select(ViewContext *vc, wm, vc->win, depsgraph, scene, region, v3d, vc->rv3d->viewmat, NULL, NULL); if (!XRAY_ACTIVE(v3d)) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } DRW_opengl_context_disable(); @@ -1732,6 +1732,8 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S { if (v3d->runtime.flag & V3D_RUNTIME_XR_SESSION_ROOT) { View3DShading *xr_shading = &wm->xr.session_settings.shading; + /* Flags that shouldn't be overridden by the 3D View shading. */ + const int flag_copy = V3D_SHADING_WORLD_ORIENTATION; BLI_assert(WM_xr_session_exists(&wm->xr)); @@ -1749,7 +1751,9 @@ void ED_view3d_xr_shading_update(wmWindowManager *wm, const View3D *v3d, const S } /* Copy shading from View3D to VR view. */ + const int old_xr_shading_flag = xr_shading->flag; *xr_shading = v3d->shading; + xr_shading->flag = (xr_shading->flag & ~flag_copy) | (old_xr_shading_flag & flag_copy); if (v3d->shading.prop) { xr_shading->prop = IDP_CopyProperty(xr_shading->prop); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 76cce5e725f..11f0e791d14 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -560,94 +560,6 @@ static void viewRedrawPost(bContext *C, TransInfo *t) #endif } -/* ************************** TRANSFORMATIONS **************************** */ - -static void view_editmove(ushort UNUSED(event)) -{ -#if 0 // TRANSFORM_FIX_ME - int refresh = 0; - /* Regular: Zoom in */ - /* Shift: Scroll up */ - /* Ctrl: Scroll right */ - /* Alt-Shift: Rotate up */ - /* Alt-Ctrl: Rotate right */ - - /* only work in 3D window for now - * In the end, will have to send to event to a 2D window handler instead - */ - if (Trans.flag & T_2D_EDIT) { - return; - } - - switch (event) { - case WHEELUPMOUSE: - if (G.qual & LR_SHIFTKEY) { - if (G.qual & LR_ALTKEY) { - G.qual &= ~LR_SHIFTKEY; - persptoetsen(PAD2); - G.qual |= LR_SHIFTKEY; - } - else { - persptoetsen(PAD2); - } - } - else if (G.qual & LR_CTRLKEY) { - if (G.qual & LR_ALTKEY) { - G.qual &= ~LR_CTRLKEY; - persptoetsen(PAD4); - G.qual |= LR_CTRLKEY; - } - else { - persptoetsen(PAD4); - } - } - else if (U.uiflag & USER_WHEELZOOMDIR) { - persptoetsen(PADMINUS); - } - else { - persptoetsen(PADPLUSKEY); - } - - refresh = 1; - break; - case WHEELDOWNMOUSE: - if (G.qual & LR_SHIFTKEY) { - if (G.qual & LR_ALTKEY) { - G.qual &= ~LR_SHIFTKEY; - persptoetsen(PAD8); - G.qual |= LR_SHIFTKEY; - } - else { - persptoetsen(PAD8); - } - } - else if (G.qual & LR_CTRLKEY) { - if (G.qual & LR_ALTKEY) { - G.qual &= ~LR_CTRLKEY; - persptoetsen(PAD6); - G.qual |= LR_CTRLKEY; - } - else { - persptoetsen(PAD6); - } - } - else if (U.uiflag & USER_WHEELZOOMDIR) { - persptoetsen(PADPLUSKEY); - } - else { - persptoetsen(PADMINUS); - } - - refresh = 1; - break; - } - - if (refresh) { - setTransformViewMatrices(&Trans); - } -#endif -} - /* ************************************************* */ static bool transform_modal_item_poll(const wmOperator *op, int value) @@ -770,6 +682,12 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""}, {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""}, + + {TFM_MODAL_AUTOCONSTRAINT, + "AUTOCONSTRAIN", + 0, + "Automatically detects one direction for constraint", + ""}, {0, NULL, 0, NULL, NULL}, }; @@ -778,6 +696,21 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) keymap = WM_modalkeymap_ensure(keyconf, "Transform Modal Map", modal_items); keymap->poll_modal_item = transform_modal_item_poll; + /* Default modal map values: + * + * \code{.c} + * WM_modalkeymap_add_item(keymap, EVT_RETKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CONFIRM); + * WM_modalkeymap_add_item(keymap, EVT_ESCKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_CANCEL); + * WM_modalkeymap_add_item(keymap, EVT_PAGEUPKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_AUTOIK_LEN_INC); + * WM_modalkeymap_add_item( + * keymap, EVT_PAGEDOWNKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_AUTOIK_LEN_DEC); + * WM_modalkeymap_add_item(keymap, EVT_GKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_TRANSLATE); + * WM_modalkeymap_add_item(keymap, EVT_RKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_ROTATE); + * WM_modalkeymap_add_item(keymap, EVT_SKEY, KM_PRESS, KM_ANY, 0, TFM_MODAL_RESIZE); + * WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, KM_ANY, 0, TFM_MODAL_AUTOCONSTRAINT); + * \endcode + */ + return keymap; } @@ -887,6 +820,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } /* handle modal keymap first */ + /* enforce redraw of transform when modifiers are used */ else if (event->type == EVT_MODAL_MAP) { switch (event->val) { case TFM_MODAL_CANCEL: @@ -1147,40 +1081,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) t->redraw |= TREDRAW_SOFT; } break; - /* Those two are only handled in transform's own handler, see T44634! */ - case TFM_MODAL_EDGESLIDE_UP: - case TFM_MODAL_EDGESLIDE_DOWN: - default: - break; - } - } - /* else do non-mapped events */ - else if (event->val == KM_PRESS) { - switch (event->type) { - case EVT_ESCKEY: - case RIGHTMOUSE: - t->state = TRANS_CANCEL; - handled = true; - break; - - case EVT_SPACEKEY: - case EVT_PADENTER: - case EVT_RETKEY: - if (event->is_repeat) { - break; - } - t->state = TRANS_CONFIRM; - handled = true; - break; - - /* enforce redraw of transform when modifiers are used */ - case EVT_LEFTSHIFTKEY: - case EVT_RIGHTSHIFTKEY: - t->modifiers |= MOD_CONSTRAINT_PLANE; - t->redraw |= TREDRAW_HARD; - handled = true; - break; - case MIDDLEMOUSE: + case TFM_MODAL_AUTOCONSTRAINT: if ((t->flag & T_NO_CONSTRAINT) == 0) { /* exception for switching to dolly, or trackball, in camera view */ if (t->flag & T_CAMERA) { @@ -1206,59 +1107,16 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } break; - case EVT_GKEY: - if (event->is_repeat) { - break; - } - /* only switch when... */ - if (t->mode != TFM_TRANSLATION && transform_mode_is_changeable(t->mode)) { - restoreTransObjects(t); - resetTransModal(t); - resetTransRestrictions(t); - transform_mode_init(t, NULL, TFM_TRANSLATION); - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; - handled = true; - } - break; - case EVT_SKEY: - if (event->is_repeat) { - break; - } - /* only switch when... */ - if (t->mode != TFM_RESIZE && transform_mode_is_changeable(t->mode)) { - restoreTransObjects(t); - resetTransModal(t); - resetTransRestrictions(t); - transform_mode_init(t, NULL, TFM_RESIZE); - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; - handled = true; - } - break; - case EVT_RKEY: - if (event->is_repeat) { - break; - } - /* only switch when... */ - if (!(t->options & CTX_TEXTURE)) { - if (transform_mode_is_changeable(t->mode)) { - restoreTransObjects(t); - resetTransModal(t); - resetTransRestrictions(t); - - if (t->mode == TFM_ROTATION) { - transform_mode_init(t, NULL, TFM_TRACKBALL); - } - else { - transform_mode_init(t, NULL, TFM_ROTATION); - } - initSnapping(t, NULL); // need to reinit after mode change - t->redraw |= TREDRAW_HARD; - handled = true; - } - } + /* Those two are only handled in transform's own handler, see T44634! */ + case TFM_MODAL_EDGESLIDE_UP: + case TFM_MODAL_EDGESLIDE_DOWN: + default: break; + } + } + /* Else do non-mapped events. */ + else if (event->val == KM_PRESS) { + switch (event->type) { case EVT_CKEY: if (event->is_repeat) { break; @@ -1295,17 +1153,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } break; - case EVT_PAGEUPKEY: - case WHEELDOWNMOUSE: - if (t->flag & T_AUTOIK) { - transform_autoik_update(t, 1); - } - else { - view_editmove(event->type); - } - t->redraw = TREDRAW_HARD; - handled = true; - break; case EVT_PADMINUS: if (event->alt && t->flag & T_PROP_EDIT) { t->prop_size /= (t->modifiers & MOD_PRECISION) ? 1.01f : 1.1f; @@ -1314,17 +1161,6 @@ int transformEvent(TransInfo *t, const wmEvent *event) handled = true; } break; - case EVT_PAGEDOWNKEY: - case WHEELUPMOUSE: - if (t->flag & T_AUTOIK) { - transform_autoik_update(t, -1); - } - else { - view_editmove(event->type); - } - t->redraw = TREDRAW_HARD; - handled = true; - break; case EVT_LEFTALTKEY: case EVT_RIGHTALTKEY: if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) { @@ -1357,31 +1193,29 @@ int transformEvent(TransInfo *t, const wmEvent *event) } else if (event->val == KM_RELEASE) { switch (event->type) { - case EVT_LEFTSHIFTKEY: - case EVT_RIGHTSHIFTKEY: - t->modifiers &= ~MOD_CONSTRAINT_PLANE; - t->redraw |= TREDRAW_HARD; - handled = true; - break; - - case MIDDLEMOUSE: - if ((t->flag & T_NO_CONSTRAINT) == 0) { - t->modifiers &= ~MOD_CONSTRAINT_SELECT; - postSelectConstraint(t); - t->redraw |= TREDRAW_HARD; - handled = true; - } - break; case EVT_LEFTALTKEY: case EVT_RIGHTALTKEY: + /* TODO: Modal Map */ if (ELEM(t->spacetype, SPACE_SEQ, SPACE_VIEW3D)) { t->flag &= ~T_ALT_TRANSFORM; t->redraw |= TREDRAW_HARD; handled = true; } break; - default: + default: { + /* Disable modifiers. */ + int modifiers = t->modifiers; + modifiers &= ~MOD_CONSTRAINT_SELECT; + if (modifiers != t->modifiers) { + if (t->modifiers & MOD_CONSTRAINT_SELECT) { + postSelectConstraint(t); + } + t->modifiers = modifiers; + t->redraw |= TREDRAW_HARD; + handled = true; + } break; + } } /* confirm transform if launch key is released after mouse move */ @@ -1544,16 +1378,14 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *region) #endif /* autokey recording icon... */ - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); xco -= U.widget_unit; yco -= (int)printable_size[1] / 2; UI_icon_draw(xco, yco, ICON_REC); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } static void drawTransformPixel(const struct bContext *C, ARegion *region, void *arg) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 1917d9463f4..1e4992e5f1a 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -79,7 +79,6 @@ typedef struct TransSnap { bool project; bool snap_self; bool peel; - bool snap_spatial_grid; bool use_backface_culling; char status; /* Snapped Element Type (currently for objects only). */ @@ -498,7 +497,6 @@ enum { MOD_PRECISION = 1 << 1, MOD_SNAP = 1 << 2, MOD_SNAP_INVERT = 1 << 3, - MOD_CONSTRAINT_PLANE = 1 << 4, }; /* use node center for transform instead of upper-left corner. @@ -576,6 +574,8 @@ enum { TFM_MODAL_PROPSIZE = 26, /* node editor insert offset (aka auto-offset) direction toggle */ TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27, + + TFM_MODAL_AUTOCONSTRAINT = 28, }; bool initTransform(struct bContext *C, diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index d0e37f22236..8fdee0e8eec 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -167,7 +167,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3]) { mul_m3_v3(t->spacemtx_inv, vec); - snapGridIncrement(t, vec); + transform_snap_increment(t, vec); if (t->flag & T_NULL_ONE) { if (!(t->con.mode & CON_AXIS0)) { @@ -785,7 +785,6 @@ void drawConstraint(TransInfo *t) else { if (tc->mode & CON_SELECT) { float vec[3]; - int depth_test_enabled; convertViewVec(t, vec, (t->mval[0] - t->con.imval[0]), (t->mval[1] - t->con.imval[1])); add_v3_v3(vec, t->center_global); @@ -794,9 +793,9 @@ void drawConstraint(TransInfo *t) drawLine(t, t->center_global, t->spacemtx[1], 'Y', 0); drawLine(t, t->center_global, t->spacemtx[2], 'Z', 0); - depth_test_enabled = GPU_depth_test_enabled(); + eGPUDepthTest depth_test_enabled = GPU_depth_test_get(); if (depth_test_enabled) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } const uint shdr_pos = GPU_vertformat_attr_add( @@ -821,7 +820,7 @@ void drawConstraint(TransInfo *t) immUnbindProgram(); if (depth_test_enabled) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } } @@ -843,7 +842,6 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; - int depth_test_enabled; if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); @@ -873,9 +871,9 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); } - depth_test_enabled = GPU_depth_test_enabled(); + eGPUDepthTest depth_test_enabled = GPU_depth_test_get(); if (depth_test_enabled) { - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); } uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -884,7 +882,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) float viewport[4]; GPU_viewport_size_get_f(viewport); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); immUniform2fv("viewportSize", &viewport[2]); immUniform1f("lineWidth", 3.0f * U.pixelsize); @@ -899,7 +897,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t) immUnbindProgram(); if (depth_test_enabled) { - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } GPU_matrix_pop(); @@ -1081,34 +1079,16 @@ static void setNearestAxis3d(TransInfo *t) } if (len[0] <= len[1] && len[0] <= len[2]) { - if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS1 | CON_AXIS2); - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s X axis"), t->spacename); - } - else { - t->con.mode |= CON_AXIS0; - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s X axis"), t->spacename); - } + t->con.mode |= CON_AXIS0; + BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s X axis"), t->spacename); } else if (len[1] <= len[0] && len[1] <= len[2]) { - if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS0 | CON_AXIS2); - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Y axis"), t->spacename); - } - else { - t->con.mode |= CON_AXIS1; - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Y axis"), t->spacename); - } + t->con.mode |= CON_AXIS1; + BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Y axis"), t->spacename); } else if (len[2] <= len[1] && len[2] <= len[0]) { - if (t->modifiers & MOD_CONSTRAINT_PLANE) { - t->con.mode |= (CON_AXIS0 | CON_AXIS1); - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" locking %s Z axis"), t->spacename); - } - else { - t->con.mode |= CON_AXIS2; - BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Z axis"), t->spacename); - } + t->con.mode |= CON_AXIS2; + BLI_snprintf(t->con.text, sizeof(t->con.text), TIP_(" along %s Z axis"), t->spacename); } } diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 573f4550fec..7ad54a56545 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -507,7 +507,7 @@ static void editmesh_mirror_data_calc(BMEditMesh *em, index[a] = MEM_mallocN(totvert * sizeof(*index[a]), __func__); EDBM_verts_mirror_cache_begin_ex( - em, a, false, test_selected_only, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]); + em, a, false, test_selected_only, true, use_topology, TRANSFORM_MAXDIST_MIRROR, index[a]); flag = TD_MIRROR_X << a; BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 2e92b4e5c09..4bf0f842f2f 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -346,7 +346,7 @@ static void set_trans_object_base_flags(TransInfo *t) ViewLayer *view_layer = t->view_layer; View3D *v3d = t->view; Scene *scene = t->scene; - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); + Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer); /* NOTE: if Base selected and has parent selected: * base->flag_legacy = BA_WAS_SEL */ @@ -357,7 +357,7 @@ static void set_trans_object_base_flags(TransInfo *t) /* Makes sure base flags and object flags are identical. */ BKE_scene_base_flag_to_objects(t->view_layer); /* Make sure depsgraph is here. */ - DEG_graph_relations_update(depsgraph, bmain, scene, view_layer); + DEG_graph_relations_update(depsgraph); /* Clear all flags we need. It will be used to detect dependencies. */ trans_object_base_deps_flag_prepare(view_layer); /* Traverse all bases and set all possible flags. */ @@ -421,7 +421,7 @@ static int count_proportional_objects(TransInfo *t) View3D *v3d = t->view; struct Main *bmain = CTX_data_main(t->context); Scene *scene = t->scene; - Depsgraph *depsgraph = BKE_scene_get_depsgraph(bmain, scene, view_layer, true); + Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer); /* Clear all flags we need. It will be used to detect dependencies. */ trans_object_base_deps_flag_prepare(view_layer); /* Rotations around local centers are allowed to propagate, so we take all objects. */ diff --git a/source/blender/editors/transform/transform_draw_cursors.c b/source/blender/editors/transform/transform_draw_cursors.c index 95ca5ae0c30..84fc45e2b45 100644 --- a/source/blender/editors/transform/transform_draw_cursors.c +++ b/source/blender/editors/transform/transform_draw_cursors.c @@ -191,7 +191,7 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd } GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); @@ -339,6 +339,6 @@ void transform_draw_cursor_draw(bContext *UNUSED(C), int x, int y, void *customd GPU_matrix_pop(); GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 6155042f555..14ef5e87534 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -1343,8 +1343,8 @@ void drawDial3d(const TransInfo *t) BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END); gizmo_get_axis_color(axis_idx, NULL, color, color); - GPU_depth_test(false); - GPU_blend(true); + GPU_depth_test(GPU_DEPTH_NONE); + GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); ED_gizmotypes_dial_3d_draw_util(mat_basis, @@ -1359,8 +1359,8 @@ void drawDial3d(const TransInfo *t) }); GPU_line_smooth(false); - GPU_depth_test(true); - GPU_blend(false); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); + GPU_blend(GPU_BLEND_NONE); } } diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index 495c21bc755..edc0781e18e 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -1014,7 +1014,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma /* scale stroke thickness */ if (td->val) { - snapGridIncrement(t, t->values_final); + transform_snap_increment(t, t->values_final); applyNumInput(&t->num, t->values_final); float ratio = t->values_final[0]; diff --git a/source/blender/editors/transform/transform_mode_baketime.c b/source/blender/editors/transform/transform_mode_baketime.c index 4e7fc3578ce..235b04b1858 100644 --- a/source/blender/editors/transform/transform_mode_baketime.c +++ b/source/blender/editors/transform/transform_mode_baketime.c @@ -67,7 +67,7 @@ static void applyBakeTime(TransInfo *t, const int mval[2]) time = (float)(t->center2d[0] - mval[0]) * fac; } - snapGridIncrement(t, &time); + transform_snap_increment(t, &time); applyNumInput(&t->num, &time); diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c index 80a5b307a91..d067c9df418 100644 --- a/source/blender/editors/transform/transform_mode_bbone_resize.c +++ b/source/blender/editors/transform/transform_mode_bbone_resize.c @@ -124,7 +124,7 @@ static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2])) copy_v3_fl(t->values_final, ratio); - snapGridIncrement(t, t->values_final); + transform_snap_increment(t, t->values_final); if (applyNumInput(&t->num, t->values_final)) { constraintNumInput(t, t->values_final); diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c index 3b51626b170..86de40448b7 100644 --- a/source/blender/editors/transform/transform_mode_bend.c +++ b/source/blender/editors/transform/transform_mode_bend.c @@ -104,7 +104,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) const float radius_snap = 0.1f; const float snap_hack = (t->snap[1] * data->warp_init_dist) / radius_snap; values.scale *= snap_hack; - snapGridIncrement(t, values.vector); + transform_snap_increment(t, values.vector); values.scale /= snap_hack; } #endif diff --git a/source/blender/editors/transform/transform_mode_boneenvelope.c b/source/blender/editors/transform/transform_mode_boneenvelope.c index b7a34769f5a..7f5a8fedeef 100644 --- a/source/blender/editors/transform/transform_mode_boneenvelope.c +++ b/source/blender/editors/transform/transform_mode_boneenvelope.c @@ -53,7 +53,7 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_boneroll.c b/source/blender/editors/transform/transform_mode_boneroll.c index 1503519c519..8805d54e1f8 100644 --- a/source/blender/editors/transform/transform_mode_boneroll.c +++ b/source/blender/editors/transform/transform_mode_boneroll.c @@ -54,7 +54,7 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGridIncrement(t, &final); + transform_snap_increment(t, &final); applyNumInput(&t->num, &final); diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c index 84e4e950804..fd65b019fe0 100644 --- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c @@ -53,7 +53,7 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c index 399cec2d62c..4d6e25dbe34 100644 --- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c +++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c @@ -55,7 +55,7 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2])) CLAMP_MAX(weight, 1.0f); - snapGridIncrement(t, &weight); + transform_snap_increment(t, &weight); applyNumInput(&t->num, &weight); diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c index 53c948c742b..a1822d99ff9 100644 --- a/source/blender/editors/transform/transform_mode_edge_crease.c +++ b/source/blender/editors/transform/transform_mode_edge_crease.c @@ -55,7 +55,7 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) CLAMP_MAX(crease, 1.0f); - snapGridIncrement(t, &crease); + transform_snap_increment(t, &crease); applyNumInput(&t->num, &crease); diff --git a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c index fde0d5b187e..5b929c39915 100644 --- a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c +++ b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c @@ -99,7 +99,7 @@ static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2])) float angle = t->values[0]; copy_v3_v3(axis, axis_final); - snapGridIncrement(t, &angle); + transform_snap_increment(t, &angle); applySnapping(t, &angle); diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index c1cb4325c09..141f9acdeb4 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -102,7 +102,7 @@ static void applySeqSlide(TransInfo *t, const int mval[2]) copy_v3_v3(t->values_final, tvec); } else { - // snapGridIncrement(t, t->values); + // transform_snap_increment(t, t->values); applyNumInput(&t->num, t->values); copy_v3_v3(t->values_final, t->values); } diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 1886f95beae..7d0e555e362 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1147,11 +1147,9 @@ void drawEdgeSlide(TransInfo *t) const float line_size = UI_GetThemeValuef(TH_OUTLINE_WIDTH) + 0.5f; - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); @@ -1266,9 +1264,9 @@ void drawEdgeSlide(TransInfo *t) GPU_matrix_pop(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } static void edge_slide_snap_apply(TransInfo *t, float *value) @@ -1465,7 +1463,9 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; applySnapping(t, &final); - snapGridIncrement(t, &final); + if (!validSnap(t)) { + transform_snap_increment(t, &final); + } /* only do this so out of range values are not displayed */ if (is_constrained) { diff --git a/source/blender/editors/transform/transform_mode_gpopacity.c b/source/blender/editors/transform/transform_mode_gpopacity.c index 4712fb7ba01..11c63be156c 100644 --- a/source/blender/editors/transform/transform_mode_gpopacity.c +++ b/source/blender/editors/transform/transform_mode_gpopacity.c @@ -53,7 +53,7 @@ static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c index ab9a0aa79ed..c025dbcaccb 100644 --- a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c @@ -53,7 +53,7 @@ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c index 68f3abda85b..3ac35ae7780 100644 --- a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c @@ -54,7 +54,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_push_pull.c b/source/blender/editors/transform/transform_mode_push_pull.c index 4a2f979ec38..2b17f208e79 100644 --- a/source/blender/editors/transform/transform_mode_push_pull.c +++ b/source/blender/editors/transform/transform_mode_push_pull.c @@ -55,7 +55,7 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2])) distance = t->values[0]; - snapGridIncrement(t, &distance); + transform_snap_increment(t, &distance); applyNumInput(&t->num, &distance); diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 5fb46b30e0d..b4245abcc12 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -91,7 +91,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2])) copy_v3_fl(t->values_final, ratio); - snapGridIncrement(t, t->values_final); + transform_snap_increment(t, t->values_final); if (applyNumInput(&t->num, t->values_final)) { constraintNumInput(t, t->values_final); diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index 4fa5dffc473..c0ddd4eb2a6 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -200,7 +200,7 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGridIncrement(t, &final); + transform_snap_increment(t, &final); float axis_final[3]; /* Use the negative axis to match the default Z axis of the view matrix. */ diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c index e508a1fa4c2..18968494395 100644 --- a/source/blender/editors/transform/transform_mode_shear.c +++ b/source/blender/editors/transform/transform_mode_shear.c @@ -128,7 +128,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2])) value = t->values[0]; - snapGridIncrement(t, &value); + transform_snap_increment(t, &value); applyNumInput(&t->num, &value); diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c index 6302bc96330..2f221181d12 100644 --- a/source/blender/editors/transform/transform_mode_shrink_fatten.c +++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c @@ -56,7 +56,7 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) distance = t->values[0]; - snapGridIncrement(t, &distance); + transform_snap_increment(t, &distance); applyNumInput(&t->num, &distance); diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c index 23d83050613..665c616bc2b 100644 --- a/source/blender/editors/transform/transform_mode_skin_resize.c +++ b/source/blender/editors/transform/transform_mode_skin_resize.c @@ -55,7 +55,7 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2])) else { copy_v3_fl(t->values_final, t->values[0]); - snapGridIncrement(t, t->values_final); + transform_snap_increment(t, t->values_final); if (applyNumInput(&t->num, t->values_final)) { constraintNumInput(t, t->values_final); diff --git a/source/blender/editors/transform/transform_mode_tilt.c b/source/blender/editors/transform/transform_mode_tilt.c index ca0a8818477..5ab23000039 100644 --- a/source/blender/editors/transform/transform_mode_tilt.c +++ b/source/blender/editors/transform/transform_mode_tilt.c @@ -54,7 +54,7 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; - snapGridIncrement(t, &final); + transform_snap_increment(t, &final); applyNumInput(&t->num, &final); diff --git a/source/blender/editors/transform/transform_mode_tosphere.c b/source/blender/editors/transform/transform_mode_tosphere.c index f6c5448a906..e747f0e75d0 100644 --- a/source/blender/editors/transform/transform_mode_tosphere.c +++ b/source/blender/editors/transform/transform_mode_tosphere.c @@ -54,7 +54,7 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2])) ratio = t->values[0]; - snapGridIncrement(t, &ratio); + transform_snap_increment(t, &ratio); applyNumInput(&t->num, &ratio); diff --git a/source/blender/editors/transform/transform_mode_trackball.c b/source/blender/editors/transform/transform_mode_trackball.c index ca5a749b275..2656411e8ab 100644 --- a/source/blender/editors/transform/transform_mode_trackball.c +++ b/source/blender/editors/transform/transform_mode_trackball.c @@ -93,7 +93,7 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2])) copy_v2_v2(phi, t->values); - snapGridIncrement(t, phi); + transform_snap_increment(t, phi); applyNumInput(&t->num, phi); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index c083e1654dc..36be26049d3 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -362,15 +362,28 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) } else { copy_v3_v3(global_dir, t->values); - if ((t->con.mode & CON_APPLY) == 0) { - snapGridIncrement(t, global_dir); - } - if (applyNumInput(&t->num, global_dir)) { removeAspectRatio(t, global_dir); } + else { + applySnapping(t, global_dir); + + if (!validSnap(t) && !(t->con.mode & CON_APPLY)) { + float dist_sq = FLT_MAX; + if (transform_snap_grid(t, global_dir)) { + dist_sq = len_squared_v3v3(t->values, global_dir); + } - applySnapping(t, global_dir); + /* Check the snap distance to the initial value to work with mixed snap. */ + float increment_loc[3]; + copy_v3_v3(increment_loc, t->values); + if (transform_snap_increment(t, increment_loc)) { + if ((dist_sq == FLT_MAX) || (len_squared_v3v3(t->values, increment_loc) < dist_sq)) { + copy_v3_v3(global_dir, increment_loc); + } + } + } + } } if (t->con.mode & CON_APPLY) { diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 38537194af3..75b973b6b14 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -390,11 +390,9 @@ void drawVertSlide(TransInfo *t) const int alpha_shade = -160; int i; - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); - GPU_blend(true); - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); GPU_matrix_push(); GPU_matrix_mul(TRANS_DATA_CONTAINER_FIRST_OK(t)->obedit->obmat); @@ -487,7 +485,7 @@ void drawVertSlide(TransInfo *t) GPU_matrix_pop(); - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } } } @@ -589,7 +587,9 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0]; applySnapping(t, &final); - snapGridIncrement(t, &final); + if (!validSnap(t)) { + transform_snap_increment(t, &final); + } /* only do this so out of range values are not displayed */ if (is_constrained) { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index ab9548ad52e..d35c2f07482 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -993,8 +993,7 @@ static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot) { /* identifiers */ ot->name = "To Sphere"; - // added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" - ot->description = "Move selected vertices outward in a spherical shape around mesh center"; + ot->description = "Move selected items outward in a spherical shape around geometric center"; ot->idname = OP_TOSPHERE; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index a700dd320b7..1813acadb9e 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -184,7 +184,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) const float *loc_prev = NULL; const float *normal = NULL; - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); RegionView3D *rv3d = CTX_wm_region_view3d(C); if (!BLI_listbase_is_empty(&t->tsnap.points)) { @@ -228,7 +228,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) ED_gizmotypes_snap_3d_draw_util( rv3d, loc_prev, loc_cur, normal, col, activeCol, t->tsnap.snapElem); - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } } else if (t->spacetype == SPACE_IMAGE) { @@ -245,7 +245,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) size = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); uint pos = GPU_vertformat_attr_add( immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); @@ -271,7 +271,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t) immUnbindProgram(); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -378,30 +378,14 @@ void applyProject(TransInfo *t) void applyGridAbsolute(TransInfo *t) { - float grid_size = 0.0f; - GearsType grid_action; int i; if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { return; } - grid_action = BIG_GEARS; - if (t->modifiers & MOD_PRECISION) { - grid_action = SMALL_GEARS; - } + float grid_size = (t->modifiers & MOD_PRECISION) ? t->snap_spatial[2] : t->snap_spatial[1]; - switch (grid_action) { - case NO_GEARS: - grid_size = t->snap_spatial[0]; - break; - case BIG_GEARS: - grid_size = t->snap_spatial[1]; - break; - case SMALL_GEARS: - grid_size = t->snap_spatial[2]; - break; - } /* early exit on unusable grid size */ if (grid_size == 0.0f) { return; @@ -445,7 +429,12 @@ void applyGridAbsolute(TransInfo *t) void applySnapping(TransInfo *t, float *vec) { /* Each Trans Data already makes the snap to face */ - if (doForceIncrementSnap(t) || (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE)) { + if (doForceIncrementSnap(t)) { + return; + } + + if (t->tsnap.project && t->tsnap.mode == SCE_SNAP_MODE_FACE) { + /* The snap has already been resolved for each transdata. */ return; } @@ -559,6 +548,12 @@ static void initSnappingMode(TransInfo *t) } t->tsnap.mode = ts->snap_mode; + if ((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && (ts->snap_flag & SCE_SNAP_ABS_GRID) && + (t->mode == TFM_TRANSLATION)) { + /* Special case in which snap to increments is transformed to snap to grid. */ + t->tsnap.mode &= ~SCE_SNAP_MODE_INCREMENT; + t->tsnap.mode |= SCE_SNAP_MODE_GRID; + } } if ((t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) && (t->flag & T_CAMERA) == 0) { @@ -600,7 +595,7 @@ static void initSnappingMode(TransInfo *t) } } else { - /* Grid if snap is not possible */ + /* Increment if snap is not possible */ t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; } } @@ -613,7 +608,7 @@ static void initSnappingMode(TransInfo *t) t->tsnap.mode = SCE_SNAP_MODE_GRID; /* Dummy, should we rather add a NOP mode? */ } else { - /* Always grid outside of 3D view */ + /* Always increment outside of 3D view */ t->tsnap.mode = SCE_SNAP_MODE_INCREMENT; } @@ -686,11 +681,6 @@ void initSnapping(TransInfo *t, wmOperator *op) t->tsnap.snap_self = !((t->settings->snap_flag & SCE_SNAP_NO_SELF) != 0); t->tsnap.peel = ((t->settings->snap_flag & SCE_SNAP_PROJECT) != 0); } - - /* for now only 3d view (others can be added if we want) */ - if (t->spacetype == SPACE_VIEW3D) { - t->tsnap.snap_spatial_grid = ((t->settings->snap_flag & SCE_SNAP_ABS_GRID) != 0); - } } t->tsnap.target = snap_target; @@ -832,11 +822,6 @@ void getSnapPoint(const TransInfo *t, float vec[3]) /** \name Calc Snap (Generic) * \{ */ -static void UNUSED_FUNCTION(CalcSnapGrid)(TransInfo *t, float *UNUSED(vec)) -{ - snapGridIncrementAction(t, t->tsnap.snapPoint, BIG_GEARS); -} - static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec)) { if (t->spacetype == SPACE_VIEW3D) { @@ -1407,77 +1392,160 @@ void snapFrameTransform(TransInfo *t, /*================================================================*/ -static void applyGridIncrement( - TransInfo *t, float *val, int max_index, const float fac[3], GearsType action); - -void snapGridIncrementAction(TransInfo *t, float *val, GearsType action) +void snapSequenceBounds(TransInfo *t, const int mval[2]) { - float fac[3]; + /* Reuse increment, strictly speaking could be another snap mode, but leave as is. */ + if (!(t->modifiers & MOD_SNAP_INVERT)) { + return; + } + + /* Convert to frame range. */ + float xmouse, ymouse; + UI_view2d_region_to_view(&t->region->v2d, mval[0], mval[1], &xmouse, &ymouse); + const int frame_curr = round_fl_to_int(xmouse); - fac[NO_GEARS] = t->snap[0]; - fac[BIG_GEARS] = t->snap[1]; - fac[SMALL_GEARS] = t->snap[2]; + /* Now find the closest sequence. */ + const int frame_near = BKE_sequencer_find_next_prev_edit( + t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true); - applyGridIncrement(t, val, t->idx_max, fac, action); + const int frame_snap = transform_convert_sequencer_get_snap_bound(t); + t->values[0] = frame_near - frame_snap; } -void snapGridIncrement(TransInfo *t, float *val) +static void snap_grid_apply_ex( + TransInfo *t, const int max_index, const float grid_dist, const float loc[3], float r_out[3]) { - GearsType action; + const float *center_global = t->center_global; + const float *asp = t->aspect; + bool use_local_axis = false; - /* only do something if using absolute or incremental grid snapping - * and there is no valid snap point */ - if ((!(t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) || validSnap(t)) && - !doForceIncrementSnap(t)) { - return; + /* use a fallback for cursor selection, + * this isn't useful as a global center for absolute grid snapping + * since its not based on the position of the selection. */ + if (t->around == V3D_AROUND_CURSOR) { + const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN); + center_global = cd->global; } - action = activeSnap(t) ? BIG_GEARS : NO_GEARS; - - if (action == BIG_GEARS && (t->modifiers & MOD_PRECISION)) { - action = SMALL_GEARS; + if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) { + use_local_axis = true; } - snapGridIncrementAction(t, val, action); + for (int i = 0; i <= max_index; i++) { + /* do not let unconstrained axis jump to absolute grid increments */ + if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) { + const float iter_fac = grid_dist * asp[i]; + + if (use_local_axis) { + float local_axis[3]; + float pos_on_axis[3]; + + copy_v3_v3(local_axis, t->spacemtx[i]); + copy_v3_v3(pos_on_axis, t->spacemtx[i]); + + /* amount of movement on axis from initial pos */ + mul_v3_fl(pos_on_axis, loc[i]); + + /* actual global position on axis */ + add_v3_v3(pos_on_axis, center_global); + + float min_dist = INFINITY; + for (int j = 0; j < 3; j++) { + if (fabs(local_axis[j]) < 0.01f) { + /* Ignore very small (normalized) axis changes */ + continue; + } + + /* closest point on grid */ + float grid_p = iter_fac * roundf(pos_on_axis[j] / iter_fac); + float dist_p = fabs((grid_p - pos_on_axis[j]) / local_axis[j]); + + /* The amount of distance needed to travel along the + * local axis to snap to the closest grid point */ + /* in the global j axis direction */ + float move_dist = (grid_p - center_global[j]) / local_axis[j]; + + if (dist_p < min_dist) { + min_dist = dist_p; + r_out[i] = move_dist; + } + } + } + else { + r_out[i] = iter_fac * roundf((loc[i] + center_global[i]) / iter_fac) - center_global[i]; + } + } + } } -void snapSequenceBounds(TransInfo *t, const int mval[2]) +static void snap_grid_apply(TransInfo *t, int max_index, const float grid_dist, float *r_val) { - /* Reuse increment, strictly speaking could be another snap mode, but leave as is. */ - if (!(t->modifiers & MOD_SNAP_INVERT)) { + BLI_assert(t->tsnap.mode & SCE_SNAP_MODE_GRID); + BLI_assert(max_index <= 2); + + /* Early bailing out if no need to snap */ + if (grid_dist == 0.0f) { return; } - /* Convert to frame range. */ - float xmouse, ymouse; - UI_view2d_region_to_view(&t->region->v2d, mval[0], mval[1], &xmouse, &ymouse); - const int frame_curr = round_fl_to_int(xmouse); + /* absolute snapping on grid based on global center. + * for now only 3d view (others can be added if we want) */ + snap_grid_apply_ex(t, max_index, grid_dist, r_val, r_val); +} - /* Now find the closest sequence. */ - const int frame_near = BKE_sequencer_find_next_prev_edit( - t->scene, frame_curr, SEQ_SIDE_BOTH, true, false, true); +bool transform_snap_grid(TransInfo *t, float *val) +{ + if ((!(t->tsnap.mode & SCE_SNAP_MODE_GRID)) || validSnap(t)) { + /* Don't do grid snapping if there is a valid snap point. */ + return false; + } - const int frame_snap = transform_convert_sequencer_get_snap_bound(t); - t->values[0] = frame_near - frame_snap; + if (t->spacetype != SPACE_VIEW3D) { + return false; + } + + if (t->mode != TFM_TRANSLATION) { + return false; + } + + float grid_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] : + t->snap[0]; + + snap_grid_apply(t, t->idx_max, grid_dist, val); + return true; } -static void applyGridIncrement( - TransInfo *t, float *val, int max_index, const float fac[3], GearsType action) +static void snap_increment_apply_ex(TransInfo *UNUSED(t), + const int max_index, + const float increment_val, + const float aspect[3], + const float loc[3], + float r_out[3]) { - float asp_local[3] = {1, 1, 1}; - const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION); - const float *asp = use_aspect ? t->aspect : asp_local; - int i; + /* relative snapping in fixed increments */ + for (int i = 0; i <= max_index; i++) { + const float iter_fac = increment_val * aspect[i]; + r_out[i] = iter_fac * roundf(loc[i] / iter_fac); + } +} - BLI_assert((t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) || - doForceIncrementSnap(t)); +static void snap_increment_apply(TransInfo *t, + int max_index, + const float increment_dist, + float *r_val) +{ + BLI_assert((t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) || doForceIncrementSnap(t)); BLI_assert(max_index <= 2); /* Early bailing out if no need to snap */ - if (fac[action] == 0.0f) { + if (increment_dist == 0.0f) { return; } + float asp_local[3] = {1, 1, 1}; + const bool use_aspect = ELEM(t->mode, TFM_TRANSLATION); + const float *asp = use_aspect ? t->aspect : asp_local; + if (use_aspect) { /* custom aspect for fcurve */ if (t->spacetype == SPACE_GRAPH) { @@ -1491,76 +1559,26 @@ static void applyGridIncrement( } } - /* absolute snapping on grid based on global center */ - if ((t->tsnap.snap_spatial_grid) && (t->mode == TFM_TRANSLATION)) { - const float *center_global = t->center_global; - bool use_local_axis = false; - - /* use a fallback for cursor selection, - * this isn't useful as a global center for absolute grid snapping - * since its not based on the position of the selection. */ - if (t->around == V3D_AROUND_CURSOR) { - const TransCenterData *cd = transformCenter_from_type(t, V3D_AROUND_CENTER_MEDIAN); - center_global = cd->global; - } - - if (t->con.mode & (CON_AXIS0 | CON_AXIS1 | CON_AXIS2)) { - use_local_axis = true; - } - - for (i = 0; i <= max_index; i++) { - /* do not let unconstrained axis jump to absolute grid increments */ - if (!(t->con.mode & CON_APPLY) || t->con.mode & (CON_AXIS0 << i)) { - const float iter_fac = fac[action] * asp[i]; - - if (use_local_axis) { - float local_axis[3]; - float pos_on_axis[3]; - - copy_v3_v3(local_axis, t->spacemtx[i]); - copy_v3_v3(pos_on_axis, t->spacemtx[i]); - - /* amount of movement on axis from initial pos */ - mul_v3_fl(pos_on_axis, val[i]); - - /* actual global position on axis */ - add_v3_v3(pos_on_axis, center_global); + snap_increment_apply_ex(t, max_index, increment_dist, asp, r_val, r_val); +} - float min_dist = INFINITY; - for (int j = 0; j < 3; j++) { - if (fabs(local_axis[j]) < 0.01f) { - /* Ignore very small (normalized) axis changes */ - continue; - } +bool transform_snap_increment(TransInfo *t, float *val) +{ + if (!(t->tsnap.mode & SCE_SNAP_MODE_INCREMENT) && !doForceIncrementSnap(t)) { + return false; + } - /* closest point on grid */ - float grid_p = iter_fac * roundf(pos_on_axis[j] / iter_fac); - float dist_p = fabs((grid_p - pos_on_axis[j]) / local_axis[j]); + if (t->spacetype != SPACE_VIEW3D && validSnap(t)) { + /* Only do something if using absolute or incremental grid snapping + * and there is no valid snap point. */ + return false; + } - /* The amount of distance needed to travel along the - * local axis to snap to the closest grid point */ - /* in the global j axis direction */ - float move_dist = (grid_p - center_global[j]) / local_axis[j]; + float increment_dist = activeSnap(t) ? (t->modifiers & MOD_PRECISION) ? t->snap[2] : t->snap[1] : + t->snap[0]; - if (dist_p < min_dist) { - min_dist = dist_p; - val[i] = move_dist; - } - } - } - else { - val[i] = iter_fac * roundf((val[i] + center_global[i]) / iter_fac) - center_global[i]; - } - } - } - } - else { - /* relative snapping in fixed increments */ - for (i = 0; i <= max_index; i++) { - const float iter_fac = fac[action] * asp[i]; - val[i] = iter_fac * roundf(val[i] / iter_fac); - } - } + snap_increment_apply(t, t->idx_max, increment_dist, val); + return true; } /** \} */ diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h index b97a9dc882c..5bee572c603 100644 --- a/source/blender/editors/transform/transform_snap.h +++ b/source/blender/editors/transform/transform_snap.h @@ -54,16 +54,10 @@ void snapFrameTransform(struct TransInfo *t, /* return args */ float *r_val); -typedef enum { - NO_GEARS = 0, - BIG_GEARS = 1, - SMALL_GEARS = 2, -} GearsType; - bool transformModeUseSnap(const TransInfo *t); -void snapGridIncrement(TransInfo *t, float *val); -void snapGridIncrementAction(TransInfo *t, float *val, GearsType action); +bool transform_snap_increment(TransInfo *t, float *val); +bool transform_snap_grid(TransInfo *t, float *val); void snapSequenceBounds(TransInfo *t, const int mval[2]); diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index 3e85342e0d7..a6eed5d54d1 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -305,7 +305,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e Scene *scene = CTX_data_scene(C); SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C); ARegion *region = CTX_wm_region(C); - ImBuf *ibuf = sequencer_ibuf_get(bmain, depsgraph, scene, sseq, CFRA, 0, NULL); + ImBuf *ibuf = sequencer_ibuf_get(bmain, region, depsgraph, scene, sseq, CFRA, 0, NULL); ImageSampleInfo *info = op->customdata; float fx, fy; diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 384da6fb931..041b2fec00b 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -38,7 +38,7 @@ #include "WM_types.h" #ifdef WITH_PYTHON -# include "BPY_extern.h" +# include "BPY_extern_run.h" #endif #include "ED_numinput.h" @@ -294,10 +294,10 @@ bool user_string_to_number(bContext *C, bUnit_ReplaceString( str_unit_convert, sizeof(str_unit_convert), str, unit_scale, unit->system, type); - return BPY_execute_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value); + return BPY_run_string_as_number(C, NULL, str_unit_convert, error_prefix, r_value); } - int success = BPY_execute_string_as_number(C, NULL, str, error_prefix, r_value); + int success = BPY_run_string_as_number(C, NULL, str, error_prefix, r_value); *r_value *= bUnit_PreferredInputUnitScalar(unit, type); *r_value /= unit_scale; return success; diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index df8d3cfb8db..044fca2310c 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -237,10 +237,10 @@ static void draw_uvs_shadow(SpaceImage *sima, if (edges) { if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } else if (overlay_alpha < 1.0f) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } col[3] = overlay_alpha; @@ -250,10 +250,10 @@ static void draw_uvs_shadow(SpaceImage *sima, if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else if (overlay_alpha < 1.0f) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } } @@ -288,10 +288,6 @@ static void draw_uvs_texpaint(const Scene *scene, Object *ob, Depsgraph *depsgra uint idx = 0; bool prev_ma_match = (mpoly->mat_nr == (ob_eval->actcol - 1)); - GPU_matrix_bind(geom->interface); - GPU_shader_set_srgb_uniform(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. * (not implemented in GPU module at the time of writing). */ @@ -299,7 +295,7 @@ static void draw_uvs_texpaint(const Scene *scene, Object *ob, Depsgraph *depsgra bool ma_match = (mpoly->mat_nr == (ob_eval->actcol - 1)); if (ma_match != prev_ma_match) { if (ma_match == false) { - GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0); + GPU_batch_draw_range(geom, draw_start, idx - draw_start); } else { draw_start = idx; @@ -309,10 +305,8 @@ static void draw_uvs_texpaint(const Scene *scene, Object *ob, Depsgraph *depsgra prev_ma_match = ma_match; } if (prev_ma_match == true) { - GPU_batch_draw_advanced(geom, draw_start, idx - draw_start, 0, 0); + GPU_batch_draw_range(geom, draw_start, idx - draw_start); } - - GPU_batch_program_use_end(geom); } else { GPU_batch_draw(geom); @@ -355,8 +349,7 @@ static void draw_uvs(SpaceImage *sima, interpedges = (ts->uv_selectmode == UV_SELECT_VERTEX); } - GPU_blend_set_func_separate( - GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); + GPU_blend(GPU_BLEND_ALPHA); if (batch->faces) { GPU_batch_program_set_builtin(batch->faces, @@ -366,7 +359,7 @@ static void draw_uvs(SpaceImage *sima, GPU_SHADER_2D_UV_FACES); if (!draw_stretch) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); UI_GetThemeColor4fv(TH_FACE, col1); UI_GetThemeColor4fv(TH_FACE_SELECT, col2); @@ -393,16 +386,16 @@ static void draw_uvs(SpaceImage *sima, GPU_batch_draw(batch->faces); if (!draw_stretch) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } if (batch->edges) { if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(true); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } else if (overlay_alpha < 1.0f) { - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); } { @@ -455,24 +448,26 @@ static void draw_uvs(SpaceImage *sima, } col1[3] = overlay_alpha; + GPU_batch_program_set_builtin(batch->edges, shader); + /* Inner Line. Use depth test to insure selection is drawn on top. */ - GPU_depth_test(true); + GPU_depth_test(GPU_DEPTH_LESS_EQUAL); GPU_line_width(1.0f); GPU_batch_uniform_4fv(batch->edges, "edgeColor", col1); GPU_batch_uniform_4fv(batch->edges, "selectColor", col2); GPU_batch_uniform_1f(batch->edges, "dashWidth", dash_width); GPU_batch_draw(batch->edges); - GPU_depth_test(false); + GPU_depth_test(GPU_DEPTH_NONE); GPU_provoking_vertex(GPU_VERTEX_LAST); } if (sima->flag & SI_SMOOTH_UV) { GPU_line_smooth(false); - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } else if (overlay_alpha < 1.0f) { - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); } } @@ -482,7 +477,7 @@ static void draw_uvs(SpaceImage *sima, const float point_size = UI_GetThemeValuef(TH_VERTEX_SIZE); const float pinned_col[4] = {1.0f, 0.0f, 0.0f, 1.0f}; /* TODO Theme? */ UI_GetThemeColor4fv(TH_VERTEX, col1); - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); GPU_program_point_size(true); GPU_batch_program_set_builtin(batch->verts, GPU_SHADER_2D_UV_VERTS); @@ -491,7 +486,12 @@ static void draw_uvs(SpaceImage *sima, GPU_batch_uniform_4fv(batch->verts, "pinnedColor", pinned_col); GPU_batch_uniform_1f(batch->verts, "pointSize", (point_size + 1.5f) * M_SQRT2); GPU_batch_uniform_1f(batch->verts, "outlineWidth", 0.75f); - GPU_batch_draw(batch->verts); + + /* #GPU_batch_draw_advanced is needed as unbinding the shader and redrawing + * causes the vertices not to draw at the right size. */ + GPU_shader_bind(batch->verts->shader); + + GPU_batch_draw_advanced(batch->verts, 0, 0, 0, 0); /* We have problem in this mode when face order make some verts * appear unselected because an adjacent face is not selected and @@ -500,9 +500,13 @@ static void draw_uvs(SpaceImage *sima, * on top. A bit overkill but it's simple. */ GPU_batch_uniform_4fv(batch->verts, "vertColor", transparent); GPU_batch_uniform_4fv(batch->verts, "selectColor", col2); - GPU_batch_draw(batch->verts); - GPU_blend(false); + GPU_batch_draw_advanced(batch->verts, 0, 0, 0, 0); + + GPU_shader_unbind(); + /* Finish #GPU_batch_draw_advanced drawing. */ + + GPU_blend(GPU_BLEND_NONE); GPU_program_point_size(false); } if (batch->facedots) { @@ -557,8 +561,8 @@ void ED_uvedit_draw_main(SpaceImage *sima, Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( view_layer, ((View3D *)NULL), &objects_len); if (objects_len > 0) { + GPU_depth_mask(true); GPU_clear_depth(1.0f); - GPU_clear(GPU_DEPTH_BIT); } /* go over all objects and create the batches + add their areas to the total */ diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 5a510aaf945..306f8a2c561 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -42,9 +42,6 @@ typedef struct UvNearestHit { /** Always set if we have a hit. */ struct BMFace *efa; struct BMLoop *l; - struct MLoopUV *luv, *luv_next; - /** Index of loop within face. */ - int lindex; /** Needs to be set before calling nearest functions. */ float dist_sq; } UvNearestHit; diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 149c5cf1f96..2ea78ca5377 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -71,10 +71,14 @@ #include "uvedit_intern.h" static void uv_select_all_perform(Scene *scene, Object *obedit, int action); + +static void uv_select_all_perform_multi_ex( + Scene *scene, Object **objects, const uint objects_len, int action, const Object *ob_exclude); static void uv_select_all_perform_multi(Scene *scene, Object **objects, const uint objects_len, int action); + static void uv_select_flush_from_tag_face(SpaceImage *sima, Scene *scene, Object *obedit, @@ -612,7 +616,7 @@ void uvedit_uv_select_disable(const Scene *scene, } } -static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(Scene *scene, +static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene *scene, BMLoop *l_src, const int cd_loop_uv_offset) { @@ -637,6 +641,37 @@ static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(Scene *scene return l_other; } +static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scene *scene, + BMLoop *l_edge, + BMVert *v_pivot, + const int cd_loop_uv_offset) +{ + BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_edge, cd_loop_uv_offset) == NULL); + + BMLoop *l_step = l_edge; + l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next; + BMLoop *l_step_last = NULL; + do { + BLI_assert(BM_vert_in_edge(l_step->e, v_pivot)); + l_step_last = l_step; + l_step = uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_step, cd_loop_uv_offset); + if (l_step) { + l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next; + } + } while (l_step != NULL); + + BM_elem_flag_set(l_step_last->e, BM_ELEM_SMOOTH, false); + + if (l_step_last != NULL) { + BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_step_last, cd_loop_uv_offset) == NULL); + } + + return l_step_last; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -671,9 +706,6 @@ bool uv_find_nearest_edge(Scene *scene, Object *obedit, const float co[2], UvNea hit->efa = efa; hit->l = l; - hit->luv = luv; - hit->luv_next = luv_next; - hit->lindex = i; hit->dist_sq = dist_test_sq; found = true; @@ -713,7 +745,6 @@ bool uv_find_nearest_face(Scene *scene, Object *obedit, const float co[2], UvNea if (uv_find_nearest_edge(scene, obedit, co, &hit)) { hit.dist_sq = dist_sq_init; hit.l = NULL; - hit.luv = hit.luv_next = NULL; BMIter iter; BMFace *efa; @@ -783,7 +814,6 @@ bool uv_find_nearest_vert(Scene *scene, hit.dist_sq = dist_sq_init; hit.l = NULL; - hit.luv = hit.luv_next = NULL; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; @@ -822,10 +852,7 @@ bool uv_find_nearest_vert(Scene *scene, hit.dist_sq = dist_test_sq; hit.l = l; - hit.luv = luv; - hit.luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); hit.efa = efa; - hit.lindex = i; found = true; } } @@ -979,200 +1006,235 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, /** \name Edge Loop Select * \{ */ -static void uv_select_edgeloop_vertex_loop_flag(UvMapVert *first) -{ - UvMapVert *iterv; - int count = 0; +/** Mode for selecting edge loops at boundaries. */ +enum eUVEdgeLoopBoundaryMode { + /** Delimit at face corners (don't walk over multiple edges in the same face). */ + UV_EDGE_LOOP_BOUNDARY_LOOP = 1, + /** Don't delimit, walk over the all connected boundary loops. */ + UV_EDGE_LOOP_BOUNDARY_ALL = 2, +}; - for (iterv = first; iterv; iterv = iterv->next) { - if (iterv->separate && iterv != first) { - break; +static BMLoop *bm_select_edgeloop_double_side_next(const Scene *scene, + BMLoop *l_step, + BMVert *v_from, + const int cd_loop_uv_offset) +{ + if (l_step->f->len == 4) { + BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); + BMLoop *l_step_over = (v_from == l_step->v) ? l_step->next : l_step->prev; + l_step_over = uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_step_over, cd_loop_uv_offset); + if (l_step_over) { + return (l_step_over->v == v_from_next) ? l_step_over->prev : l_step_over->next; } - - count++; - } - - if (count < 5) { - first->flag = 1; } + return NULL; } -static UvMapVert *uv_select_edgeloop_vertex_map_get(UvVertMap *vmap, BMFace *efa, BMLoop *l) +static BMLoop *bm_select_edgeloop_single_side_next(const Scene *scene, + BMLoop *l_step, + BMVert *v_from, + const int cd_loop_uv_offset) { - UvMapVert *iterv, *first; - first = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); + BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); + return uvedit_loop_find_other_boundary_loop_with_visible_face( + scene, l_step, v_from_next, cd_loop_uv_offset); +} - for (iterv = first; iterv; iterv = iterv->next) { - if (iterv->separate) { - first = iterv; - } - if (iterv->poly_index == BM_elem_index_get(efa)) { - return first; +/* TODO(campbell): support this in the BMesh API, as we have for clearing other types. */ +static void bm_loop_tags_clear(BMesh *bm) +{ + BMIter iter; + BMFace *f; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMIter liter; + BMLoop *l_iter; + BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { + BM_elem_flag_disable(l_iter, BM_ELEM_TAG); } } - - return NULL; } -static bool uv_select_edgeloop_edge_tag_faces(BMEditMesh *em, - UvMapVert *first1, - UvMapVert *first2, - int *totface) +/** + * Tag all loops which should be selected, the caller must select. + */ +static void uv_select_edgeloop_double_side_tag(const Scene *scene, + BMEditMesh *em, + BMLoop *l_init_pair[2], + const int cd_loop_uv_offset) { - UvMapVert *iterv1, *iterv2; - BMFace *efa; - int tot = 0; - - /* count number of faces this edge has */ - for (iterv1 = first1; iterv1; iterv1 = iterv1->next) { - if (iterv1->separate && iterv1 != first1) { - break; - } + bm_loop_tags_clear(em->bm); - for (iterv2 = first2; iterv2; iterv2 = iterv2->next) { - if (iterv2->separate && iterv2 != first2) { + for (int side = 0; side < 2; side++) { + BMLoop *l_step_pair[2] = {l_init_pair[0], l_init_pair[1]}; + BMVert *v_from = side ? l_step_pair[0]->e->v1 : l_step_pair[0]->e->v2; + /* Disable since we start from the same edge. */ + BM_elem_flag_disable(l_step_pair[0], BM_ELEM_TAG); + BM_elem_flag_disable(l_step_pair[1], BM_ELEM_TAG); + while ((l_step_pair[0] != NULL) && (l_step_pair[1] != NULL)) { + if (!uvedit_face_visible_test(scene, l_step_pair[0]->f) || + !uvedit_face_visible_test(scene, l_step_pair[1]->f) || + /* Check loops have not diverged. */ + (uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_step_pair[0], cd_loop_uv_offset) != l_step_pair[1])) { break; } - if (iterv1->poly_index == iterv2->poly_index) { - /* if face already tagged, don't do this edge */ - efa = BM_face_at_index(em->bm, iterv1->poly_index); - if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - return false; - } + BLI_assert(l_step_pair[0]->e == l_step_pair[1]->e); + + BM_elem_flag_enable(l_step_pair[0], BM_ELEM_TAG); + BM_elem_flag_enable(l_step_pair[1], BM_ELEM_TAG); + + BMVert *v_from_next = BM_edge_other_vert(l_step_pair[0]->e, v_from); + /* Walk over both sides, ensure they keep on the same edge. */ + for (int i = 0; i < ARRAY_SIZE(l_step_pair); i++) { + l_step_pair[i] = bm_select_edgeloop_double_side_next( + scene, l_step_pair[i], v_from, cd_loop_uv_offset); + } - tot++; + if ((l_step_pair[0] && BM_elem_flag_test(l_step_pair[0], BM_ELEM_TAG)) || + (l_step_pair[1] && BM_elem_flag_test(l_step_pair[1], BM_ELEM_TAG))) { break; } + v_from = v_from_next; } } +} - if (*totface == 0) { /* start edge */ - *totface = tot; - } - else if (tot != *totface) { /* check for same number of faces as start edge */ - return false; +/** + * Tag all loops which should be selected, the caller must select. + * + * \param r_count_by_select: Count the number of unselected and selected loops, + * this is needed to implement cycling between #eUVEdgeLoopBoundaryMode. + */ +static void uv_select_edgeloop_single_side_tag(const Scene *scene, + BMEditMesh *em, + BMLoop *l_init, + const int cd_loop_uv_offset, + enum eUVEdgeLoopBoundaryMode boundary_mode, + int r_count_by_select[2]) +{ + if (r_count_by_select) { + r_count_by_select[0] = r_count_by_select[1] = 0; } - /* tag the faces */ - for (iterv1 = first1; iterv1; iterv1 = iterv1->next) { - if (iterv1->separate && iterv1 != first1) { - break; - } + bm_loop_tags_clear(em->bm); - for (iterv2 = first2; iterv2; iterv2 = iterv2->next) { - if (iterv2->separate && iterv2 != first2) { + for (int side = 0; side < 2; side++) { + BMLoop *l_step = l_init; + BMVert *v_from = side ? l_step->e->v1 : l_step->e->v2; + /* Disable since we start from the same edge. */ + BM_elem_flag_disable(l_step, BM_ELEM_TAG); + while (l_step != NULL) { + + if (!uvedit_face_visible_test(scene, l_step->f) || + /* Check the boundary is still a boundary. */ + (uvedit_loop_find_other_radial_loop_with_visible_face( + scene, l_step, cd_loop_uv_offset) != NULL)) { break; } - if (iterv1->poly_index == iterv2->poly_index) { - efa = BM_face_at_index(em->bm, iterv1->poly_index); - BM_elem_flag_enable(efa, BM_ELEM_TAG); + if (r_count_by_select != NULL) { + r_count_by_select[uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)] += 1; + /* Early exit when mixed could be optional if needed. */ + if (r_count_by_select[0] && r_count_by_select[1]) { + r_count_by_select[0] = r_count_by_select[1] = -1; + break; + } + } + + BM_elem_flag_enable(l_step, BM_ELEM_TAG); + + BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); + BMFace *f_step_prev = l_step->f; + + l_step = bm_select_edgeloop_single_side_next(scene, l_step, v_from, cd_loop_uv_offset); + + if (l_step && BM_elem_flag_test(l_step, BM_ELEM_TAG)) { break; } + if (boundary_mode == UV_EDGE_LOOP_BOUNDARY_LOOP) { + /* Don't allow walking over the the face. */ + if (f_step_prev == l_step->f) { + break; + } + } + v_from = v_from_next; } } - - return true; } -static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) +static int uv_select_edgeloop( + SpaceImage *sima, Scene *scene, Object *obedit, UvNearestHit *hit, const bool extend) { BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMFace *efa; - BMIter iter, liter; - BMLoop *l; - UvVertMap *vmap; - UvMapVert *iterv_curr; - UvMapVert *iterv_next; - int starttotf; - bool looking, select; + bool select; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - /* setup */ - BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, false, false); - - BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); - - if (!extend) { - uv_select_all_perform(scene, obedit, SEL_DESELECT); + if (extend) { + select = !(uvedit_uv_select_test(scene, hit->l, cd_loop_uv_offset)); + } + else { + select = true; } - BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false); - - /* set flags for first face and verts */ - iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, hit->efa, hit->l); - iterv_next = uv_select_edgeloop_vertex_map_get(vmap, hit->efa, hit->l->next); - uv_select_edgeloop_vertex_loop_flag(iterv_curr); - uv_select_edgeloop_vertex_loop_flag(iterv_next); - - starttotf = 0; - uv_select_edgeloop_edge_tag_faces(em, iterv_curr, iterv_next, &starttotf); - - /* sorry, first edge isn't even ok */ - looking = !(iterv_curr->flag == 0 && iterv_next->flag == 0); - - /* iterate */ - while (looking) { - looking = false; - - /* find correct valence edges which are not tagged yet, but connect to tagged one */ + BMLoop *l_init_pair[2] = { + hit->l, + uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset), + }; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG) && uvedit_face_visible_test(scene, efa)) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - /* check face not hidden and not tagged */ - if (!(iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l))) { - continue; - } - if (!(iterv_next = uv_select_edgeloop_vertex_map_get(vmap, efa, l->next))) { - continue; - } + /* When selecting boundaries, support cycling between selection modes. */ + enum eUVEdgeLoopBoundaryMode boundary_mode = UV_EDGE_LOOP_BOUNDARY_LOOP; - /* check if vertex is tagged and has right valence */ - if (iterv_curr->flag || iterv_next->flag) { - if (uv_select_edgeloop_edge_tag_faces(em, iterv_curr, iterv_next, &starttotf)) { - looking = true; - BM_elem_flag_enable(efa, BM_ELEM_TAG); + /* Tag all loops that are part of the edge loop (select after). + * This is done so we can */ + if (l_init_pair[1] == NULL) { + int count_by_select[2]; + /* If the loops selected toggle the boundaries. */ + uv_select_edgeloop_single_side_tag( + scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select); + if (count_by_select[!select] == 0) { + boundary_mode = UV_EDGE_LOOP_BOUNDARY_ALL; - uv_select_edgeloop_vertex_loop_flag(iterv_curr); - uv_select_edgeloop_vertex_loop_flag(iterv_next); - break; - } - } - } + /* If the boundary is selected, toggle back to the loop. */ + uv_select_edgeloop_single_side_tag( + scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select); + if (count_by_select[!select] == 0) { + boundary_mode = UV_EDGE_LOOP_BOUNDARY_LOOP; } } } - /* do the actual select/deselect */ - iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, hit->efa, hit->l); - iterv_next = uv_select_edgeloop_vertex_map_get(vmap, hit->efa, hit->l->next); - iterv_curr->flag = 1; - iterv_next->flag = 1; - - if (extend) { - select = !(uvedit_uv_select_test(scene, hit->l, cd_loop_uv_offset)); + if (l_init_pair[1] == NULL) { + uv_select_edgeloop_single_side_tag( + scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, NULL); } else { - select = true; + uv_select_edgeloop_double_side_tag(scene, em, l_init_pair, cd_loop_uv_offset); } - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - iterv_curr = uv_select_edgeloop_vertex_map_get(vmap, efa, l); + /* Apply the selection. */ + if (!extend) { + uv_select_all_perform(scene, obedit, SEL_DESELECT); + } - if (iterv_curr->flag) { - uvedit_uv_select_set(scene, em, l, select, false, cd_loop_uv_offset); + /* Select all tagged loops. */ + { + BMIter iter; + BMFace *f; + BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) { + BMIter liter; + BMLoop *l_iter; + BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { + if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { + uvedit_edge_select_set_with_sticky( + sima, scene, em, l_iter, select, false, cd_loop_uv_offset); + } } } } - /* cleanup */ - BM_uv_vert_map_free(vmap); - return (select) ? 1 : -1; } @@ -1770,10 +1832,8 @@ static void uv_select_all_perform(Scene *scene, Object *obedit, int action) } } -static void uv_select_all_perform_multi(Scene *scene, - Object **objects, - const uint objects_len, - int action) +static void uv_select_all_perform_multi_ex( + Scene *scene, Object **objects, const uint objects_len, int action, const Object *ob_exclude) { if (action == SEL_TOGGLE) { action = uvedit_select_is_any_selected_multi(scene, objects, objects_len) ? SEL_DESELECT : @@ -1782,10 +1842,21 @@ static void uv_select_all_perform_multi(Scene *scene, for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; + if (ob_exclude && (obedit == ob_exclude)) { + continue; + } uv_select_all_perform(scene, obedit, action); } } +static void uv_select_all_perform_multi(Scene *scene, + Object **objects, + const uint objects_len, + int action) +{ + uv_select_all_perform_multi_ex(scene, objects, objects_len, action, NULL); +} + static int uv_select_all_exec(bContext *C, wmOperator *op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -1931,8 +2002,7 @@ static int uv_mouse_select_multi(bContext *C, /* do selection */ if (selectmode == UV_SELECT_ISLAND) { if (!extend) { - /* TODO(MULTI_EDIT): We only need to de-select non-active */ - uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT); + uv_select_all_perform_multi_ex(scene, objects, objects_len, SEL_DESELECT, obedit); } /* Current behavior of 'extend' * is actually toggling, so pass extend flag as 'toggle' here */ @@ -2122,12 +2192,11 @@ static int uv_mouse_select_loop_generic_multi(bContext *C, /* Do selection. */ if (!extend) { - /* TODO(MULTI_EDIT): We only need to de-select non-active */ - uv_select_all_perform_multi(scene, objects, objects_len, SEL_DESELECT); + uv_select_all_perform_multi_ex(scene, objects, objects_len, SEL_DESELECT, obedit); } if (loop_type == UV_LOOP_SELECT) { - flush = uv_select_edgeloop(scene, obedit, &hit, extend); + flush = uv_select_edgeloop(sima, scene, obedit, &hit, extend); } else if (loop_type == UV_RING_SELECT) { flush = uv_select_edgering(sima, scene, obedit, &hit, extend); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 6332a6ab48f..6dac31794b4 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1765,7 +1765,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void pos_id = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); } - GPU_blend(true); + GPU_blend(GPU_BLEND_ALPHA); /* Static Tris */ if (stitch_preview->static_tris) { @@ -1829,7 +1829,7 @@ static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(region), void stitch_draw_vbo(vbo_line, GPU_PRIM_LINES, col); } - GPU_blend(false); + GPU_blend(GPU_BLEND_NONE); /* draw stitch vert/lines preview */ if (ssc->mode == STITCH_VERT) { |