diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-10-31 17:21:12 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-10-31 17:27:03 +0300 |
commit | 941484ff81744ad2dca1741f3e9c4b4c18664a82 (patch) | |
tree | 3d80e516e39a7d55be8439c2ce3e06943de0a3f6 /source | |
parent | 0dd98af2559b89149f2b6ae586969c0544c26369 (diff) | |
parent | 7fb393f9ba3866026c8fb2c5c5ef7e0906cfe8b4 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source')
25 files changed, 587 insertions, 109 deletions
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 06bef637107..fd5b20f3e38 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -227,4 +227,14 @@ enum { void BKE_curve_batch_cache_dirty(struct Curve *cu, int mode); void BKE_curve_batch_cache_free(struct Curve *cu); +/* curve_decimate.c */ +unsigned int BKE_curve_decimate_bezt_array( + struct BezTriple *bezt_array, const unsigned int bezt_array_len, const unsigned int resolu, const bool is_cyclic, + const char flag_test, const char flag_set, + const float error_sq_max, const unsigned int error_target_len); + +void BKE_curve_decimate_nurb( + struct Nurb *nu, const unsigned int resolu, + const float error_sq_max, const unsigned int error_target_len); + #endif /* __BKE_CURVE_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index b2883735343..6063c068909 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -50,6 +50,7 @@ set(INC ../../../intern/smoke/extern ../../../intern/atomic ../../../intern/libmv + ../../../extern/curve_fit_nd ) set(INC_SYS @@ -93,6 +94,7 @@ set(SRC intern/context.c intern/crazyspace.c intern/curve.c + intern/curve_decimate.c intern/customdata.c intern/customdata_file.c intern/data_transfer.c diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c new file mode 100644 index 00000000000..7983c63c99d --- /dev/null +++ b/source/blender/blenkernel/intern/curve_decimate.c @@ -0,0 +1,339 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/curve_decimate.c + * \ingroup bke + */ + +#include "DNA_curve_types.h" + +#include "MEM_guardedalloc.h" +#include "BLI_heap.h" +#include "BLI_math_vector.h" + +#include "BKE_curve.h" + +#include "curve_fit_nd.h" + +#include "BLI_strict_flags.h" + +struct Knot { + struct Knot *next, *prev; + uint point_index; /* index in point array */ + uint knot_index; /* index in knot array*/ + float tan[2][3]; + float handles[2]; + + HeapNode *heap_node; + uint can_remove : 1; + uint is_removed : 1; + +#ifndef NDEBUG + const float *co; +#endif +}; + +struct Removal { + uint knot_index; + /* handles for prev/next knots */ + float handles[2]; +}; + +static float knot_remove_error_value( + const float tan_l[3], const float tan_r[3], + const float (*points)[3], const uint points_len, + /* avoid having to re-calculate again */ + float r_handle_factors[2]) +{ + const uint dims = 3; + float error_sq = FLT_MAX; + uint error_sq_index; + float handle_factors[2][3]; + + curve_fit_cubic_to_points_single_fl( + &points[0][0], points_len, NULL, dims, 0.0f, + tan_l, tan_r, + handle_factors[0], handle_factors[1], + &error_sq, &error_sq_index); + + sub_v3_v3(handle_factors[0], points[0]); + r_handle_factors[0] = dot_v3v3(tan_l, handle_factors[0]); + + sub_v3_v3(handle_factors[1], points[points_len - 1]); + r_handle_factors[1] = dot_v3v3(tan_r, handle_factors[1]); + + return error_sq; +} + +static void knot_remove_error_recalculate( + Heap *heap, const float (*points)[3], const uint points_len, + struct Knot *k, const float error_sq_max) +{ + BLI_assert(k->can_remove); + float handles[2]; + +#ifndef NDEBUG + BLI_assert(equals_v3v3(points[k->prev->point_index], k->prev->co)); + BLI_assert(equals_v3v3(points[k->next->point_index], k->next->co)); +#endif + + const float (*points_offset)[3]; + uint points_offset_len; + + if (k->prev->point_index < k->next->point_index) { + points_offset = &points[k->prev->point_index]; + points_offset_len = (k->next->point_index - k->prev->point_index) + 1; + } + else { + points_offset = &points[k->prev->point_index]; + points_offset_len = ((k->next->point_index + points_len) - k->prev->point_index) + 1; + } + + const float cost_sq = knot_remove_error_value( + k->prev->tan[1], k->next->tan[0], + points_offset, points_offset_len, + handles); + + if (cost_sq < error_sq_max) { + struct Removal *r; + if (k->heap_node) { + r = BLI_heap_node_ptr(k->heap_node); + } + else { + r = MEM_mallocN(sizeof(*r), __func__); + r->knot_index = k->knot_index; + } + + copy_v2_v2(r->handles, handles); + + BLI_heap_insert_or_update(heap, &k->heap_node, cost_sq, r); + } + else { + if (k->heap_node) { + struct Removal *r; + r = BLI_heap_node_ptr(k->heap_node); + BLI_heap_remove(heap, k->heap_node); + + MEM_freeN(r); + + k->heap_node = NULL; + } + } +} + +static void curve_decimate( + const float (*points)[3], const uint points_len, + struct Knot *knots, const uint knots_len, + float error_sq_max, const uint error_target_len) +{ + Heap *heap = BLI_heap_new_ex(knots_len); + for (uint i = 0; i < knots_len; i++) { + struct Knot *k = &knots[i]; + if (k->can_remove) { + knot_remove_error_recalculate(heap, points, points_len, k, error_sq_max); + } + } + + uint knots_len_remaining = knots_len; + + while ((knots_len_remaining > error_target_len) && + (BLI_heap_is_empty(heap) == false)) + { + struct Knot *k; + + { + struct Removal *r = BLI_heap_popmin(heap); + k = &knots[r->knot_index]; + k->heap_node = NULL; + k->prev->handles[1] = r->handles[0]; + k->next->handles[0] = r->handles[1]; + MEM_freeN(r); + } + + struct Knot *k_prev = k->prev; + struct Knot *k_next = k->next; + + /* remove ourselves */ + k_next->prev = k_prev; + k_prev->next = k_next; + + k->next = NULL; + k->prev = NULL; + k->is_removed = true; + + if (k_prev->can_remove) { + knot_remove_error_recalculate(heap, points, points_len, k_prev, error_sq_max); + } + + if (k_next->can_remove) { + knot_remove_error_recalculate(heap, points, points_len, k_next, error_sq_max); + } + + knots_len_remaining -= 1; + } + + BLI_heap_free(heap, MEM_freeN); +} + + +uint BKE_curve_decimate_bezt_array( + BezTriple *bezt_array, const uint bezt_array_len, + const uint resolu, const bool is_cyclic, + const char flag_test, const char flag_set, + const float error_sq_max, const uint error_target_len) +{ + const uint bezt_array_last = bezt_array_len - 1; + const uint points_len = BKE_curve_calc_coords_axis_len(bezt_array_len, resolu, is_cyclic, true); + + float (*points)[3] = MEM_mallocN((sizeof(float[3]) * points_len * (is_cyclic ? 2 : 1)), __func__); + + BKE_curve_calc_coords_axis(bezt_array, bezt_array_len, resolu, is_cyclic, false, 0, sizeof(float[3]), &points[0][0]); + BKE_curve_calc_coords_axis(bezt_array, bezt_array_len, resolu, is_cyclic, false, 1, sizeof(float[3]), &points[0][1]); + BKE_curve_calc_coords_axis(bezt_array, bezt_array_len, resolu, is_cyclic, false, 2, sizeof(float[3]), &points[0][2]); + + const uint knots_len = bezt_array_len; + struct Knot *knots = MEM_mallocN((sizeof(*knots) * bezt_array_len), __func__); + + if (is_cyclic) { + memcpy(points[points_len], points[0], sizeof(float[3]) * points_len); + } + + for (uint i = 0; i < bezt_array_len; i++) { + knots[i].heap_node = NULL; + knots[i].can_remove = (bezt_array[i].f2 & flag_test) != 0; + knots[i].is_removed = false; + knots[i].next = &knots[i + 1]; + knots[i].prev = &knots[i - 1]; + knots[i].point_index = i * resolu; + knots[i].knot_index = i; + + sub_v3_v3v3(knots[i].tan[0], bezt_array[i].vec[0], bezt_array[i].vec[1]); + knots[i].handles[0] = normalize_v3(knots[i].tan[0]); + + sub_v3_v3v3(knots[i].tan[1], bezt_array[i].vec[1], bezt_array[i].vec[2]); + knots[i].handles[1] = -normalize_v3(knots[i].tan[1]); + +#ifndef NDEBUG + knots[i].co = bezt_array[i].vec[1]; + BLI_assert(equals_v3v3(knots[i].co, points[knots[i].point_index])); +#endif + } + + if (is_cyclic) { + knots[0].prev = &knots[bezt_array_last]; + knots[bezt_array_last].next = &knots[0]; + } + else { + knots[0].prev = NULL; + knots[bezt_array_last].next = NULL; + + /* always keep end-points */ + knots[0].can_remove = false; + knots[bezt_array_last].can_remove = false; + } + + curve_decimate(points, points_len, knots, knots_len, error_sq_max, error_target_len); + + MEM_freeN(points); + + uint knots_len_decimated = knots_len; + + /* Update handle type on modifications. */ +#define HANDLE_UPDATE(a, b) \ + { \ + if (a == HD_VECT) { \ + a = HD_FREE; \ + } \ + else if (a == HD_AUTO) { \ + a = HD_ALIGN; \ + } \ + /* opposite handle */ \ + if (b == HD_AUTO) { \ + b = HD_ALIGN; \ + } \ + } ((void)0) + + for (uint i = 0; i < bezt_array_len; i++) { + if (knots[i].is_removed) { + /* caller must remove */ + bezt_array[i].f2 |= flag_set; + knots_len_decimated--; + } + else { + bezt_array[i].f2 &= (char)~flag_set; + if (is_cyclic || i != 0) { + uint i_prev = (i != 0) ? i - 1 : bezt_array_last; + if (knots[i_prev].is_removed) { + madd_v3_v3v3fl(bezt_array[i].vec[0], bezt_array[i].vec[1], knots[i].tan[0], knots[i].handles[0]); + HANDLE_UPDATE(bezt_array[i].h1, bezt_array[i].h2); + } + } + if (is_cyclic || i != bezt_array_last) { + uint i_next = (i != bezt_array_last) ? i + 1 : 0; + if (knots[i_next].is_removed) { + madd_v3_v3v3fl(bezt_array[i].vec[2], bezt_array[i].vec[1], knots[i].tan[1], knots[i].handles[1]); + HANDLE_UPDATE(bezt_array[i].h2, bezt_array[i].h1); + } + } + } + } + +#undef HANDLE_UPDATE + + MEM_freeN(knots); + + return knots_len_decimated; +} +#define SELECT 1 + + +void BKE_curve_decimate_nurb( + Nurb *nu, const uint resolu, + const float error_sq_max, const uint error_target_len) +{ + const char flag_test = BEZT_FLAG_TEMP_TAG; + + const uint pntsu_dst = BKE_curve_decimate_bezt_array( + nu->bezt, (uint)nu->pntsu, resolu, (nu->flagu & CU_NURB_CYCLIC) != 0, + SELECT, flag_test, + error_sq_max, error_target_len); + + if (pntsu_dst == (uint)nu->pntsu) { + return; + } + + BezTriple *bezt_src = nu->bezt; + BezTriple *bezt_dst = MEM_mallocN(sizeof(BezTriple) * pntsu_dst, __func__); + + int i_src = 0, i_dst = 0; + + while (i_src < nu->pntsu) { + if ((bezt_src[i_src].f2 & flag_test) == 0) { + bezt_dst[i_dst] = bezt_src[i_src]; + i_dst++; + } + i_src++; + } + + MEM_freeN(bezt_src); + + nu->bezt = bezt_dst; + nu->pntsu = i_dst; +} diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 7261ed0a11c..689d3010a7a 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -411,11 +411,10 @@ static void poselib_add_menu_invoke__replacemenu(bContext *C, uiLayout *layout, /* add each marker to this menu */ for (marker = act->markers.first; marker; marker = marker->next) { PointerRNA props_ptr; - - props_ptr = uiItemFullO_ptr(layout, ot, - marker->name, ICON_ARMATURE_DATA, NULL, - WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); - + uiItemFullO_ptr( + layout, ot, + marker->name, ICON_ARMATURE_DATA, NULL, + WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_int_set(&props_ptr, "frame", marker->frame); RNA_string_set(&props_ptr, "name", marker->name); } diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 02c76a840f1..bf1e22ae170 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -109,6 +109,7 @@ void CURVE_OT_radius_set(struct wmOperatorType *ot); void CURVE_OT_spline_weight_set(struct wmOperatorType *ot); void CURVE_OT_handle_type_set(struct wmOperatorType *ot); void CURVE_OT_normals_make_consistent(struct wmOperatorType *ot); +void CURVE_OT_decimate(struct wmOperatorType *ot); void CURVE_OT_shade_smooth(struct wmOperatorType *ot); void CURVE_OT_shade_flat(struct wmOperatorType *ot); void CURVE_OT_tilt_clear(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 5d637b113d8..4dfd4a5c0f0 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -94,6 +94,7 @@ void ED_operatortypes_curve(void) WM_operatortype_append(CURVE_OT_spline_weight_set); WM_operatortype_append(CURVE_OT_handle_type_set); WM_operatortype_append(CURVE_OT_normals_make_consistent); + WM_operatortype_append(CURVE_OT_decimate); WM_operatortype_append(CURVE_OT_shade_smooth); WM_operatortype_append(CURVE_OT_shade_flat); WM_operatortype_append(CURVE_OT_tilt_clear); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4757c896650..565521ad111 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -5909,6 +5909,86 @@ void CURVE_OT_dissolve_verts(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static bool nurb_bezt_flag_any(const Nurb *nu, const char flag_test) +{ + BezTriple *bezt = nu->bezt; + int i; + + for (i = nu->pntsu, bezt = nu->bezt; i--; bezt++) { + if (bezt->f2 & flag_test) { + return true; + } + } + + return false; +} + +static int curve_decimate_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Curve *cu = (Curve *)obedit->data; + bool all_supported = true; + bool changed = false; + + { + const float error_sq_max = FLT_MAX; + float ratio = RNA_float_get(op->ptr, "ratio"); + + ListBase *editnurb = object_editcurve_get(obedit); + Nurb *nu; + + for (nu = editnurb->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) { + const int error_target_len = max_ii(2, nu->pntsu * ratio); + if (error_target_len != nu->pntsu) { + BKE_curve_decimate_nurb(nu, cu->resolu, error_sq_max, error_target_len); + changed = true; + } + } + } + else { + all_supported = false; + } + } + } + + if (all_supported == false) { + BKE_report(op->reports, RPT_WARNING, "Only bezier curves are supported"); + } + + if (changed) { + cu->actnu = cu->actvert = CU_ACT_NONE; + if (ED_curve_updateAnimPaths(obedit->data)) { + WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); + } + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DEG_id_tag_update(obedit->data, 0); + } + + return OPERATOR_FINISHED; +} + +void CURVE_OT_decimate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Decimate Curve"; + ot->description = "Simplify selected curves"; + ot->idname = "CURVE_OT_decimate"; + + /* api callbacks */ + ot->exec = curve_decimate_exec; + ot->poll = ED_operator_editcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_factor(ot->srna, "ratio", 1.0f, 0.0f, 1.0f, "Ratio", "", 0.0f, 1.0f); +} + + /********************** shade smooth/flat operator *********************/ static int shade_smooth_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 97f63a64aad..b30d71941d6 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -823,7 +823,6 @@ void UI_exit(void); #define UI_LAYOUT_ALIGN_CENTER 2 #define UI_LAYOUT_ALIGN_RIGHT 3 -#define UI_ITEM_O_RETURN_PROPS (1 << 0) #define UI_ITEM_R_EXPAND (1 << 1) #define UI_ITEM_R_SLIDER (1 << 2) #define UI_ITEM_R_TOGGLE (1 << 3) @@ -998,8 +997,14 @@ void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value); void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value); -PointerRNA uiItemFullO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag); -PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag); +void uiItemFullO_ptr( + uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, + struct IDProperty *properties, int context, int flag, + PointerRNA *r_opptr); +void uiItemFullO( + uiLayout *layout, const char *idname, const char *name, int icon, + struct IDProperty *properties, int context, int flag, + PointerRNA *r_opptr); void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon); void uiItemFullR(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, int value, int flag, const char *name, int icon); @@ -1023,6 +1028,7 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval); /* value void uiItemS(uiLayout *layout); /* separator */ void uiItemMenuF(uiLayout *layout, const char *name, int icon, uiMenuCreateFunc func, void *arg); +void uiItemMenuEnumO_ptr(uiLayout *layout, struct bContext *C, struct wmOperatorType *ot, const char *propname, const char *name, int icon); void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon); void uiItemMenuEnumR_prop(uiLayout *layout, struct PointerRNA *ptr, PropertyRNA *prop, const char *name, int icon); void uiItemMenuEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, const char *name, int icon); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2c8994466f1..bb813f399d6 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -6736,16 +6736,15 @@ static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, Pr if (file[0]) { BLI_assert(subtype == PROP_FILEPATH); - - props_ptr = uiItemFullO_ptr( - layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"), - ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr( + layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open File Externally"), + ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr); RNA_string_set(&props_ptr, "filepath", filepath); } - props_ptr = uiItemFullO_ptr( - layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"), - ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr( + layout, ot, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Open Location Externally"), + ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &props_ptr); RNA_string_set(&props_ptr, "filepath", dir); } @@ -7026,21 +7025,23 @@ static bool ui_but_menu(bContext *C, uiBut *but) { /* Docs */ char buf[512]; - PointerRNA ptr_props; if (UI_but_online_manual_id(but, buf, sizeof(buf))) { + PointerRNA ptr_props; uiItemO(layout, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"), ICON_URL, "WM_OT_doc_view_manual_ui_context"); - ptr_props = uiItemFullO(layout, "WM_OT_doc_view", - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"), - ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO( + layout, "WM_OT_doc_view", + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"), + ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr_props); RNA_string_set(&ptr_props, "doc_id", buf); /* XXX inactive option, not for public! */ #if 0 - ptr_props = uiItemFullO(layout, "WM_OT_doc_edit", - "Submit Description", ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO( + layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE, + NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr_props); RNA_string_set(&ptr_props, "doc_id", buf); RNA_string_set(&ptr_props, "doc_new", RNA_property_description(but->rnaprop)); #endif @@ -7054,9 +7055,9 @@ static bool ui_but_menu(bContext *C, uiBut *but) /* perhaps we should move this into (G.debug & G_DEBUG) - campbell */ if (ui_block_is_menu(but->block) == false) { - uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO(layout, "UI_OT_editsource", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL); } - uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL); mt = WM_menutype_find("WM_MT_button_context", true); if (mt) { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index a63c000467f..1ac54d5353d 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -790,9 +790,17 @@ static void ui_item_disabled(uiLayout *layout, const char *name) but->disabled_info = ""; } -/* operator items */ -PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int icon, IDProperty *properties, int context, int flag) +/** + * Operator Item + * \param r_opptr: Optional, initialize with operator properties when not NULL. + * Will always be written to even in the case of errors. + */ +void uiItemFullO_ptr( + uiLayout *layout, wmOperatorType *ot, + const char *name, int icon, IDProperty *properties, int context, int flag, + PointerRNA *r_opptr) { + /* Take care to fill 'r_opptr' whatever happens. */ uiBlock *block = layout->root->block; uiBut *but; int w; @@ -841,9 +849,8 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam UI_but_flag_enable(but, UI_BUT_REDALERT); /* assign properties */ - if (properties || (flag & UI_ITEM_O_RETURN_PROPS)) { + if (properties || r_opptr) { PointerRNA *opptr = UI_but_operator_ptr_get(but); - if (properties) { opptr->data = properties; } @@ -851,20 +858,28 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam IDPropertyTemplate val = {0}; opptr->data = IDP_New(IDP_GROUP, &val, "wmOperatorProperties"); } - - return *opptr; + if (r_opptr) { + *r_opptr = *opptr; + } } - - return PointerRNA_NULL; } -PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, int icon, IDProperty *properties, int context, int flag) +void uiItemFullO( + uiLayout *layout, const char *opname, + const char *name, int icon, IDProperty *properties, int context, int flag, + PointerRNA *r_opptr) { wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ - UI_OPERATOR_ERROR_RET(ot, opname, return PointerRNA_NULL); + UI_OPERATOR_ERROR_RET( + ot, opname, { + if (r_opptr) { + *r_opptr = PointerRNA_NULL; + }; + return; + }); - return uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag); + uiItemFullO_ptr(layout, ot, name, icon, properties, context, flag, r_opptr); } static const char *ui_menu_enumpropname(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int retval) @@ -908,7 +923,7 @@ void uiItemEnumO_ptr(uiLayout *layout, wmOperatorType *ot, const char *name, int if (!name) name = ui_menu_enumpropname(layout, &ptr, prop, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value) { @@ -1002,7 +1017,7 @@ void uiItemsFullEnumO_items( } RNA_property_enum_set(&tptr, prop, item->value); - uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag); + uiItemFullO_ptr(target, ot, item->name, item->icon, tptr.data, context, flag, NULL); ui_but_tip_from_enum_item(block->buttons.last, item); } @@ -1132,7 +1147,7 @@ void uiItemEnumO_value(uiLayout *layout, const char *name, int icon, const char if (!name) name = ui_menu_enumpropname(layout, &ptr, prop, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value_str) @@ -1176,7 +1191,7 @@ void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char if (!name) name = ui_menu_enumpropname(layout, &ptr, prop, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) @@ -1189,7 +1204,7 @@ void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *op WM_operator_properties_create_ptr(&ptr, ot); RNA_boolean_set(&ptr, propname, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) @@ -1202,7 +1217,7 @@ void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname WM_operator_properties_create_ptr(&ptr, ot); RNA_int_set(&ptr, propname, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value) @@ -1215,7 +1230,7 @@ void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opna WM_operator_properties_create_ptr(&ptr, ot); RNA_float_set(&ptr, propname, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value) @@ -1228,12 +1243,12 @@ void uiItemStringO(uiLayout *layout, const char *name, int icon, const char *opn WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, propname, value); - uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0); + uiItemFullO_ptr(layout, ot, name, icon, ptr.data, layout->root->opcontext, 0, NULL); } void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname) { - uiItemFullO(layout, opname, name, icon, NULL, layout->root->opcontext, 0); + uiItemFullO(layout, opname, name, icon, NULL, layout->root->opcontext, 0, NULL); } /* RNA property items */ @@ -1938,19 +1953,15 @@ static void menu_item_enum_opname_menu(bContext *UNUSED(C), uiLayout *layout, vo UI_block_direction_set(layout->root->block, UI_DIR_DOWN); } -void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name, int icon) +void uiItemMenuEnumO_ptr( + uiLayout *layout, bContext *C, wmOperatorType *ot, const char *propname, + const char *name, int icon) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ MenuItemLevel *lvl; uiBut *but; - UI_OPERATOR_ERROR_RET(ot, opname, return); - - if (!ot->srna) { - ui_item_disabled(layout, opname); - RNA_warning("operator missing srna '%s'", opname); - return; - } + /* Caller must check */ + BLI_assert(ot->srna != NULL); if (name == NULL) { name = RNA_struct_ui_name(ot->srna); @@ -1960,7 +1971,7 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch icon = ICON_BLANK1; lvl = MEM_callocN(sizeof(MenuItemLevel), "MenuItemLevel"); - BLI_strncpy(lvl->opname, opname, sizeof(lvl->opname)); + BLI_strncpy(lvl->opname, ot->idname, sizeof(lvl->opname)); BLI_strncpy(lvl->propname, propname, sizeof(lvl->propname)); lvl->opcontext = layout->root->opcontext; @@ -1980,6 +1991,23 @@ void uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const ch } } +void uiItemMenuEnumO( + uiLayout *layout, bContext *C, const char *opname, const char *propname, + const char *name, int icon) +{ + wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + + UI_OPERATOR_ERROR_RET(ot, opname, return); + + if (!ot->srna) { + ui_item_disabled(layout, opname); + RNA_warning("operator missing srna '%s'", opname); + return; + } + + uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon); +} + static void menu_item_enum_rna_menu(bContext *UNUSED(C), uiLayout *layout, void *arg) { MenuItemLevel *lvl = (MenuItemLevel *)(((uiBut *)arg)->func_argN); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index c4bb50bb68b..b52c4c3afb1 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3701,10 +3701,10 @@ void uiTemplateOperatorPropertyButs( uiItemM(row, (bContext *)C, "WM_MT_operator_presets", NULL, ICON_NONE); wmOperatorType *ot = WM_operatortype_find("WM_OT_operator_preset_add", false); - op_ptr = uiItemFullO_ptr(row, ot, "", ICON_ZOOMIN, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(row, ot, "", ICON_ZOOMIN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_string_set(&op_ptr, "operator", op->type->idname); - op_ptr = uiItemFullO_ptr(row, ot, "", ICON_ZOOMOUT, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(row, ot, "", ICON_ZOOMOUT, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_string_set(&op_ptr, "operator", op->type->idname); RNA_boolean_set(&op_ptr, "remove_active", true); } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 05739a2dec0..1f994423e73 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -318,8 +318,9 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event) uiLayout *layout = UI_popup_menu_layout(pup); /* create operator menu item with relevant properties filled in */ + PointerRNA opptr_dummy; uiItemFullO_ptr(layout, op->type, op->type->name, ICON_NONE, NULL, - WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS); + WM_OP_EXEC_REGION_WIN, 0, &opptr_dummy); /* present the menu and be done... */ UI_popup_menu_end(C, pup); @@ -922,12 +923,13 @@ static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent #if 0 uiItemEnumO_ptr(layout, ot, NULL, 0, "type", PAR_OBJECT); #else - opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Object"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "type", PAR_OBJECT); RNA_boolean_set(&opptr, "keep_transform", false); - opptr = uiItemFullO_ptr(layout, ot, IFACE_("Object (Keep Transform)"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, - UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr( + layout, ot, IFACE_("Object (Keep Transform)"), ICON_NONE, + NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "type", PAR_OBJECT); RNA_boolean_set(&opptr, "keep_transform", true); #endif diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index db7f40db5e5..4f89fd45a6b 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2795,12 +2795,12 @@ static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE); layout = UI_popup_menu_layout(pup); - ptr = uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO(layout, "SCREEN_OT_area_split", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); /* store initial mouse cursor position */ RNA_int_set(&ptr, "mouse_x", event->x); RNA_int_set(&ptr, "mouse_y", event->y); - ptr = uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO(layout, "SCREEN_OT_area_join", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0, &ptr); /* mouse cursor on edge, '4' can fail on wide edges... */ RNA_int_set(&ptr, "min_x", event->x + 4); RNA_int_set(&ptr, "min_y", event->y + 4); diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index d64420fb976..e90c63f7a45 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -381,9 +381,9 @@ static void workspace_append_button( lib_path, sizeof(lib_path), from_main->name, BKE_idcode_to_name(GS(id->name)), NULL); BLI_assert(STREQ(ot_append->idname, "WM_OT_append")); - opptr = uiItemFullO_ptr( - layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, - WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr( + layout, ot_append, workspace->id.name + 2, ICON_NONE, NULL, + WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_string_set(&opptr, "directory", lib_path); RNA_string_set(&opptr, "filename", id->name + 2); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index ca5d0f53ea4..6e08f47f60d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -5237,7 +5237,7 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW uiItemS(layout); } - uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0); + uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, NULL); UI_popup_menu_end(C, pup); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 67584fbe1f1..f6c519ff27d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1287,7 +1287,7 @@ static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, Point scn_ptr = RNA_pointer_get(ptr, "scene"); RNA_string_get(&scn_ptr, "name", scene_name); - op_ptr = uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO(row, "RENDER_OT_render", "", ICON_RENDER_STILL, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_string_set(&op_ptr, "layer", layer_name); RNA_string_set(&op_ptr, "scene", scene_name); } @@ -1778,9 +1778,9 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi col = uiLayoutColumn(row, true); ot = WM_operatortype_find("NODE_OT_output_file_move_active_socket", false); - op_ptr = uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_enum_set(&op_ptr, "direction", 1); - op_ptr = uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_enum_set(&op_ptr, "direction", 2); if (active_input_ptr.data) { @@ -1791,7 +1791,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi row = uiLayoutRow(col, false); uiItemR(row, &active_input_ptr, "name", 0, "", ICON_NONE); uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "", - ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY); + ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY, NULL); } else { col = uiLayoutColumn(layout, true); @@ -1800,7 +1800,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi row = uiLayoutRow(col, false); uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE); uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "", - ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY); + ICON_X, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_R_ICON_ONLY, NULL); /* format details for individual files */ imfptr = RNA_pointer_get(&active_input_ptr, "format"); @@ -2112,7 +2112,9 @@ static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), Poi static void node_composit_buts_switch_view_ex(uiLayout *layout, bContext *UNUSED(C), PointerRNA *UNUSED(ptr)) { - uiItemFullO(layout, "NODE_OT_switch_view_update", "Update Views", ICON_FILE_REFRESH, NULL, WM_OP_INVOKE_DEFAULT, 0); + uiItemFullO( + layout, "NODE_OT_switch_view_update", + "Update Views", ICON_FILE_REFRESH, NULL, WM_OP_INVOKE_DEFAULT, 0, NULL); } static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 925298451ce..e8b4e6ec990 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -151,21 +151,21 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa) uiItemL(col, IFACE_("Inputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input", NULL, 0, 0, 0, 0); - opptr = uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "in_out", SOCK_IN); col = uiLayoutColumn(split, true); uiItemL(col, IFACE_("Outputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output", NULL, 0, 0, 0, 0); - opptr = uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "in_out", SOCK_OUT); ot = WM_operatortype_find("NODE_OT_tree_socket_move", false); col = uiLayoutColumn(row, true); - opptr = uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_TRIA_UP, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "direction", 1); - opptr = uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(col, ot, "", ICON_TRIA_DOWN, NULL, WM_OP_EXEC_DEFAULT, 0, &opptr); RNA_enum_set(&opptr, "direction", 2); if (sock) { diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index ed5187151d3..f28e70a112e 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1991,56 +1991,56 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) PointerRNA ptr; /* Cannot use uiItemEnumO()... have multiple properties to set. */ - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Object"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_OBJECT); /* par becomes parent, make the associated menus */ if (par->type == OB_ARMATURE) { - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Armature Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE); - ptr = uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_(" With Empty Groups"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); - ptr = uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_(" With Envelope Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); - ptr = uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_(" With Automatic Weights"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Bone"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_BONE); } else if (par->type == OB_CURVE) { - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Curve Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_CURVE); - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Follow Path"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_FOLLOW); - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Path Constraint"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_PATH_CONST); } else if (par->type == OB_LATTICE) { - ptr = uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, IFACE_("Lattice Deform"), 0, NULL, WM_OP_EXEC_DEFAULT, 0, &ptr); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_LATTICE); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index ddb87d96ec1..d5772a8d592 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -881,12 +881,12 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) /* The weight group paste function */ icon = (locked) ? ICON_BLANK1 : ICON_PASTEDOWN; - op_ptr = uiItemFullO(row, "OBJECT_OT_vertex_weight_paste", "", icon, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO(row, "OBJECT_OT_vertex_weight_paste", "", icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_int_set(&op_ptr, "weight_group", i); /* The weight entry delete function */ icon = (locked) ? ICON_LOCKED : ICON_X; - op_ptr = uiItemFullO(row, "OBJECT_OT_vertex_weight_delete", "", icon, NULL, WM_OP_INVOKE_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO(row, "OBJECT_OT_vertex_weight_delete", "", icon, NULL, WM_OP_INVOKE_DEFAULT, 0, &op_ptr); RNA_int_set(&op_ptr, "weight_group", i); yco -= UI_UNIT_Y; diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index 1d99fcfdd3a..5e3c783c1b6 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -218,7 +218,7 @@ static void view3d_panel_tool_shelf(const bContext *C, Panel *pa) for (ct = st->toolshelf.first; ct; ct = ct->next) { if (STREQLEN(context, ct->context, OP_MAX_TYPENAME)) { col = uiLayoutColumn(pa->layout, true); - uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0); + uiItemFullO(col, ct->opname, NULL, ICON_NONE, NULL, WM_OP_INVOKE_REGION_WIN, 0, NULL); } } } diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 8178079eb19..85a4b6ba63b 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -232,8 +232,9 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE); layout = UI_popup_menu_layout(pup); - props_ptr = uiItemFullO_ptr(layout, ot, IFACE_("Remove Pack"), ICON_NONE, - NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr( + layout, ot, IFACE_("Remove Pack"), ICON_NONE, + NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_REMOVE); RNA_string_set(&props_ptr, "id", id_name); @@ -246,7 +247,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha switch (checkPackedFile(local_name, pf)) { case PF_NOFILE: BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), local_name); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); @@ -254,7 +255,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha case PF_EQUAL: BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), local_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); @@ -262,13 +263,13 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha case PF_DIFFERS: BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), local_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_LOCAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), local_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_LOCAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_LOCAL); RNA_string_set(&props_ptr, "id", id_name); break; @@ -280,27 +281,27 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha case PF_NOFILE: BLI_snprintf(line, sizeof(line), IFACE_("Create %s"), abs_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_EQUAL: BLI_snprintf(line, sizeof(line), IFACE_("Use %s (identical)"), abs_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; case PF_DIFFERS: BLI_snprintf(line, sizeof(line), IFACE_("Use %s (differs)"), abs_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_USE_ORIGINAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_USE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); BLI_snprintf(line, sizeof(line), IFACE_("Overwrite %s"), abs_name); //uiItemEnumO_ptr(layout, ot, line, 0, "method", PF_WRITE_ORIGINAL); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, &props_ptr); RNA_enum_set(&props_ptr, "method", PF_WRITE_ORIGINAL); RNA_string_set(&props_ptr, "id", id_name); break; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index ea446552874..f4f4c1818c3 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -380,6 +380,12 @@ enum { /* *************** BEZTRIPLE **************** */ +/* BezTriple.f1,2,3 */ +typedef enum eBezTriple_Flag { + /* SELECT */ + BEZT_FLAG_TEMP_TAG = (1 << 1), /* always clear. */ +} eBezTriple_Flag; + /* h1 h2 (beztriple) */ typedef enum eBezTriple_Handle { HD_FREE = 0, diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 5e36250497c..267ac16e1be 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -194,10 +194,12 @@ static PointerRNA rna_uiItemO(uiLayout *layout, const char *opname, const char * icon = icon_value; } - flag = UI_ITEM_O_RETURN_PROPS; + flag = 0; flag |= (emboss) ? 0 : UI_ITEM_R_NO_BG; - return uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag); + PointerRNA opptr; + uiItemFullO_ptr(layout, ot, name, icon, NULL, uiLayoutGetOperatorContext(layout), flag, &opptr); + return opptr; } static void rna_uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opname, const char *propname, const char *name, @@ -213,8 +215,7 @@ static void rna_uiItemMenuEnumO(uiLayout *layout, bContext *C, const char *opnam /* Get translated name (label). */ name = rna_translate_ui_text(name, text_ctxt, ot->srna, NULL, translate); - /* XXX This will search operator again :( */ - uiItemMenuEnumO(layout, C, opname, propname, name, icon); + uiItemMenuEnumO_ptr(layout, C, ot, propname, name, icon); } static void rna_uiItemL(uiLayout *layout, const char *name, const char *text_ctxt, int translate, diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 53d3cd31485..800be7a3720 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1251,7 +1251,7 @@ int WM_operator_confirm_message_ex(bContext *C, wmOperator *op, pup = UI_popup_menu_begin(C, title, icon); layout = UI_popup_menu_layout(pup); - uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0); + uiItemFullO_ptr(layout, op->type, message, ICON_NONE, properties, WM_OP_EXEC_REGION_WIN, 0, NULL); UI_popup_menu_end(C, pup); return OPERATOR_INTERFACE; @@ -2019,13 +2019,11 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar "https://docs.blender.org/manual/en/dev/"); uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org"); if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) { - BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d" - STRINGIFY(BLENDER_VERSION_CHAR) "_release", + BLI_snprintf(url, sizeof(url), "https://docs.blender.org/api/%d.%d"STRINGIFY(BLENDER_VERSION_CHAR), BLENDER_VERSION / 100, BLENDER_VERSION % 100); } else { - BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d_%d", - BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); + BLI_snprintf(url, sizeof(url), "https://docs.blender.org/api/master"); } uiItemStringO(col, IFACE_("Python API Reference"), ICON_URL, "WM_OT_url_open", "url", url); uiItemL(col, "", ICON_NONE); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 6f874e7728c..31a636e4a85 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -632,8 +632,8 @@ void ED_curve_editnurb_make(struct Object *obedit) RET_NONE void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon) RET_NONE -struct PointerRNA uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag) RET_STRUCT(PointerRNA) -PointerRNA uiItemFullO_ptr(struct uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag) RET_STRUCT(PointerRNA) +void uiItemFullO(uiLayout *layout, const char *idname, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr) RET_NONE +void uiItemFullO_ptr(struct uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, struct IDProperty *properties, int context, int flag, struct PointerRNA *r_opptr) RET_NONE struct uiLayout *uiLayoutRow(uiLayout *layout, int align) RET_NULL struct uiLayout *uiLayoutColumn(uiLayout *layout, int align) RET_NULL struct uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align) RET_NULL @@ -649,6 +649,7 @@ void uiItemPointerR(uiLayout *layout, struct PointerRNA *ptr, const char *propna void uiItemsEnumO(uiLayout *layout, const char *opname, const char *propname) RET_NONE void uiItemEnumO_string(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, const char *value) RET_NONE void uiItemMenuEnumO(uiLayout *layout, struct bContext *C, const char *opname, const char *propname, const char *name, int icon) RET_NONE +void uiItemMenuEnumO_ptr(uiLayout *layout, struct bContext *C, struct wmOperatorType *ot, const char *propname, const char *name, int icon) RET_NONE void uiItemBooleanO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) RET_NONE void uiItemIntO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, int value) RET_NONE void uiItemFloatO(uiLayout *layout, const char *name, int icon, const char *opname, const char *propname, float value) RET_NONE |