diff options
Diffstat (limited to 'source/blender/editors')
48 files changed, 591 insertions, 370 deletions
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index d3d00fc44f2..8dfb8177ddb 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -270,7 +270,7 @@ static void joined_armature_fix_links( } /* join armature exec is exported for use in object->join objects operator... */ -int join_armature_exec(bContext *C, wmOperator *op) +int ED_armature_join_objects_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -754,7 +754,7 @@ static void bone_connect_to_new_parent(ListBase *edbo, float offset[3]; if ((selbone->parent) && (selbone->flag & BONE_CONNECTED)) { - selbone->parent->flag &= ~(BONE_TIPSEL); + selbone->parent->flag &= ~BONE_TIPSEL; } /* make actbone the parent of selbone */ @@ -956,7 +956,7 @@ static void editbone_clear_parent(EditBone *ebone, int mode) { if (ebone->parent) { /* for nice selection */ - ebone->parent->flag &= ~(BONE_TIPSEL); + ebone->parent->flag &= ~BONE_TIPSEL; } if (mode == 1) { diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index eb7c1bc74ea..ccd39429704 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -188,7 +188,7 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode Base *base = NULL; bool sel; - hitresult &= ~(BONESEL_ANY); + hitresult &= ~BONESEL_ANY; /* Determine what the current bone is */ if (is_editmode == false) { base = ED_armature_base_and_pchan_from_select_buffer(bases, bases_len, hitresult, &pchan); @@ -1302,7 +1302,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (ebone->parent) { - ebone->parent->flag |= (BONE_TIPSEL); + ebone->parent->flag |= BONE_TIPSEL; } } break; @@ -1317,7 +1317,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (ebone->parent) { - ebone->parent->flag |= (BONE_TIPSEL); + ebone->parent->flag |= BONE_TIPSEL; } } } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 82f5d99aa47..a39c8261b32 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6895,7 +6895,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot) * This is used externally, by #OBJECT_OT_join. * TODO: shape keys - as with meshes. */ -int join_curve_exec(bContext *C, wmOperator *op) +int ED_curve_join_objects_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c index 9294bc6e91b..73f970876b1 100644 --- a/source/blender/editors/curve/editcurve_select.c +++ b/source/blender/editors/curve/editcurve_select.c @@ -988,7 +988,7 @@ void CURVE_OT_select_more(wmOperatorType *ot) /* identifiers */ ot->name = "Select More"; ot->idname = "CURVE_OT_select_more"; - ot->description = "Select control points directly linked to already selected ones"; + ot->description = "Select control points at the boundary of each selection region"; /* api callbacks */ ot->exec = curve_select_more_exec; @@ -1203,7 +1203,7 @@ void CURVE_OT_select_less(wmOperatorType *ot) /* identifiers */ ot->name = "Select Less"; ot->idname = "CURVE_OT_select_less"; - ot->description = "Reduce current selection by deselecting boundary elements"; + ot->description = "Deselect control points at the boundary of each selection region"; /* api callbacks */ ot->exec = curve_select_less_exec; diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index 5c5adb32a97..2bd83475f00 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -381,10 +381,11 @@ static void gp_stroke_convertcoords(tGPsdata *p, const float mval[2], float out[ } } -/* Apply smooth to buffer while drawing +/** + * Apply smooth to buffer while drawing * to smooth point C, use 2 before (A, B) and current point (D): * - * A----B-----C------D + * `A----B-----C------D` * * \param p: Temp data * \param inf: Influence factor @@ -2053,7 +2054,7 @@ static void annotation_draw_apply_event( /* Key to toggle stabilization. */ if (event->shift > 0 && p->paintmode == GP_PAINTMODE_DRAW) { /* Using permanent stabilization, shift will deactivate the flag. */ - if (p->flags & (GP_PAINTFLAG_USE_STABILIZER)) { + if (p->flags & GP_PAINTFLAG_USE_STABILIZER) { if (p->flags & GP_PAINTFLAG_USE_STABILIZER_TEMP) { gpencil_draw_toggle_stabilizer_cursor(p, false); p->flags &= ~GP_PAINTFLAG_USE_STABILIZER_TEMP; diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index d2b1eba7d86..5db2e904dee 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -282,8 +282,10 @@ void ED_gplayer_frames_duplicate(bGPDlayer *gpl) } } -/* Set keyframe type for selected frames from given gp-layer - * \param type: The type of keyframe (eBezTriple_KeyframeType) to set selected frames to +/** + * Set keyframe type for selected frames from given gp-layer + * + * \param type: The type of keyframe (#eBezTriple_KeyframeType) to set selected frames to. */ void ED_gplayer_frames_keytype_set(bGPDlayer *gpl, short type) { diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 502097a0678..ab52a484d2f 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -472,15 +472,16 @@ static void set_pixel(ImBuf *ibuf, int idx, const float col[4]) } } -/* check if the size of the leak is narrow to determine if the stroke is closed +/** + * Check if the size of the leak is narrow to determine if the stroke is closed * this is used for strokes with small gaps between them to get a full fill * and do not get a full screen fill. * - * \param ibuf: Image pixel data - * \param maxpixel: Maximum index - * \param limit: Limit of pixels to analyze - * \param index: Index of current pixel - * \param type: 0-Horizontal 1-Vertical + * \param ibuf: Image pixel data. + * \param maxpixel: Maximum index. + * \param limit: Limit of pixels to analyze. + * \param index: Index of current pixel. + * \param type: 0-Horizontal 1-Vertical. */ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index, int type) { @@ -576,11 +577,12 @@ static bool is_leak_narrow(ImBuf *ibuf, const int maxpixel, int limit, int index return (bool)(t_a && t_b); } -/* Boundary fill inside strokes +/** + * Boundary fill inside strokes * Fills the space created by a set of strokes using the stroke color as the boundary * of the shape to fill. * - * \param tgpf: Temporary fill data + * \param tgpf: Temporary fill data. */ static void gpencil_boundaryfill_area(tGPDfill *tgpf) { diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index a9eb94498ad..e3512b8660f 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -551,10 +551,11 @@ static void gp_brush_angle(bGPdata *gpd, Brush *brush, tGPspoint *pt, const floa } } -/* Apply smooth to buffer while drawing +/** + * Apply smooth to buffer while drawing * to smooth point C, use 2 before (A, B) and current point (D): * - * A----B-----C------D + * `A----B-----C------D` * * \param p: Temp data * \param inf: Influence factor diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 52274520176..fd5131ce867 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -286,7 +286,8 @@ bGPdata *ED_gpencil_data_get_active(const bContext *C) return ob->data; } -/* Get the active Grease Pencil datablock +/** + * Get the active Grease Pencil datablock * \note This is the original (bmain) copy of the datablock, stored in files. * Do not use for reading evaluated copies of GP Objects data */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 541e2633512..eef431c40fa 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -174,7 +174,7 @@ void ED_operatormacros_armature(void); void ED_keymap_armature(struct wmKeyConfig *keyconf); /* armature_relations.c */ -int join_armature_exec(struct bContext *C, struct wmOperator *op); +int ED_armature_join_objects_exec(struct bContext *C, struct wmOperator *op); /* armature_select.c */ struct Base *ED_armature_base_and_ebone_from_select_buffer(struct Base **bases, diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 95c454043da..79f5f62f293 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -66,7 +66,7 @@ int ED_curve_nurb_select_count(struct View3D *v3d, struct Nurb *nu); bool ED_curve_nurb_select_all(const struct Nurb *nu); bool ED_curve_nurb_deselect_all(const struct Nurb *nu); -int join_curve_exec(struct bContext *C, struct wmOperator *op); +int ED_curve_join_objects_exec(struct bContext *C, struct wmOperator *op); /* editcurve_select.c */ bool ED_curve_select_check(struct View3D *v3d, struct EditNurb *editnurb); diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 938d1059f90..5c2106b934c 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -38,8 +38,12 @@ void ED_operatortypes_metaball(void); void ED_operatormacros_metaball(void); void ED_keymap_metaball(struct wmKeyConfig *keyconf); -struct MetaElem *ED_mball_add_primitive( - struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type); +struct MetaElem *ED_mball_add_primitive(struct bContext *C, + struct Object *obedit, + bool obedit_is_new, + float mat[4][4], + float dia, + int type); bool ED_mball_select_pick( struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 20e54df1ccb..17e2043a7a8 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -445,8 +445,8 @@ void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalct void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess); /* *** meshtools.c *** */ -int join_mesh_exec(struct bContext *C, struct wmOperator *op); -int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op); +int ED_mesh_join_objects_exec(struct bContext *C, struct wmOperator *op); +int ED_mesh_shapes_join_objects_exec(struct bContext *C, struct wmOperator *op); /* mirror lookup api */ /* Spatial Mirror */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 42feda0e1bc..3f3f0513184 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -4872,7 +4872,7 @@ static void ui_numedit_set_active(uiBut *but) /* Don't change the cursor once pressed. */ if ((but->flag & UI_SELECT) == 0) { - if ((but->drawflag & (UI_BUT_ACTIVE_LEFT)) || (but->drawflag & (UI_BUT_ACTIVE_RIGHT))) { + if ((but->drawflag & UI_BUT_ACTIVE_LEFT) || (but->drawflag & UI_BUT_ACTIVE_RIGHT)) { if (data->changed_cursor) { WM_cursor_modal_restore(data->window); data->changed_cursor = false; @@ -9947,7 +9947,7 @@ static int ui_handle_menu_event(bContext *C, if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) { if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) { /* for root menus, allow clicking to close */ - if (block->flag & (UI_BLOCK_OUT_1)) { + if (block->flag & UI_BLOCK_OUT_1) { menu->menuretval = UI_RETURN_OK; } else { @@ -9955,7 +9955,7 @@ static int ui_handle_menu_event(bContext *C, } } else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) { - if (block->flag & (UI_BLOCK_OUT_1)) { + if (block->flag & UI_BLOCK_OUT_1) { menu->menuretval = UI_RETURN_OK; } else { @@ -10049,7 +10049,7 @@ static int ui_handle_menu_event(bContext *C, /* strict check, and include the parent rect */ if (!menu->dotowards && !saferct) { - if (block->flag & (UI_BLOCK_OUT_1)) { + if (block->flag & UI_BLOCK_OUT_1) { menu->menuretval = UI_RETURN_OK; } else { diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 55657d7297a..4fff80d5def 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -583,6 +583,26 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region) /****************************** panels ******************************/ +/** + * Set flag state for a panel and its subpanels. + * + * \return True if this function changed any of the flags, false if it didn't. + */ +static bool panel_set_flag_recursive(Panel *panel, int flag, bool value) +{ + short flag_original = panel->flag; + + SET_FLAG_FROM_TEST(panel->flag, value, flag); + + bool changed = (flag_original != panel->flag); + + LISTBASE_FOREACH (Panel *, child, &panel->children) { + changed |= panel_set_flag_recursive(child, flag, value); + } + + return changed; +} + static void panels_collapse_all(const bContext *C, ScrArea *area, ARegion *region, @@ -980,7 +1000,7 @@ void ui_draw_aligned_panel(uiStyle *style, * can't be dragged. This may be changed in future. */ show_background); const int panel_col = is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK; - const bool draw_box_style = (panel->type && panel->type->flag & (PNL_DRAW_BOX)); + const bool draw_box_style = (panel->type && panel->type->flag & PNL_DRAW_BOX); /* Use the theme for box widgets for box-style panels. */ uiWidgetColors *box_wcol = NULL; @@ -2017,11 +2037,25 @@ static void ui_handle_panel_header( if (button == 2) { /* close */ ED_region_tag_redraw(region); } - else { /* collapse */ + else { + /* Collapse and expand panels. */ + if (ctrl) { /* Only collapse all for parent panels. */ if (block->panel->type != NULL && block->panel->type->parent == NULL) { - panels_collapse_all(C, area, region, block->panel); + if (block->panel->flag & PNL_CLOSED || BLI_listbase_is_empty(&block->panel->children)) { + panels_collapse_all(C, area, region, block->panel); + } + else { + const int closed_flag = (align == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY; + /* If a panel has subpanels and it's open, toggle the expansion + * of the subpanels (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); @@ -2899,24 +2933,6 @@ static void ui_handler_remove_panel(bContext *C, void *userdata) panel_activate_state(C, panel, PANEL_STATE_EXIT); } -/** - * Set selection state for a panel and its subpanels. The subpanels need to know they are selected - * too so they can be drawn above their parent when it is dragged. - */ -static void set_panel_selection(Panel *panel, bool value) -{ - if (value) { - panel->flag |= PNL_SELECT; - } - else { - panel->flag &= ~PNL_SELECT; - } - - LISTBASE_FOREACH (Panel *, child, &panel->children) { - set_panel_selection(child, value); - } -} - static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state) { uiHandlePanelData *data = panel->activedata; @@ -2929,6 +2945,8 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG); + /* Set selection state for the panel and its subpanels, which need to know they are selected + * too so they can be drawn above their parent when it's dragged. */ if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) { if (data && data->state != PANEL_STATE_ANIMATION) { /* XXX: @@ -2941,10 +2959,10 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS check_panel_overlap(region, NULL); /* clears */ } - set_panel_selection(panel, false); + panel_set_flag_recursive(panel, PNL_SELECT, false); } else { - set_panel_selection(panel, true); + panel_set_flag_recursive(panel, PNL_SELECT, true); } if (data && data->animtimer) { diff --git a/source/blender/editors/interface/interface_region_menu_popup.c b/source/blender/editors/interface/interface_region_menu_popup.c index 3e34b7f3f8a..65f5798bdce 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.c +++ b/source/blender/editors/interface/interface_region_menu_popup.c @@ -184,7 +184,12 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi pup->block->handle = NULL; } - if (pup->but) { + /* Find block minimum width. */ + if (uiLayoutGetUnitsX(pup->layout) != 0.0f) { + /* Use the minimum width from the layout if it's set. */ + minwidth = uiLayoutGetUnitsX(pup->layout) * UI_UNIT_X; + } + else if (pup->but) { /* minimum width to enforece */ if (pup->but->drawstr[0]) { minwidth = BLI_rctf_size_x(&pup->but->rect); @@ -193,7 +198,13 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi /* For buttons with no text, use the minimum (typically icon only). */ minwidth = UI_MENU_WIDTH_MIN; } + } + else { + minwidth = UI_MENU_WIDTH_MIN; + } + /* Find block direction. */ + if (pup->but) { if (pup->block->direction != 0) { /* allow overriding the direction from menu_func */ direction = pup->block->direction; @@ -203,7 +214,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi } } else { - minwidth = UI_MENU_WIDTH_MIN; direction = UI_DIR_DOWN; } diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index f8419ba3eba..8fee9df8706 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -113,10 +113,10 @@ BLI_INLINE void clamp_rctf_to_rcti(rcti *dst, const rctf *src) static int view2d_scroll_mapped(int scroll) { if (scroll & V2D_SCROLL_HORIZONTAL_FULLR) { - scroll &= ~(V2D_SCROLL_HORIZONTAL); + scroll &= ~V2D_SCROLL_HORIZONTAL; } if (scroll & V2D_SCROLL_VERTICAL_FULLR) { - scroll &= ~(V2D_SCROLL_VERTICAL); + scroll &= ~V2D_SCROLL_VERTICAL; } return scroll; } @@ -198,7 +198,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll) } /* horizontal scroller */ - if (scroll & (V2D_SCROLL_BOTTOM)) { + if (scroll & V2D_SCROLL_BOTTOM) { /* on bottom edge of region */ v2d->hor = *mask_scroll; v2d->hor.ymax = scroll_height; @@ -211,7 +211,7 @@ static void view2d_masks(View2D *v2d, const rcti *mask_scroll) /* adjust vertical scroller if there's a horizontal scroller, to leave corner free */ if (scroll & V2D_SCROLL_VERTICAL) { - if (scroll & (V2D_SCROLL_BOTTOM)) { + if (scroll & V2D_SCROLL_BOTTOM) { /* on bottom edge of region */ v2d->vert.ymin = v2d->hor.ymax; } diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 98bbd7af943..34108853c61 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -2299,8 +2299,8 @@ static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent * } /* zone is also inappropriate if scroller is not visible... */ - if (((vsm->scroller == 'h') && (v2d->scroll & (V2D_SCROLL_HORIZONTAL_FULLR))) || - ((vsm->scroller == 'v') && (v2d->scroll & (V2D_SCROLL_VERTICAL_FULLR)))) { + if (((vsm->scroller == 'h') && (v2d->scroll & V2D_SCROLL_HORIZONTAL_FULLR)) || + ((vsm->scroller == 'v') && (v2d->scroll & V2D_SCROLL_VERTICAL_FULLR))) { /* free customdata initialized */ scroller_activate_exit(C, op); diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index fc2c55ffeda..2de03363a77 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -410,8 +410,11 @@ void WM_OT_alembic_export(wmOperatorType *ot) "Use Subdivision Schema", "Export meshes using Alembic's subdivision schema"); - RNA_def_boolean( - ot->srna, "apply_subdiv", 0, "Apply Subdivision Surface", "Export subdivision surfaces as meshes"); + RNA_def_boolean(ot->srna, + "apply_subdiv", + 0, + "Apply Subdivision Surface", + "Export subdivision surfaces as meshes"); RNA_def_boolean(ot->srna, "curves_as_mesh", diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 917bbe61e3d..1bdf2ede22a 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -297,7 +297,7 @@ static void join_mesh_single(Depsgraph *depsgraph, *mpoly_pp += me->totpoly; } -int join_mesh_exec(bContext *C, wmOperator *op) +int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -706,12 +706,14 @@ int join_mesh_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/*********************** JOIN AS SHAPES ***************************/ +/* -------------------------------------------------------------------- */ +/** \name Join as Shapes + * \{ */ /* Append selected meshes vertex locations as shapes of the active mesh, * return 0 if no join is made (error) and 1 of the join is done */ -int join_mesh_shapes_exec(bContext *C, wmOperator *op) +int ED_mesh_shapes_join_objects_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -796,6 +798,8 @@ int join_mesh_shapes_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Mesh Topology Mirror API * \{ */ diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index a25175510cd..094011ebef1 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -58,6 +58,10 @@ #include "mball_intern.h" +/* -------------------------------------------------------------------- */ +/** \name Edit Mode Functions + * \{ */ + /* This function is used to free all MetaElems from MetaBall */ void ED_mball_editmball_free(Object *obedit) { @@ -93,9 +97,36 @@ void ED_mball_editmball_load(Object *UNUSED(obedit)) { } -/* Add metaelem primitive to metaball object (which is in edit mode) */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Selection + * \{ */ + +bool ED_mball_deselect_all_multi(bContext *C) +{ + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ViewContext vc; + ED_view3d_viewcontext_init(C, &vc, depsgraph); + uint bases_len = 0; + Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( + vc.view_layer, vc.v3d, &bases_len); + bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len); + MEM_freeN(bases); + return changed_multi; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Add Meta Primitive Utility + * \{ */ + +/** + * Add meta-element primitive to meta-ball object (which is in edit mode). + */ MetaElem *ED_mball_add_primitive( - bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type) + bContext *UNUSED(C), Object *obedit, bool obedit_is_new, float mat[4][4], float dia, int type) { MetaBall *mball = (MetaBall *)obedit->data; MetaElem *ml; @@ -109,16 +140,28 @@ MetaElem *ED_mball_add_primitive( ml = BKE_mball_element_add(mball, type); ml->rad *= dia; - mball->wiresize *= dia; - mball->rendersize *= dia; + + if (obedit_is_new) { + mball->wiresize *= dia; + mball->rendersize *= dia; + } copy_v3_v3(&ml->x, mat[3]); + /* MB_ELIPSOID works differently (intentional?). Whatever the case, + * on testing this needs to be skipped otherwise it doesn't behave like other types. */ + if (type != MB_ELIPSOID) { + mul_v3_fl(&ml->expx, dia); + } ml->flag |= SELECT; mball->lastelem = ml; return ml; } -/***************************** Select/Deselect operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select/Deselect Operator + * \{ */ /* Select or deselect all MetaElements */ static int mball_select_all_exec(bContext *C, wmOperator *op) @@ -175,8 +218,11 @@ void MBALL_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/** \} */ + /* -------------------------------------------------------------------- */ -/* Select Similar */ +/** \name Select Similar Operator + * \{ */ enum { SIMMBALL_TYPE = 1, @@ -428,9 +474,12 @@ void MBALL_OT_select_similar(wmOperatorType *ot) RNA_def_float(ot->srna, "threshold", 0.1, 0.0, FLT_MAX, "Threshold", "", 0.01, 1.0); } -/***************************** Select random operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Random Operator + * \{ */ -/* Random metaball selection */ static int select_random_metaelems_exec(bContext *C, wmOperator *op) { const bool select = (RNA_enum_get(op->ptr, "action") == SEL_SELECT); @@ -494,7 +543,11 @@ void MBALL_OT_select_random_metaelems(struct wmOperatorType *ot) WM_operator_properties_select_random(ot); } -/***************************** Duplicate operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Duplicate Meta-Ball Operator + * \{ */ /* Duplicate selected MetaElements */ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) @@ -546,9 +599,14 @@ void MBALL_OT_duplicate_metaelems(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/***************************** Delete operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Delete Meta-Ball Operator + * + * Delete all selected MetaElems (not MetaBall). + * \{ */ -/* Delete all selected MetaElems (not MetaBall) */ static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -601,9 +659,12 @@ void MBALL_OT_delete_metaelems(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/***************************** Hide operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Hide Meta-Elements Operator + * \{ */ -/* Hide selected MetaElems */ static int hide_metaelems_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -646,9 +707,12 @@ void MBALL_OT_hide_metaelems(wmOperatorType *ot) ot->srna, "unselected", false, "Unselected", "Hide unselected rather than selected"); } -/***************************** Unhide operator *****************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Un-Hide Meta-Elements Operator + * \{ */ -/* Unhide all edited MetaElems */ static int reveal_metaelems_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -689,6 +753,12 @@ void MBALL_OT_reveal_metaelems(wmOperatorType *ot) RNA_def_boolean(ot->srna, "select", true, "Select", ""); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Select Pick Utility + * \{ */ + /* Select MetaElement with mouse click (user can select radius circle or * stiffness circle) */ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) @@ -740,7 +810,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese continue; } - if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) { + if (metaelem_id != (hitresult & 0xFFFF0000 & ~MBALLSEL_ANY)) { continue; } @@ -831,15 +901,4 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese return false; } -bool ED_mball_deselect_all_multi(bContext *C) -{ - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - ViewContext vc; - ED_view3d_viewcontext_init(C, &vc, depsgraph); - uint bases_len = 0; - Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( - vc.view_layer, vc.v3d, &bases_len); - bool changed_multi = BKE_mball_deselect_all_multi_ex(bases, bases_len); - MEM_freeN(bases); - return changed_multi; -} +/** \} */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 5af586942dc..b60ce459ba6 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -860,7 +860,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) * we want to pass in 1 so other values such as resolution are scaled by 1.0. */ dia = RNA_float_get(op->ptr, "radius") / 2; - ED_mball_add_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type")); + ED_mball_add_primitive(C, obedit, newob, mat, dia, RNA_enum_get(op->ptr, "type")); /* userdef */ if (newob && !enter_editmode) { @@ -2136,7 +2136,7 @@ static const EnumPropertyItem convert_target_items[] = { {0, NULL, 0, NULL, NULL}, }; -static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob) +static void object_data_convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Object *ob) { if (ob->runtime.curve_cache == NULL) { /* Force creation. This is normally not needed but on operator @@ -2155,7 +2155,7 @@ static void convert_ensure_curve_cache(Depsgraph *depsgraph, Scene *scene, Objec } } -static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob) +static void object_data_convert_curve_to_mesh(Main *bmain, Depsgraph *depsgraph, Object *ob) { Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); Curve *curve = ob->data; @@ -2188,7 +2188,7 @@ static void curvetomesh(Main *bmain, Depsgraph *depsgraph, Object *ob) } } -static bool convert_poll(bContext *C) +static bool object_convert_poll(bContext *C) { Scene *scene = CTX_data_scene(C); Base *base_act = CTX_data_active_base(C); @@ -2198,7 +2198,7 @@ static bool convert_poll(bContext *C) (base_act->flag & BASE_SELECTED) && !ID_IS_LINKED(obact)); } -/* Helper for convert_exec */ +/* Helper for object_convert_exec */ static Base *duplibase_for_convert( Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob) { @@ -2233,7 +2233,7 @@ static Base *duplibase_for_convert( * time we need to duplicate an object to convert it. Even worse, this is not 100% correct, since * we do not yet have duplicated obdata. * However, that is a safe solution for now. Proper, longer-term solution is to refactor - * convert_exec to: + * object_convert_exec to: * - duplicate all data it needs to in a first loop. * - do a single update. * - convert data in a second loop. */ @@ -2251,7 +2251,7 @@ static Base *duplibase_for_convert( return basen; } -static int convert_exec(bContext *C, wmOperator *op) +static int object_convert_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -2528,7 +2528,7 @@ static int convert_exec(bContext *C, wmOperator *op) if (target == OB_MESH) { /* No assumption should be made that the resulting objects is a mesh, as conversion can * fail. */ - curvetomesh(bmain, depsgraph, newob); + object_data_convert_curve_to_mesh(bmain, depsgraph, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); } @@ -2553,7 +2553,7 @@ static int convert_exec(bContext *C, wmOperator *op) /* No assumption should be made that the resulting objects is a mesh, as conversion can * fail. */ - curvetomesh(bmain, depsgraph, newob); + object_data_convert_curve_to_mesh(bmain, depsgraph, newob); /* meshes doesn't use displist */ BKE_object_free_curve_cache(newob); } @@ -2607,7 +2607,7 @@ static int convert_exec(bContext *C, wmOperator *op) } } - convert_ensure_curve_cache(depsgraph, scene, baseob); + object_data_convert_ensure_curve_cache(depsgraph, scene, baseob); BKE_mesh_from_metaball(&baseob->runtime.curve_cache->disp, newob->data); if (obact->type == OB_MBALL) { @@ -2710,7 +2710,7 @@ static int convert_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static void convert_ui(bContext *C, wmOperator *op) +static void object_convert_ui(bContext *UNUSED(C), wmOperator *op) { uiLayout *layout = op->layout; PointerRNA ptr; @@ -2739,9 +2739,9 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* api callbacks */ ot->invoke = WM_menu_invoke; - ot->exec = convert_exec; - ot->poll = convert_poll; - ot->ui = convert_ui; + ot->exec = object_convert_exec; + ot->poll = object_convert_poll; + ot->ui = object_convert_ui; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2797,8 +2797,12 @@ void OBJECT_OT_convert(wmOperatorType *ot) /* used below, assumes id.new is correct */ /* leaves selection of base/object unaltered */ /* Does set ID->newid pointers. */ -static Base *object_add_duplicate_internal( - Main *bmain, Scene *scene, ViewLayer *view_layer, Object *ob, const eDupli_ID_Flags dupflag) +static Base *object_add_duplicate_internal(Main *bmain, + Scene *scene, + ViewLayer *view_layer, + Object *ob, + const eDupli_ID_Flags dupflag, + const eLibIDDuplicateFlags duplicate_options) { Base *base, *basen = NULL; Object *obn; @@ -2807,7 +2811,7 @@ static Base *object_add_duplicate_internal( /* nothing? */ } else { - obn = ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag)); + obn = ID_NEW_SET(ob, BKE_object_duplicate(bmain, ob, dupflag, duplicate_options)); DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); base = BKE_view_layer_base_find(view_layer, ob); @@ -2851,7 +2855,8 @@ Base *ED_object_add_duplicate( Base *basen; Object *ob; - basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag); + basen = object_add_duplicate_internal( + bmain, scene, view_layer, base->object, dupflag, LIB_ID_DUPLICATE_IS_SUBPROCESS); if (basen == NULL) { return NULL; } @@ -2882,7 +2887,8 @@ static int duplicate_exec(bContext *C, wmOperator *op) const eDupli_ID_Flags dupflag = (linked) ? 0 : (eDupli_ID_Flags)U.dupflag; CTX_DATA_BEGIN (C, Base *, base, selected_bases) { - Base *basen = object_add_duplicate_internal(bmain, scene, view_layer, base->object, dupflag); + Base *basen = object_add_duplicate_internal( + bmain, scene, view_layer, base->object, dupflag, 0); /* note that this is safe to do with this context iterator, * the list is made in advance */ @@ -2953,7 +2959,7 @@ void OBJECT_OT_duplicate(wmOperatorType *ot) * Use for drag & drop. * \{ */ -static int add_named_exec(bContext *C, wmOperator *op) +static int object_add_named_exec(bContext *C, wmOperator *op) { wmWindow *win = CTX_wm_window(C); const wmEvent *event = win ? win->eventstate : NULL; @@ -2976,7 +2982,7 @@ static int add_named_exec(bContext *C, wmOperator *op) } /* prepare dupli */ - basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag); + basen = object_add_duplicate_internal(bmain, scene, view_layer, ob, dupflag, 0); if (basen == NULL) { BKE_report(op->reports, RPT_ERROR, "Object could not be duplicated"); @@ -3016,7 +3022,7 @@ void OBJECT_OT_add_named(wmOperatorType *ot) ot->idname = "OBJECT_OT_add_named"; /* api callbacks */ - ot->exec = add_named_exec; + ot->exec = object_add_named_exec; ot->poll = ED_operator_objectmode; /* flags */ @@ -3037,7 +3043,7 @@ void OBJECT_OT_add_named(wmOperatorType *ot) * * \{ */ -static bool join_poll(bContext *C) +static bool object_join_poll(bContext *C) { Object *ob = CTX_data_active_object(C); @@ -3053,7 +3059,7 @@ static bool join_poll(bContext *C) } } -static int join_exec(bContext *C, wmOperator *op) +static int object_join_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); @@ -3074,13 +3080,13 @@ static int join_exec(bContext *C, wmOperator *op) } if (ob->type == OB_MESH) { - return join_mesh_exec(C, op); + return ED_mesh_join_objects_exec(C, op); } else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { - return join_curve_exec(C, op); + return ED_curve_join_objects_exec(C, op); } else if (ob->type == OB_ARMATURE) { - return join_armature_exec(C, op); + return ED_armature_join_objects_exec(C, op); } else if (ob->type == OB_GPENCIL) { return ED_gpencil_join_objects_exec(C, op); @@ -3097,8 +3103,8 @@ void OBJECT_OT_join(wmOperatorType *ot) ot->idname = "OBJECT_OT_join"; /* api callbacks */ - ot->exec = join_exec; - ot->poll = join_poll; + ot->exec = object_join_exec; + ot->poll = object_join_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3141,7 +3147,7 @@ static int join_shapes_exec(bContext *C, wmOperator *op) } if (ob->type == OB_MESH) { - return join_mesh_shapes_exec(C, op); + return ED_mesh_shapes_join_objects_exec(C, op); } return OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d522dcabae3..90dd16ea393 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1771,15 +1771,8 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout const char *name = BKE_collection_ui_name_get(menu->collection); UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP); - uiItemIntO(layout, name, ICON_NONE, menu->ot->idname, "collection_index", menu->index); - uiItemS(layout); - - for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL; - submenu = submenu->next) { - move_to_collection_menus_items(layout, submenu); - } - uiItemS(layout); + // uiItemS(layout); WM_operator_properties_create_ptr(&menu->ptr, menu->ot); RNA_int_set(&menu->ptr, "collection_index", menu->index); @@ -1787,6 +1780,15 @@ static void move_to_collection_menu_create(bContext *UNUSED(C), uiLayout *layout uiItemFullO_ptr( layout, menu->ot, "New Collection", ICON_ADD, menu->ptr.data, WM_OP_INVOKE_DEFAULT, 0, NULL); + + uiItemS(layout); + + uiItemIntO(layout, name, ICON_SCENE_DATA, menu->ot->idname, "collection_index", menu->index); + + for (MoveToCollectionData *submenu = menu->submenus.first; submenu != NULL; + submenu = submenu->next) { + move_to_collection_menus_items(layout, submenu); + } } static void move_to_collection_menus_items(uiLayout *layout, MoveToCollectionData *menu) diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c index c518fd32c7f..5d4476ecb8c 100644 --- a/source/blender/editors/object/object_modes.c +++ b/source/blender/editors/object/object_modes.c @@ -116,7 +116,7 @@ bool ED_object_mode_compat_test(const Object *ob, eObjectMode mode) case OB_SURF: case OB_FONT: case OB_MBALL: - if (mode & (OB_MODE_EDIT)) { + if (mode & OB_MODE_EDIT) { return true; } break; diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index c04122edd36..5ea02de1e45 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1145,7 +1145,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region) /* find overlapping previous region on same place */ for (ar1 = region->prev; ar1; ar1 = ar1->prev) { - if (ar1->flag & (RGN_FLAG_HIDDEN)) { + if (ar1->flag & RGN_FLAG_HIDDEN) { continue; } @@ -1194,7 +1194,7 @@ static void region_overlap_fix(ScrArea *area, ARegion *region) /* At this point, 'region' is in its final position and still open. * Make a final check it does not overlap any previous 'other side' region. */ for (ar1 = region->prev; ar1; ar1 = ar1->prev) { - if (ar1->flag & (RGN_FLAG_HIDDEN)) { + if (ar1->flag & RGN_FLAG_HIDDEN) { continue; } if (ELEM(ar1->alignment, RGN_ALIGN_FLOAT)) { @@ -2566,16 +2566,16 @@ void ED_region_panels_layout_ex(const bContext *C, /* 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); + 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); + v2d->scroll |= V2D_SCROLL_BOTTOM; + v2d->scroll &= ~V2D_SCROLL_RIGHT; } /* collect categories */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index b2243f2ccb9..5fcd10d0feb 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4311,7 +4311,7 @@ static int match_region_with_redraws(int spacetype, } break; case SPACE_NODE: - if (redraws & (TIME_NODES)) { + if (redraws & TIME_NODES) { return 1; } break; diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 2c6f708d82a..447d5373a48 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -909,7 +909,7 @@ PaintStroke *paint_stroke_new(bContext *C, stroke->zoom_2d = max_ff(zoomx, zoomy); if (stroke->stroke_mode == BRUSH_STROKE_INVERT) { - if (br->flag & (BRUSH_CURVE)) { + if (br->flag & BRUSH_CURVE) { RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL); } } @@ -1467,8 +1467,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event) } else if (first_modal || /* regular dabs */ - (!(br->flag & (BRUSH_AIRBRUSH)) && - (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) || + (!(br->flag & BRUSH_AIRBRUSH) && (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) || /* airbrush */ ((br->flag & BRUSH_AIRBRUSH) && event->type == TIMER && event->customdata == stroke->timer)) { diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index e92ea906237..1e4919761a1 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -128,7 +128,7 @@ static SpaceLink *action_new(const ScrArea *area, const Scene *scene) region->v2d.minzoom = 0.01f; region->v2d.maxzoom = 50; region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES); - region->v2d.scroll |= (V2D_SCROLL_RIGHT); + region->v2d.scroll |= V2D_SCROLL_RIGHT; region->v2d.keepzoom = V2D_LOCKZOOM_Y; region->v2d.keepofs = V2D_KEEPOFS_Y; region->v2d.align = V2D_ALIGN_NO_POS_Y; diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 84ab5e6524b..c3aca95910b 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -118,7 +118,7 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene) MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; MovieTrackingDopesheetChannel *channel; float strip[4], selected_strip[4]; - float height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT); + float height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT; uint keyframe_len = 0; @@ -305,7 +305,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *region) MovieTracking *tracking = &clip->tracking; MovieTrackingDopesheet *dopesheet = &tracking->dopesheet; - int height = (dopesheet->tot_channel * CHANNEL_STEP) + (CHANNEL_HEIGHT); + int height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT; if (height > BLI_rcti_size_y(&v2d->mask)) { /* don't use totrect set, as the width stays the same diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a68e06951f7..6ec99730e09 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -96,7 +96,7 @@ static void init_preview_region(const Scene *scene, region->v2d.minzoom = 0.01f; region->v2d.maxzoom = 50; region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES); - region->v2d.scroll |= (V2D_SCROLL_RIGHT); + region->v2d.scroll |= V2D_SCROLL_RIGHT; region->v2d.keepzoom = V2D_LOCKZOOM_Y; region->v2d.keepofs = V2D_KEEPOFS_Y; region->v2d.align = V2D_ALIGN_NO_POS_Y; diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index d8c097cad37..775159fbd79 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -70,7 +70,7 @@ static SpaceLink *console_new(const ScrArea *UNUSED(area), const Scene *UNUSED(s region->regiontype = RGN_TYPE_WINDOW; /* keep in sync with info */ - region->v2d.scroll |= (V2D_SCROLL_RIGHT); + region->v2d.scroll |= V2D_SCROLL_RIGHT; region->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */ region->v2d.keepofs |= V2D_LOCKOFS_X; region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT); diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c index c9f2ec38354..cb0fdcf23ca 100644 --- a/source/blender/editors/space_image/image_edit.c +++ b/source/blender/editors/space_image/image_edit.c @@ -191,7 +191,7 @@ int ED_space_image_get_display_channel_mask(ImBuf *ibuf) result &= ~(SI_USE_ALPHA | SI_SHOW_ALPHA); } if (!zbuf) { - result &= ~(SI_SHOW_ZBUF); + result &= ~SI_SHOW_ZBUF; } if (!color) { result &= ~(SI_SHOW_R | SI_SHOW_G | SI_SHOW_B); diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 04df0f0d4f0..ddf45eb4dce 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -77,7 +77,7 @@ static SpaceLink *info_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen region->regiontype = RGN_TYPE_WINDOW; /* keep in sync with console */ - region->v2d.scroll |= (V2D_SCROLL_RIGHT); + region->v2d.scroll |= V2D_SCROLL_RIGHT; region->v2d.align |= V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_NEG_Y; /* align bottom left */ region->v2d.keepofs |= V2D_LOCKOFS_X; region->v2d.keepzoom = (V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT); diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index f060693d9f4..9ec38a2e9eb 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -120,7 +120,7 @@ static SpaceLink *nla_new(const ScrArea *area, const Scene *scene) region->v2d.minzoom = 0.01f; region->v2d.maxzoom = 50; region->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_HORIZONTAL_HANDLES); - region->v2d.scroll |= (V2D_SCROLL_RIGHT); + region->v2d.scroll |= V2D_SCROLL_RIGHT; region->v2d.keepzoom = V2D_LOCKZOOM_Y; region->v2d.keepofs = V2D_KEEPOFS_Y; region->v2d.align = V2D_ALIGN_NO_POS_Y; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 01ac3a80871..ab50158c8bc 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -849,12 +849,35 @@ static void node_shader_buts_tex_environment_ex(uiLayout *layout, bContext *C, P static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "sky_type", DEFAULT_FLAGS, "", ICON_NONE); - uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE); - uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE); - if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NEW) { + if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_PREETHAM) { + uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE); + uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE); + } + if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_HOSEK) { + uiItemR(layout, ptr, "sun_direction", DEFAULT_FLAGS, "", ICON_NONE); + uiItemR(layout, ptr, "turbidity", DEFAULT_FLAGS, NULL, ICON_NONE); uiItemR(layout, ptr, "ground_albedo", DEFAULT_FLAGS, NULL, ICON_NONE); } + if (RNA_enum_get(ptr, "sky_type") == SHD_SKY_NISHITA) { + uiItemR(layout, ptr, "sun_disc", DEFAULT_FLAGS, NULL, 0); + + if (RNA_boolean_get(ptr, "sun_disc")) { + uiItemR(layout, ptr, "sun_size", DEFAULT_FLAGS, NULL, ICON_NONE); + } + + uiLayout *col; + col = uiLayoutColumn(layout, true); + uiItemR(col, ptr, "sun_elevation", DEFAULT_FLAGS, NULL, ICON_NONE); + uiItemR(col, ptr, "sun_rotation", DEFAULT_FLAGS, NULL, ICON_NONE); + + uiItemR(layout, ptr, "altitude", DEFAULT_FLAGS, NULL, ICON_NONE); + + col = uiLayoutColumn(layout, true); + uiItemR(col, ptr, "air_density", DEFAULT_FLAGS, NULL, ICON_NONE); + uiItemR(col, ptr, "dust_density", DEFAULT_FLAGS, NULL, ICON_NONE); + uiItemR(col, ptr, "ozone_density", DEFAULT_FLAGS, NULL, ICON_NONE); + } } static void node_shader_buts_tex_gradient(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index bd8950c5085..43d844df900 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -1323,7 +1323,7 @@ static void node_draw_basis(const bContext *C, UI_BTYPE_LABEL, 0, showname, - (int)(rct->xmin + (NODE_MARGIN_X)), + (int)(rct->xmin + NODE_MARGIN_X), (int)(rct->ymax - NODE_DY), (short)(iconofs - rct->xmin - 18.0f), (short)NODE_DY, diff --git a/source/blender/editors/space_outliner/outliner_collections.c b/source/blender/editors/space_outliner/outliner_collections.c index 6ff3ccc5bb4..131491fcc40 100644 --- a/source/blender/editors/space_outliner/outliner_collections.c +++ b/source/blender/editors/space_outliner/outliner_collections.c @@ -581,7 +581,8 @@ static int collection_duplicate_exec(bContext *C, wmOperator *op) "it won't be linked to any view layer"); } - BKE_collection_duplicate(bmain, parent, collection, true, !linked); + const eDupli_ID_Flags dupli_flags = USER_DUP_OBJECT | (linked ? 0 : U.dupflag); + BKE_collection_duplicate(bmain, parent, collection, dupli_flags, 0); DEG_relations_tag_update(bmain); WM_main_add_notifier(NC_SCENE | ND_LAYER, CTX_data_scene(C)); diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index f2b64bc2a4b..3a928485711 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -495,6 +495,7 @@ TreeElement *outliner_find_parent_element(ListBase *lb, TreeElement *outliner_find_id(struct SpaceOutliner *soops, ListBase *lb, const struct ID *id); TreeElement *outliner_find_posechannel(ListBase *lb, const struct bPoseChannel *pchan); TreeElement *outliner_find_editbone(ListBase *lb, const struct EditBone *ebone); +TreeElement *outliner_search_back_te(TreeElement *te, short idcode); struct ID *outliner_search_back(TreeElement *te, short idcode); bool outliner_tree_traverse(const SpaceOutliner *soops, ListBase *tree, diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index fa8422573ab..40fb5c7be3a 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -302,28 +302,32 @@ static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_p static eOLDrawState tree_element_set_active_object(bContext *C, Scene *scene, ViewLayer *view_layer, - SpaceOutliner *soops, + SpaceOutliner *UNUSED(soops), TreeElement *te, const eOLSetState set, bool recursive) { TreeStoreElem *tselem = TREESTORE(te); TreeStoreElem *parent_tselem = NULL; + TreeElement *parent_te = NULL; Scene *sce; Base *base; Object *ob = NULL; - TreeElement *te_ob = NULL; /* if id is not object, we search back */ - if (te->idcode == ID_OB) { + if (tselem->type == 0 && te->idcode == ID_OB) { ob = (Object *)tselem->id; } else { - ob = (Object *)outliner_search_back(te, ID_OB); - - /* Don't return when activating children of the previous active object. */ - if (ob == OBACT(view_layer) && set == OL_SETSEL_NONE) { - return OL_DRAWSEL_NONE; + parent_te = outliner_search_back_te(te, ID_OB); + if (parent_te) { + parent_tselem = TREESTORE(parent_te); + ob = (Object *)parent_tselem->id; + + /* Don't return when activating children of the previous active object. */ + if (ob == OBACT(view_layer) && set == OL_SETSEL_NONE) { + return OL_DRAWSEL_NONE; + } } } if (ob == NULL) { @@ -356,11 +360,6 @@ static eOLDrawState tree_element_set_active_object(bContext *C, } } - te_ob = outliner_find_id(soops, &soops->tree, (ID *)ob); - if (te_ob != NULL && te_ob != te) { - parent_tselem = TREESTORE(te_ob); - } - if (base) { if (set == OL_SETSEL_EXTEND) { /* swap select */ diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 80a63af3f42..4b780df1cbf 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -44,6 +44,7 @@ #include "DNA_world_types.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_utildefines.h" #include "BKE_anim_data.h" @@ -689,12 +690,8 @@ static void object_deselect_cb(bContext *C, } } -static void outliner_object_delete(bContext *C, - ReportList *reports, - Scene *scene, - TreeStoreElem *tselem) +static void outliner_object_delete_fn(bContext *C, ReportList *reports, Scene *scene, Object *ob) { - Object *ob = (Object *)tselem->id; if (ob) { Main *bmain = CTX_data_main(C); if (ob->id.tag & LIB_TAG_INDIRECT) { @@ -860,7 +857,6 @@ void outliner_do_object_operation_ex(bContext *C, bool select_recurse) { TreeElement *te; - for (te = lb->first; te; te = te->next) { TreeStoreElem *tselem = TREESTORE(te); bool select_handled = false; @@ -1175,82 +1171,6 @@ static void outliner_do_data_operation( } } -static Base *outline_delete_hierarchy(bContext *C, ReportList *reports, Scene *scene, Base *base) -{ - Base *child_base, *base_next; - Object *parent; - ViewLayer *view_layer = CTX_data_view_layer(C); - - if (!base) { - return NULL; - } - - for (child_base = view_layer->object_bases.first; child_base; child_base = base_next) { - base_next = child_base->next; - for (parent = child_base->object->parent; parent && (parent != base->object); - parent = parent->parent) { - /* pass */ - } - if (parent) { - base_next = outline_delete_hierarchy(C, reports, scene, child_base); - } - } - - base_next = base->next; - - Main *bmain = CTX_data_main(C); - if (base->object->id.tag & LIB_TAG_INDIRECT) { - BKE_reportf(reports, - RPT_WARNING, - "Cannot delete indirectly linked object '%s'", - base->object->id.name + 2); - return base_next; - } - else if (BKE_library_ID_is_indirectly_used(bmain, base->object) && - ID_REAL_USERS(base->object) <= 1 && ID_EXTRA_USERS(base->object) == 0) { - BKE_reportf(reports, - RPT_WARNING, - "Cannot delete object '%s' from scene '%s', indirectly used objects need at least " - "one user", - base->object->id.name + 2, - scene->id.name + 2); - return base_next; - } - ED_object_base_free_and_unlink(CTX_data_main(C), scene, base->object); - return base_next; -} - -static void object_delete_hierarchy_cb(bContext *C, - ReportList *reports, - Scene *scene, - TreeElement *te, - TreeStoreElem *UNUSED(tsep), - TreeStoreElem *tselem, - void *UNUSED(user_data)) -{ - ViewLayer *view_layer = CTX_data_view_layer(C); - Base *base = (Base *)te->directdata; - Object *obedit = CTX_data_edit_object(C); - - if (!base) { - base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id); - } - if (base) { - /* Check also library later. */ - for (; obedit && (obedit != base->object); obedit = obedit->parent) { - /* pass */ - } - if (obedit == base->object) { - ED_object_editmode_exit(C, EM_FREEDATA); - } - - outline_delete_hierarchy(C, reports, scene, base); - } - - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); -} - static Base *outline_batch_delete_hierarchy( ReportList *reports, Main *bmain, ViewLayer *view_layer, Scene *scene, Base *base) { @@ -1303,21 +1223,16 @@ static Base *outline_batch_delete_hierarchy( return base_next; } -static void object_batch_delete_hierarchy_cb(bContext *C, +static void object_batch_delete_hierarchy_fn(bContext *C, ReportList *reports, Scene *scene, - TreeElement *te, - TreeStoreElem *UNUSED(tsep), - TreeStoreElem *tselem, - void *UNUSED(user_data)) + Object *ob) { ViewLayer *view_layer = CTX_data_view_layer(C); - Base *base = (Base *)te->directdata; Object *obedit = CTX_data_edit_object(C); - if (!base) { - base = BKE_view_layer_base_find(view_layer, (Object *)tselem->id); - } + Base *base = BKE_view_layer_base_find(view_layer, ob); + if (base) { /* Check also library later. */ for (; obedit && (obedit != base->object); obedit = obedit->parent) { @@ -1341,7 +1256,6 @@ enum { OL_OP_SELECT = 1, OL_OP_DESELECT, OL_OP_SELECT_HIERARCHY, - OL_OP_DELETE_HIERARCHY, OL_OP_REMAP, OL_OP_LOCALIZED, /* disabled, see below */ OL_OP_TOGVIS, @@ -1356,7 +1270,6 @@ static const EnumPropertyItem prop_object_op_types[] = { {OL_OP_SELECT, "SELECT", ICON_RESTRICT_SELECT_OFF, "Select", ""}, {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""}, {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""}, - {OL_OP_DELETE_HIERARCHY, "DELETE_HIERARCHY", 0, "Delete Hierarchy", ""}, {OL_OP_REMAP, "REMAP", 0, @@ -1370,7 +1283,6 @@ static const EnumPropertyItem prop_object_op_types[] = { static int outliner_object_operation_exec(bContext *C, wmOperator *op) { - struct wmMsgBus *mbus = CTX_wm_message_bus(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); @@ -1411,43 +1323,6 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op) str = "Deselect Objects"; selection_changed = true; } - else if (event == OL_OP_DELETE_HIERARCHY) { - ViewLayer *view_layer = CTX_data_view_layer(C); - const Base *basact_prev = BASACT(view_layer); - - /* Keeping old 'safe and slow' code for a bit (new one enabled on 28/01/2019). */ - if (G.debug_value == 666) { - outliner_do_object_operation_ex( - C, op->reports, scene, soops, &soops->tree, object_delete_hierarchy_cb, NULL, false); - } - else { - BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); - - outliner_do_object_operation_ex(C, - op->reports, - scene, - soops, - &soops->tree, - object_batch_delete_hierarchy_cb, - NULL, - false); - - BKE_id_multi_tagged_delete(bmain); - } - - /* XXX: See outliner_delete_exec comment below. */ - outliner_cleanup_tree(soops); - - DEG_relations_tag_update(bmain); - str = "Delete Object Hierarchy"; - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - if (basact_prev != BASACT(view_layer)) { - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); - WM_msg_publish_rna_prop(mbus, &scene->id, view_layer, LayerObjects, active); - } - selection_changed = true; - } else if (event == OL_OP_REMAP) { outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL); /* No undo push here, operator does it itself (since it's a modal one, the op_undo_depth trick @@ -1511,22 +1386,38 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot) /** \name Delete Object/Collection Operator * \{ */ -static void outliner_objects_delete( - bContext *C, Scene *scene, SpaceOutliner *soops, ReportList *reports, ListBase *lb) +typedef void (*OutlinerDeleteFunc)(bContext *C, ReportList *reports, Scene *scene, Object *ob); + +static void outliner_do_object_delete(bContext *C, + ReportList *reports, + Scene *scene, + GSet *objects_to_delete, + OutlinerDeleteFunc delete_fn) { - LISTBASE_FOREACH (TreeElement *, te, lb) { - TreeStoreElem *tselem = TREESTORE(te); + GSetIterator objects_to_delete_iter; + GSET_ITER (objects_to_delete_iter, objects_to_delete) { + Object *ob = (Object *)BLI_gsetIterator_getKey(&objects_to_delete_iter); - if (tselem->flag & TSE_SELECTED) { - if (tselem->type == 0 && te->idcode == ID_OB) { - outliner_object_delete(C, reports, scene, tselem); - } - } + delete_fn(C, reports, scene, ob); + } +} - if (TSELEM_OPEN(tselem, soops)) { - outliner_objects_delete(C, scene, soops, reports, &te->subtree); - } +static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata) +{ + GSet *objects_to_delete = (GSet *)customdata; + TreeStoreElem *tselem = TREESTORE(te); + + if (outliner_is_collection_tree_element(te)) { + return TRAVERSE_CONTINUE; } + + if (tselem->type || (tselem->id == NULL) || (GS(tselem->id->name) != ID_OB)) { + return TRAVERSE_SKIP_CHILDS; + } + + BLI_gset_add(objects_to_delete, tselem->id); + + return TRAVERSE_CONTINUE; } static int outliner_delete_exec(bContext *C, wmOperator *op) @@ -1535,12 +1426,32 @@ static int outliner_delete_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SpaceOutliner *soops = CTX_wm_space_outliner(C); struct wmMsgBus *mbus = CTX_wm_message_bus(C); - ViewLayer *view_layer = CTX_data_view_layer(C); const Base *basact_prev = BASACT(view_layer); - outliner_collection_delete(C, bmain, scene, op->reports, false); - outliner_objects_delete(C, scene, soops, op->reports, &soops->tree); + const bool delete_hierarchy = RNA_boolean_get(op->ptr, "hierarchy"); + + /* Get selected objects skipping duplicates to prevent deleting objects linked to multiple + * collections twice */ + GSet *objects_to_delete = BLI_gset_ptr_new(__func__); + outliner_tree_traverse( + soops, &soops->tree, 0, TSE_SELECTED, outliner_find_objects_to_delete, objects_to_delete); + + if (delete_hierarchy) { + BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); + + outliner_do_object_delete( + C, op->reports, scene, objects_to_delete, object_batch_delete_hierarchy_fn); + + BKE_id_multi_tagged_delete(bmain); + } + else { + outliner_do_object_delete(C, op->reports, scene, objects_to_delete, outliner_object_delete_fn); + } + + BLI_gset_free(objects_to_delete, NULL); + + outliner_collection_delete(C, bmain, scene, op->reports, delete_hierarchy); /* Tree management normally happens from draw_outliner(), but when * you're clicking too fast on Delete object from context menu in @@ -1577,6 +1488,11 @@ void OUTLINER_OT_delete(wmOperatorType *ot) /* flags */ ot->flag |= OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + PropertyRNA *prop = RNA_def_boolean( + ot->srna, "hierarchy", false, "Hierarchy", "Delete child objects and collections"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } /** \} */ diff --git a/source/blender/editors/space_outliner/outliner_utils.c b/source/blender/editors/space_outliner/outliner_utils.c index a058c30cef2..5f19d8b8757 100644 --- a/source/blender/editors/space_outliner/outliner_utils.c +++ b/source/blender/editors/space_outliner/outliner_utils.c @@ -256,7 +256,7 @@ TreeElement *outliner_find_editbone(ListBase *lb, const EditBone *ebone) return NULL; } -ID *outliner_search_back(TreeElement *te, short idcode) +TreeElement *outliner_search_back_te(TreeElement *te, short idcode) { TreeStoreElem *tselem; te = te->parent; @@ -264,13 +264,26 @@ ID *outliner_search_back(TreeElement *te, short idcode) while (te) { tselem = TREESTORE(te); if (tselem->type == 0 && te->idcode == idcode) { - return tselem->id; + return te; } te = te->parent; } return NULL; } +ID *outliner_search_back(TreeElement *te, short idcode) +{ + TreeElement *search_te; + TreeStoreElem *tselem; + + search_te = outliner_search_back_te(te, idcode); + if (search_te) { + tselem = TREESTORE(search_te); + return tselem->id; + } + return NULL; +} + /** * Iterate over all tree elements (pre-order traversal), executing \a func callback for * each tree element matching the optional filters. diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 9311cbed265..dc1fcfca8b4 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -673,6 +673,14 @@ int seq_effect_find_selected(Scene *scene, *r_selseq2 = seq2; *r_selseq3 = seq3; + /* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */ + if (BKE_sequence_effect_get_num_inputs(type) < 3) { + *r_selseq3 = NULL; + } + if (BKE_sequence_effect_get_num_inputs(type) < 2) { + *r_selseq2 = NULL; + } + return 1; } @@ -1403,14 +1411,21 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) BKE_sequence_base_shuffle(ed->seqbasep, seq, scene); } } - else if (seq->type & SEQ_TYPE_EFFECT) { + } + + /* Recalculate bounds of effect strips. */ + for (seq = ed->seqbasep->first; seq; seq = seq->next) { + if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && (seq->seq1->flag & SELECT)) { + BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); BKE_sequence_calc(scene, seq); } else if (seq->seq2 && (seq->seq2->flag & SELECT)) { + BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); BKE_sequence_calc(scene, seq); } else if (seq->seq3 && (seq->seq3->flag & SELECT)) { + BKE_sequencer_offset_animdata(scene, seq, (snap_frame - seq->startdisp)); BKE_sequence_calc(scene, seq); } } @@ -2218,6 +2233,11 @@ static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op) Sequence *seq1, *seq2, *seq3, *last_seq = BKE_sequencer_active_get(scene); const char *error_msg; + if (BKE_sequence_effect_get_num_inputs(last_seq->type) != 0) { + BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs"); + return OPERATOR_CANCELLED; + } + if (!seq_effect_find_selected( scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg)) { BKE_report(op->reports, RPT_ERROR, error_msg); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 2686edd58a5..85b70354ab3 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -409,32 +409,15 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) /* Select left, right or overlapping the current frame. */ if (side_of_frame) { /* Use different logic for this. */ - float x; if (extend == false) { ED_sequencer_deselect_all(scene); } - /* 10px margin around current frame to select under the current frame with mouse. */ - float margin = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask) * 10; - x = UI_view2d_region_to_view_x(v2d, mval[0]); - if (x >= CFRA - margin && x <= CFRA + margin) { - x = CFRA; - } + const float x = UI_view2d_region_to_view_x(v2d, mval[0]); SEQP_BEGIN (ed, seq) { - bool test = false; - /* FIXME(campbell): this functionality is only in the sequencer, - * either we should support this for all timeline views or remove it. */ - if ((x == CFRA) && (seq->startdisp <= CFRA) && (seq->enddisp >= CFRA)) { - /* Select overlapping the current frame. */ - test = true; - } - else if ((x < CFRA && seq->enddisp <= CFRA) || (x > CFRA && seq->startdisp >= CFRA)) { + if (((x < CFRA) && (seq->enddisp <= CFRA)) || ((x >= CFRA) && (seq->startdisp >= CFRA))) { /* Select left or right. */ - test = true; - } - - if (test) { seq->flag |= SELECT; recurs_sel_seq(seq); } @@ -1023,7 +1006,6 @@ static int sequencer_select_side_of_frame_exec(bContext *C, wmOperator *op) void SEQUENCER_OT_select_side_of_frame(wmOperatorType *ot) { static const EnumPropertyItem sequencer_select_left_right_types[] = { - {0, "OVERLAP", 0, "Overlap", "Select overlapping the current frame"}, {-1, "LEFT", 0, "Left", "Select to the left of the current frame"}, {1, "RIGHT", 0, "Right", "Select to the right of the current frame"}, {0, NULL, 0, NULL, NULL}, diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 06d1a033a0d..506969443fd 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -55,6 +55,10 @@ #include "view3d_intern.h" /* own include */ +/* -------------------------------------------------------------------- */ +/** \name Modal Key-map + * \{ */ + /* NOTE: these defines are saved in keymap files, * do not change values but just add new ones */ enum { @@ -138,6 +142,12 @@ void fly_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_fly"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Fly Structs + * \{ */ + typedef struct FlyInfo { /* context stuff */ RegionView3D *rv3d; @@ -205,6 +215,12 @@ typedef struct FlyInfo { } FlyInfo; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Fly Drawing + * \{ */ + /* prototypes */ #ifdef WITH_INPUT_NDOF static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm); @@ -278,6 +294,12 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(regio immUnbindProgram(); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Fly Logic + * \{ */ + /* FlyInfo->state */ enum { FLY_RUNNING = 0, @@ -1034,6 +1056,12 @@ static void flyApply_ndof(bContext *C, FlyInfo *fly, bool is_confirm) } #endif /* WITH_INPUT_NDOF */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Fly Operator + * \{ */ + static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -1128,3 +1156,5 @@ void VIEW3D_OT_fly(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_BLOCKING; } + +/** \} */ diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 829d793333e..f2e42cd1725 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -209,7 +209,7 @@ static void uiTemplatePaintModeSelection(uiLayout *layout, struct bContext *C) PointerRNA meshptr; RNA_pointer_create(ob->data, &RNA_Mesh, ob->data, &meshptr); - if (ob->mode & (OB_MODE_TEXTURE_PAINT)) { + if (ob->mode & OB_MODE_TEXTURE_PAINT) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } else { diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 1bdb8268c23..9e235d72f26 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -3007,7 +3007,7 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO continue; } - if (metaelem_id != (hitresult & 0xFFFF0000 & ~(MBALLSEL_ANY))) { + if (metaelem_id != (hitresult & 0xFFFF0000 & ~MBALLSEL_ANY)) { continue; } diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 7aefd173953..50fa573423a 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -65,6 +65,10 @@ /* ensure the target position is one we can reach, see: T45771 */ #define USE_PIXELSIZE_NATIVE_SUPPORT +/* -------------------------------------------------------------------- */ +/** \name Modal Key-map + * \{ */ + /* NOTE: these defines are saved in keymap files, * do not change values but just add new ones */ enum { @@ -173,6 +177,12 @@ void walk_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk"); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Walk Structs + * \{ */ + typedef struct WalkTeleport { eWalkTeleportState state; float duration; /* from user preferences */ @@ -283,6 +293,12 @@ typedef struct WalkInfo { } WalkInfo; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Walk Drawing + * \{ */ + /* prototypes */ #ifdef WITH_INPUT_NDOF static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm); @@ -340,6 +356,12 @@ static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *region, voi immUnbindProgram(); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Internal Walk Logic + * \{ */ + static void walk_navigation_mode_set(WalkInfo *walk, eWalkMethod mode) { if (mode == WALK_MODE_FREE) { @@ -1343,7 +1365,12 @@ static void walkApply_ndof(bContext *C, WalkInfo *walk, bool is_confirm) } #endif /* WITH_INPUT_NDOF */ -/****** walk operator ******/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Walk Operator + * \{ */ + static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -1438,3 +1465,5 @@ void VIEW3D_OT_walk(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_BLOCKING; } + +/** \} */ diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 838c1880881..97b14d5ddd2 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -79,6 +79,27 @@ static void projection_matrix_calc(const TransInfo *t, float r_pmtx[3][3]) } /* ************************** CONSTRAINTS ************************* */ +#define CONSTRAIN_EPSILON 0.0001f + +static void constraint_plane_calc(TransInfo *t, float r_plane[4]) +{ + const float *constraint_vector[2]; + int n = 0; + for (int i = 0; i < 3; i++) { + if (t->con.mode & (CON_AXIS0 << i)) { + constraint_vector[n++] = t->spacemtx[i]; + if (n == 2) { + break; + } + } + } + BLI_assert(n == 2); + + cross_v3_v3v3(r_plane, constraint_vector[0], constraint_vector[1]); + normalize_v3(r_plane); + r_plane[3] = -dot_v3v3(r_plane, t->center_global); +} + static void constraintValuesFinal(TransInfo *t, float vec[3]) { int mode = t->con.mode; @@ -297,32 +318,79 @@ static void axisProjection(const TransInfo *t, } /** - * Return true if the 2x axis are both aligned when projected into the view. - * In this case, we can't usefully project the cursor onto the plane. + * Snap to the intersection between the edge direction and the constraint plane. */ -static bool isPlaneProjectionViewAligned(const TransInfo *t) +static void constraint_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3]) { - const float eps = 0.001f; - const float *constraint_vector[2]; - int n = 0; - for (int i = 0; i < 3; i++) { - if (t->con.mode & (CON_AXIS0 << i)) { - constraint_vector[n++] = t->spacemtx[i]; - if (n == 2) { - break; - } - } + float lambda; + const float *edge_snap_point = t->tsnap.snapPoint; + const float *edge_dir = t->tsnap.snapNormal; + bool is_aligned = fabsf(dot_v3v3(edge_dir, plane)) < CONSTRAIN_EPSILON; + if (!is_aligned && isect_ray_plane_v3(edge_snap_point, edge_dir, plane, &lambda, false)) { + madd_v3_v3v3fl(r_out, edge_snap_point, edge_dir, lambda); + sub_v3_v3(r_out, t->tsnap.snapTarget); } - BLI_assert(n == 2); +} + +/** + * Snap to the nearest point between the snap point and the line that + * intersects the face plane with the constraint plane. + */ +static void constraint_plane_to_face(const TransInfo *t, const float plane[4], float r_out[3]) +{ + float face_plane[4], isect_orig[3], isect_dir[3]; + const float *face_snap_point = t->tsnap.snapPoint; + const float *face_normal = t->tsnap.snapNormal; + plane_from_point_normal_v3(face_plane, face_snap_point, face_normal); + bool is_aligned = fabsf(dot_v3v3(plane, face_plane)) > (1.0f - CONSTRAIN_EPSILON); + if (!is_aligned && isect_plane_plane_v3(plane, face_plane, isect_orig, isect_dir)) { + closest_to_ray_v3(r_out, face_snap_point, isect_orig, isect_dir); + sub_v3_v3(r_out, t->tsnap.snapTarget); + } +} - float view_to_plane[3], plane_normal[3]; +/** + * Snap to the nearest point on the axis to the edge/line element. + */ +static void constraint_axis_to_edge(const TransInfo *t, const float axis[3], float r_out[3]) +{ + float lambda; + const float *edge_snap_point = t->tsnap.snapPoint; + const float *edge_dir = t->tsnap.snapNormal; + bool is_aligned = fabsf(dot_v3v3(axis, edge_dir)) > (1.0f - CONSTRAIN_EPSILON); + if (!is_aligned && + isect_ray_ray_v3(t->tsnap.snapTarget, axis, edge_snap_point, edge_dir, &lambda, NULL)) { + mul_v3_v3fl(r_out, axis, lambda); + } +} - getViewVector(t, t->center_global, view_to_plane); +/** + * Snap to the intersection of the axis and the plane defined by the face. + */ +static void constraint_axis_to_face(const TransInfo *t, const float axis[3], float r_out[3]) +{ + float lambda; + float face_plane[4]; + const float *face_snap_point = t->tsnap.snapPoint; + const float *face_normal = t->tsnap.snapNormal; + plane_from_point_normal_v3(face_plane, face_snap_point, face_normal); + bool is_aligned = fabsf(dot_v3v3(face_normal, face_plane)) < CONSTRAIN_EPSILON; + if (!is_aligned && isect_ray_plane_v3(t->tsnap.snapTarget, axis, face_plane, &lambda, false)) { + mul_v3_v3fl(r_out, axis, lambda); + } +} - cross_v3_v3v3(plane_normal, constraint_vector[0], constraint_vector[1]); - normalize_v3(plane_normal); +/** + * Return true if the 2x axis are both aligned when projected into the view. + * In this case, we can't usefully project the cursor onto the plane. + */ +static bool isPlaneProjectionViewAligned(const TransInfo *t, float plane[4]) +{ + const float eps = 0.001f; + float view_to_plane[3]; + getViewVector(t, t->center_global, view_to_plane); - float factor = dot_v3v3(plane_normal, view_to_plane); + float factor = dot_v3v3(plane, view_to_plane); return fabsf(factor) < eps; } @@ -361,14 +429,31 @@ static void applyAxisConstraintVec( copy_v3_v3(out, in); if (!td && t->con.mode & CON_APPLY) { mul_m3_v3(t->con.pmtx, out); + bool is_snap_to_edge = false, is_snap_to_face = false; + if (activeSnap(t)) { + is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0; + is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE) != 0; + } - // With snap, a projection is alright, no need to correct for view alignment - if (!validSnap(t)) { + /* With snap points, a projection is alright, no adjustments needed. */ + if (!validSnap(t) || is_snap_to_edge || is_snap_to_face) { const int dims = getConstraintSpaceDimension(t); if (dims == 2) { if (!is_zero_v3(out)) { - if (!isPlaneProjectionViewAligned(t)) { - planeProjection(t, in, out); + float plane[4]; + constraint_plane_calc(t, plane); + + if (is_snap_to_edge) { + constraint_plane_to_edge(t, plane, out); + } + else if (is_snap_to_face) { + constraint_plane_to_face(t, plane, out); + } + else { + /* View alignment correction. */ + if (!isPlaneProjectionViewAligned(t, plane)) { + planeProjection(t, in, out); + } } } } @@ -384,7 +469,17 @@ static void applyAxisConstraintVec( else if (t->con.mode & CON_AXIS2) { copy_v3_v3(c, t->spacemtx[2]); } - axisProjection(t, c, in, out); + + if (is_snap_to_edge) { + constraint_axis_to_edge(t, c, out); + } + else if (is_snap_to_face) { + constraint_axis_to_face(t, c, out); + } + else { + /* View alignment correction. */ + axisProjection(t, c, in, out); + } } } postConstraintChecks(t, out); |