diff options
Diffstat (limited to 'source/blender/editors')
172 files changed, 3948 insertions, 2266 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index a441dce5656..845ad72d7aa 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -574,8 +574,7 @@ static void *acf_scene_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (scene->adt) return GET_ACF_FLAG_PTR(scene->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -719,9 +718,8 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ob->adt) return GET_ACF_FLAG_PTR(ob->adt->flag, type); - else - return NULL; - + return NULL; + default: /* unsupported */ return NULL; } @@ -1053,9 +1051,8 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *ty if (adt) { return GET_ACF_FLAG_PTR(adt->flag, type); } - else - return NULL; - + return NULL; + case ACHANNEL_SETTING_EXPAND: /* expanded */ return GET_ACF_FLAG_PTR(act->flag, type); @@ -1213,9 +1210,8 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ma->adt) return GET_ACF_FLAG_PTR(ma->adt->flag, type); - else - return NULL; - + return NULL; + default: /* unsupported */ return NULL; } @@ -1290,8 +1286,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (la->adt) return GET_ACF_FLAG_PTR(la->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1374,8 +1369,7 @@ static void *acf_dstex_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (tex->adt) return GET_ACF_FLAG_PTR(tex->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1451,8 +1445,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ca->adt) return GET_ACF_FLAG_PTR(ca->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1538,8 +1531,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (cu->adt) return GET_ACF_FLAG_PTR(cu->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1615,8 +1607,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (key->adt) return GET_ACF_FLAG_PTR(key->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1692,8 +1683,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (wo->adt) return GET_ACF_FLAG_PTR(wo->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1769,8 +1759,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (part->adt) return GET_ACF_FLAG_PTR(part->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1846,8 +1835,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (mb->adt) return GET_ACF_FLAG_PTR(mb->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -1923,8 +1911,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (arm->adt) return GET_ACF_FLAG_PTR(arm->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2011,8 +1998,7 @@ static void *acf_dsntree_setting_ptr(bAnimListElem *ale, int setting, short *typ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (ntree->adt) return GET_ACF_FLAG_PTR(ntree->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2088,8 +2074,7 @@ static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, int setting, short case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (linestyle->adt) return GET_ACF_FLAG_PTR(linestyle->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2165,8 +2150,7 @@ static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, int setting, short *type case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (me->adt) return GET_ACF_FLAG_PTR(me->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2242,8 +2226,7 @@ static void *acf_dslat_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (lt->adt) return GET_ACF_FLAG_PTR(lt->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2319,8 +2302,7 @@ static void *acf_dsspk_setting_ptr(bAnimListElem *ale, int setting, short *type) case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */ if (spk->adt) return GET_ACF_FLAG_PTR(spk->adt->flag, type); - else - return NULL; + return NULL; default: /* unsupported */ return NULL; @@ -2921,9 +2903,8 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting return ((*val) & flag) == 0; else return ((*val) & flag) != 0; + break; } - break; - case sizeof(short): /* short pointer for setting */ { short *val = (short *)ptr; @@ -2932,9 +2913,8 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting return ((*val) & flag) == 0; else return ((*val) & flag) != 0; + break; } - break; - case sizeof(char): /* char pointer for setting */ { char *val = (char *)ptr; @@ -2943,8 +2923,8 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting return ((*val) & flag) == 0; else return ((*val) & flag) != 0; + break; } - break; } } } @@ -2994,22 +2974,20 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, { int *val = (int *)ptr; ACF_SETTING_SET(*val, flag, mode); + break; } - break; - case sizeof(short): /* short pointer for setting */ { short *val = (short *)ptr; ACF_SETTING_SET(*val, flag, mode); + break; } - break; - case sizeof(char): /* char pointer for setting */ { char *val = (char *)ptr; ACF_SETTING_SET(*val, flag, mode); + break; } - break; } } } @@ -3156,14 +3134,14 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float { SpaceAction *saction = (SpaceAction *)ac->sl; draw_sliders = (saction->flag & SACTION_SLIDERS); + break; } - break; case SPACE_IPO: { SpaceIpo *sipo = (SpaceIpo *)ac->sl; draw_sliders = (sipo->flag & SIPO_SLIDERS); + break; } - break; } } @@ -3443,6 +3421,7 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush, otherwise all would open/close at once */ default: uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL); + break; } } } @@ -3546,14 +3525,14 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale { SpaceAction *saction = (SpaceAction *)ac->sl; draw_sliders = (saction->flag & SACTION_SLIDERS); + break; } - break; case SPACE_IPO: { SpaceIpo *sipo = (SpaceIpo *)ac->sl; draw_sliders = (sipo->flag & SIPO_SLIDERS); + break; } - break; } } diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 481430f37e4..e04c51b33d8 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -94,23 +94,22 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f bActionGroup *agrp = (bActionGroup *)ale->data; ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE); + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)ale->data; ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE); + break; } - break; case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)ale->data; ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE); + break; } - break; - case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: @@ -131,8 +130,8 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f if (ale->adt) { ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE); } + break; } - break; } } @@ -143,21 +142,20 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f { bActionGroup *agrp = (bActionGroup *)channel_data; agrp->flag |= AGRP_ACTIVE; + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)channel_data; fcu->flag |= FCURVE_ACTIVE; + break; } - break; case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)channel_data; nlt->flag |= NLATRACK_ACTIVE; + break; } - break; - case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: @@ -177,8 +175,8 @@ void ANIM_set_active_channel(bAnimContext *ac, void *data, short datatype, int f if (ale && ale->adt) { ale->adt->flag |= ADT_UI_ACTIVE; } + break; } - break; } } @@ -256,9 +254,8 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s { if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED)) sel = ACHANNEL_SETFLAG_CLEAR; + break; } - break; - case ANIMTYPE_GPLAYER: if (ale->flag & GP_LAYER_SELECT) sel = ACHANNEL_SETFLAG_CLEAR; @@ -283,55 +280,54 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s if (scene->adt) { ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED); } + break; } - break; case ANIMTYPE_OBJECT: + { #if 0 /* for now, do not take object selection into account, since it gets too annoying */ - { - Base *base = (Base *)ale->data; - Object *ob = base->object; - - ACHANNEL_SET_FLAG(base, sel, SELECT); - ACHANNEL_SET_FLAG(ob, sel, SELECT); - - if (ob->adt) { - ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED); - } + Base *base = (Base *)ale->data; + Object *ob = base->object; + + ACHANNEL_SET_FLAG(base, sel, SELECT); + ACHANNEL_SET_FLAG(ob, sel, SELECT); + + if (ob->adt) { + ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED); } #endif break; + } case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED); agrp->flag &= ~AGRP_ACTIVE; + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)ale->data; ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED); fcu->flag &= ~FCURVE_ACTIVE; + break; } - break; case ANIMTYPE_SHAPEKEY: { KeyBlock *kb = (KeyBlock *)ale->data; ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL); + break; } - break; case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)ale->data; ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED); nlt->flag &= ~NLATRACK_ACTIVE; + break; } - break; - case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: @@ -354,24 +350,22 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED); ale->adt->flag &= ~ADT_UI_ACTIVE; } + break; } - break; - case ANIMTYPE_GPLAYER: { bGPDlayer *gpl = (bGPDlayer *)ale->data; ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT); + break; } - break; - case ANIMTYPE_MASKLAYER: { MaskLayer *masklay = (MaskLayer *)ale->data; ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT); + break; } - break; } } @@ -801,23 +795,22 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr is_sel = SEL_AGRP(agrp); is_untouchable = (agrp->flag & AGRP_TEMP) != 0; + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)channel; is_sel = SEL_FCU(fcu); + break; } - break; case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)channel; is_sel = SEL_NLT(nlt); + break; } - break; - default: printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %d\n", type); return; @@ -1435,9 +1428,8 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* try to free F-Curve */ ANIM_fcurve_delete_from_animdata(&ac, adt, fcu); + break; } - break; - case ANIMTYPE_GPLAYER: { /* Grease Pencil layer */ @@ -1447,9 +1439,8 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* try to delete the layer's data and the layer itself */ free_gpencil_frames(gpl); BLI_freelinkN(&gpd->layers, gpl); + break; } - break; - case ANIMTYPE_MASKLAYER: { /* Mask layer */ @@ -1458,8 +1449,8 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* try to delete the layer's data and the layer itself */ BKE_mask_layer_remove(mask, masklay); + break; } - break; } } @@ -2131,8 +2122,8 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec /* always clear active flag after doing this */ agrp->flag &= ~AGRP_ACTIVE; + break; } - break; case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)ale->data; @@ -2141,8 +2132,8 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec * currently adds complications when doing other stuff */ ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED); + break; } - break; } } @@ -2367,8 +2358,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; case ANIMTYPE_OBJECT: { bDopeSheet *ads = (bDopeSheet *)ac->data; @@ -2406,9 +2397,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in adt->flag |= ADT_UI_ACTIVE; notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; - case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: @@ -2445,9 +2435,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; - case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)ale->data; @@ -2482,8 +2471,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP); notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)ale->data; @@ -2504,8 +2493,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE); notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; case ANIMTYPE_SHAPEKEY: { KeyBlock *kb = (KeyBlock *)ale->data; @@ -2522,8 +2511,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; case ANIMTYPE_GPDATABLOCK: { bGPdata *gpd = (bGPdata *)ale->data; @@ -2534,8 +2523,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in gpd->flag ^= GP_DATA_EXPAND; notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + break; } - break; case ANIMTYPE_GPLAYER: { bGPDlayer *gpl = (bGPDlayer *)ale->data; @@ -2552,8 +2541,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in } notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + break; } - break; case ANIMTYPE_MASKDATABLOCK: { Mask *mask = (Mask *)ale->data; @@ -2564,8 +2553,8 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in mask->flag ^= MASK_ANIMF_EXPAND; notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + break; } - break; case ANIMTYPE_MASKLAYER: { MaskLayer *masklay = (MaskLayer *)ale->data; @@ -2582,11 +2571,12 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in } notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + break; } - break; default: if (G.debug & G_DEBUG) printf("Error: Invalid channel type in mouse_anim_channels()\n"); + break; } /* free channels */ diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 2e580a57a01..9e8800fd91e 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -126,17 +126,15 @@ void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short t if (hours) sprintf(str, "%s%02d:%02d:%02d", neg, hours, minutes, seconds); else sprintf(str, "%s%02d:%02d", neg, minutes, seconds); } + break; } - break; - case USER_TIMECODE_SMPTE_MSF: { /* reduced SMPTE format that always shows minutes, seconds, frames. Hours only shown as needed. */ if (hours) sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames); else sprintf(str, "%s%02d:%02d:%02d", neg, minutes, seconds, frames); + break; } - break; - case USER_TIMECODE_MILLISECONDS: { /* reduced SMPTE. Instead of frames, milliseconds are shown */ @@ -145,25 +143,23 @@ void ANIM_timecode_string_from_frame(char *str, Scene *scene, int power, short t if (hours) sprintf(str, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, cfra); else sprintf(str, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, cfra); + break; } - break; - case USER_TIMECODE_SECONDS_ONLY: { /* only show the original seconds display */ /* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ if (power <= 0) sprintf(str, "%.*f", 1 - power, raw_seconds); else sprintf(str, "%d", (int)floor(raw_seconds + GLA_PIXEL_OFS)); + break; } - break; - case USER_TIMECODE_SMPTE_FULL: default: { /* full SMPTE format */ sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames); + break; } - break; } } else { diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 41aeb92e182..91003674524 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -301,22 +301,20 @@ short ANIM_animdata_context_getdata(bAnimContext *ac) { SpaceAction *saction = (SpaceAction *)sl; ok = actedit_get_context(ac, saction); + break; } - break; - case SPACE_IPO: { SpaceIpo *sipo = (SpaceIpo *)sl; ok = graphedit_get_context(ac, sipo); + break; } - break; - case SPACE_NLA: { SpaceNla *snla = (SpaceNla *)sl; ok = nlaedit_get_context(ac, snla); + break; } - break; } } @@ -543,9 +541,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne */ ale->key_data = NULL; ale->datatype = ALE_ALL; + break; } - break; - case ANIMTYPE_SCENE: { Scene *sce = (Scene *)data; @@ -556,8 +553,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_SCE; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_OBJECT: { Base *base = (Base *)data; @@ -569,8 +566,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_OB; ale->adt = BKE_animdata_from_id(&ob->id); + break; } - break; case ANIMTYPE_FILLACTD: { bAction *act = (bAction *)data; @@ -579,8 +576,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = act; ale->datatype = ALE_ACT; + break; } - break; case ANIMTYPE_FILLDRIVERS: { AnimData *adt = (AnimData *)data; @@ -590,9 +587,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne // XXX... drivers don't show summary for now ale->key_data = NULL; ale->datatype = ALE_NONE; + break; } - break; - case ANIMTYPE_DSMAT: { Material *ma = (Material *)data; @@ -604,8 +600,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSLAM: { Lamp *la = (Lamp *)data; @@ -617,8 +613,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSCAM: { Camera *ca = (Camera *)data; @@ -630,8 +626,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSCUR: { Curve *cu = (Curve *)data; @@ -643,8 +639,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSARM: { bArmature *arm = (bArmature *)data; @@ -656,8 +652,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSMESH: { Mesh *me = (Mesh *)data; @@ -669,8 +665,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSLAT: { Lattice *lt = (Lattice *)data; @@ -682,8 +678,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSSPK: { Speaker *spk = (Speaker *)data; @@ -695,8 +691,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSSKEY: { Key *key = (Key *)data; @@ -708,8 +704,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSWOR: { World *wo = (World *)data; @@ -721,8 +717,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSNTREE: { bNodeTree *ntree = (bNodeTree *)data; @@ -734,8 +730,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSLINESTYLE: { FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data; @@ -747,8 +743,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSPART: { ParticleSettings *part = (ParticleSettings *)ale->data; @@ -760,8 +756,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; case ANIMTYPE_DSTEX: { Tex *tex = (Tex *)data; @@ -773,9 +769,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_ACT; ale->adt = BKE_animdata_from_id(data); + break; } - break; - case ANIMTYPE_GROUP: { bActionGroup *agrp = (bActionGroup *)data; @@ -784,8 +779,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = NULL; ale->datatype = ALE_GROUP; + break; } - break; case ANIMTYPE_FCURVE: { FCurve *fcu = (FCurve *)data; @@ -794,9 +789,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = fcu; ale->datatype = ALE_FCURVE; + break; } - break; - case ANIMTYPE_SHAPEKEY: { KeyBlock *kb = (KeyBlock *)data; @@ -824,9 +818,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne } ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE; } + break; } - break; - case ANIMTYPE_GPLAYER: { bGPDlayer *gpl = (bGPDlayer *)data; @@ -835,9 +828,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = NULL; ale->datatype = ALE_GPFRAME; + break; } - break; - case ANIMTYPE_MASKLAYER: { MaskLayer *masklay = (MaskLayer *)data; @@ -846,9 +838,8 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = NULL; ale->datatype = ALE_MASKLAY; + break; } - break; - case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)data; @@ -857,15 +848,15 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->key_data = &nlt->strips; ale->datatype = ALE_NLASTRIP; + break; } - break; case ANIMTYPE_NLAACTION: { /* nothing to include for now... nothing editable from NLA-perspective here */ ale->key_data = NULL; ale->datatype = ALE_NONE; + break; } - break; } } @@ -1654,20 +1645,20 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, { Material *ma = (Material *)owner_id; mtex = (MTex **)(&ma->mtex); + break; } - break; case ID_LA: { Lamp *la = (Lamp *)owner_id; mtex = (MTex **)(&la->mtex); + break; } - break; case ID_WO: { World *wo = (World *)owner_id; mtex = (MTex **)(&wo->mtex); + break; } - break; default: { /* invalid/unsupported option */ @@ -1812,8 +1803,8 @@ static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) { afm->items += animdata_filter_ds_texture(afm->ac, &afm->tmp_data, afm->ads, tex, owner_id, afm->filter_mode); } + break; } - break; /* TODO: images? */ } @@ -1920,8 +1911,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSCAM; expanded = FILTER_CAM_OBJD(ca); + break; } - break; case OB_LAMP: /* ---------- Lamp ----------- */ { Lamp *la = (Lamp *)ob->data; @@ -1931,8 +1922,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSLAM; expanded = FILTER_LAM_OBJD(la); + break; } - break; case OB_CURVE: /* ------- Curve ---------- */ case OB_SURF: /* ------- Nurbs Surface ---------- */ case OB_FONT: /* ------- Text Curve ---------- */ @@ -1944,8 +1935,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSCUR; expanded = FILTER_CUR_OBJD(cu); + break; } - break; case OB_MBALL: /* ------- MetaBall ---------- */ { MetaBall *mb = (MetaBall *)ob->data; @@ -1955,8 +1946,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSMBALL; expanded = FILTER_MBALL_OBJD(mb); + break; } - break; case OB_ARMATURE: /* ------- Armature ---------- */ { bArmature *arm = (bArmature *)ob->data; @@ -1966,8 +1957,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSARM; expanded = FILTER_ARM_OBJD(arm); + break; } - break; case OB_MESH: /* ------- Mesh ---------- */ { Mesh *me = (Mesh *)ob->data; @@ -1977,8 +1968,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSMESH; expanded = FILTER_MESH_OBJD(me); + break; } - break; case OB_LATTICE: /* ---- Lattice ---- */ { Lattice *lt = (Lattice *)ob->data; @@ -1988,16 +1979,16 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b type = ANIMTYPE_DSLAT; expanded = FILTER_LATTICE_OBJD(lt); + break; } - break; case OB_SPEAKER: /* ---------- Speaker ----------- */ { Speaker *spk = (Speaker *)ob->data; type = ANIMTYPE_DSSPK; expanded = FILTER_SPK_OBJD(spk); + break; } - break; } /* add object data animation channels */ @@ -2020,8 +2011,8 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b /* textures */ if (!(ads->filterflag & ADS_FILTER_NOTEX)) tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, &la->id, filter_mode); + break; } - break; } } END_ANIMFILTER_SUBCHANNELS; @@ -2603,58 +2594,52 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo /* the check for the DopeSheet summary is included here since the summary works here too */ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact); + break; } - break; - case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */ { /* the check for the DopeSheet summary is included here since the summary works here too */ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items = animdata_filter_shapekey(ac, anim_data, data, filter_mode); + break; } - break; - case ANIMCONT_GPENCIL: { if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items = animdata_filter_gpencil(anim_data, data, filter_mode); + break; } - break; - case ANIMCONT_MASK: { if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items = animdata_filter_mask(anim_data, data, filter_mode); + break; } - break; - case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ { /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode); + break; } - break; - case ANIMCONT_FCURVES: /* Graph Editor -> F-Curves/Animation Editing */ case ANIMCONT_DRIVERS: /* Graph Editor -> Drivers Editing */ case ANIMCONT_NLA: /* NLA Editor */ { /* all of these editors use the basic DopeSheet data for filtering options, but don't have all the same features */ items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode); + break; } - break; - case ANIMCONT_CHANNEL: /* animation channel */ { bDopeSheet *ads = ac->ads; /* based on the channel type, filter relevant data for this */ items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode); + break; } - break; } - + /* remove any 'weedy' entries */ items = animdata_filter_remove_invalid(anim_data); diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index 54c7f7ea30f..c571da1ba74 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -54,14 +54,14 @@ void ANIM_OT_keyframe_insert_menu(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); void ANIM_OT_keyframe_clear_v3d(struct wmOperatorType *ot); -/* Keyframe managment operators for UI buttons (RMB menu). */ +/* Keyframe management operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot); void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot); /* .......... */ -/* KeyingSet managment operators for UI buttons (RMB menu) */ +/* KeyingSet management operators for UI buttons (RMB menu) */ void ANIM_OT_keyingset_button_add(struct wmOperatorType *ot); void ANIM_OT_keyingset_button_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index f3edb61f487..3c8576be312 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -401,7 +401,7 @@ static void draw_marker(View2D *v2d, TimeMarker *marker, int cfra, int flag) glDisable(GL_BLEND); /* and the marker name too, shifted slightly to the top-right */ - if (marker->name && marker->name[0]) { + if (marker->name[0]) { float x, y; /* minimal y coordinate which wouldn't be occluded by scroll */ @@ -553,7 +553,7 @@ static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent * /* ************************** add markers *************************** */ /* add TimeMarker at curent frame */ -static int ed_marker_add(bContext *C, wmOperator *UNUSED(op)) +static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op)) { ListBase *markers = ED_context_get_markers(C); TimeMarker *marker; @@ -593,7 +593,7 @@ static void MARKER_OT_add(wmOperatorType *ot) ot->idname = "MARKER_OT_add"; /* api callbacks */ - ot->exec = ed_marker_add; + ot->exec = ed_marker_add_exec; ot->invoke = ed_markers_opwrap_invoke; ot->poll = ED_operator_animview_active; @@ -763,7 +763,6 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even MarkerMove *mm = op->customdata; View2D *v2d = UI_view2d_fromcontext(C); TimeMarker *marker, *selmarker = NULL; - float dx, fac; char str[256]; switch (event->type) { @@ -791,6 +790,9 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even } break; case MOUSEMOVE: + { + float dx, fac; + if (hasNumInput(&mm->num)) break; @@ -863,6 +865,8 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even ED_area_headerprint(CTX_wm_area(C), str); } + break; + } } if (event->val == KM_PRESS) { diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 8c49bee3058..df93da8b7c1 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -449,8 +449,8 @@ static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *pro /* free old one */ MEM_freeN(basepath); } + break; } - break; } /* fix RNA pointer, as we've now changed the ID root by changing the paths */ diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index adea3bcdc31..5ceca478b47 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -242,8 +242,8 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s else uiDefBut(block, LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } + break; } - break; } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index d9d2180e184..4e6cc53f962 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -601,30 +601,27 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, { if (sel) glColor4f(0.33f, 0.75f, 0.93f, alpha); else glColor4f(0.70f, 0.86f, 0.91f, alpha); + break; } - break; - case BEZT_KEYTYPE_EXTREME: /* redish frames for now */ { if (sel) glColor4f(0.95f, 0.5f, 0.5f, alpha); else glColor4f(0.91f, 0.70f, 0.80f, alpha); + break; } - break; - case BEZT_KEYTYPE_JITTER: /* greenish frames for now? */ { if (sel) glColor4f(0.38f, 0.75f, 0.26f, alpha); else glColor4f(0.58f, 0.90f, 0.46f, alpha); + break; } - break; - case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames for now */ default: { if (sel) UI_ThemeColorShadeAlpha(TH_STRIP_SELECT, 50, -255 * (1.0f - alpha)); else glColor4f(0.91f, 0.91f, 0.91f, alpha); + break; } - break; } glCallList(displist2); diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index 2cb2f6683ef..cfa5f9f032c 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -628,9 +628,8 @@ static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short f PropertyRNA *prop; RNA_id_pointer_create(aci->id, &id_ptr); - RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop); - if (prop) { + if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) { const char *identifier = RNA_property_identifier(prop); int len_id = strlen(identifier); int len_path = strlen(fcu->rna_path); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 1638e4ce629..63acc5a943c 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1962,10 +1962,11 @@ short id_frame_has_keyframe(ID *id, float frame, short filter) return object_frame_has_keyframe((Object *)id, frame, filter); break; - case ID_SCE: /* scene */ +#if 0 // XXX TODO... for now, just use 'normal' behavior - // break; - + case ID_SCE: /* scene */ + break; +#endif default: /* 'normal type' */ { AnimData *adt = BKE_animdata_from_id(id); @@ -1973,8 +1974,8 @@ short id_frame_has_keyframe(ID *id, float frame, short filter) /* only check keyframes in active action */ if (adt) return action_frame_has_keyframe(adt->action, frame, filter); + break; } - break; } diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 07825f59c2f..ebe8dccc356 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -1004,8 +1004,8 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe // XXX: only object transforms? DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); + break; } - break; } /* send notifiers for updates (this doesn't require context to work!) */ diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 13c1f2d5b2b..d480d41f5d6 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -84,39 +84,25 @@ EditBone *ED_armature_edit_bone_add(bArmature *arm, const char *name) return bone; } -/* v3d and rv3d are allowed to be NULL */ -void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) +void add_primitive_bone(Object *obedit_arm, bool view_aligned) { - Object *obedit = scene->obedit; // XXX get from context - bArmature *arm = obedit->data; - float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3]; - EditBone *bone; - - /* Get inverse point for head and orientation for tail */ - invert_m4_m4(obedit->imat, obedit->obmat); - mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d)); + bArmature *arm = obedit_arm->data; + EditBone *bone; - if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) - copy_m3_m4(obmat, rv3d->viewmat); - else unit_m3(obmat); - - copy_m3_m4(viewmat, obedit->obmat); - mul_m3_m3m3(totmat, obmat, viewmat); - invert_m3_m3(imat, totmat); - - ED_armature_deselect_all(obedit, 0); + ED_armature_deselect_all(obedit_arm, 0); /* Create a bone */ bone = ED_armature_edit_bone_add(arm, "Bone"); arm->act_edbone = bone; - copy_v3_v3(bone->head, curs); - - if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) - add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1 + zero_v3(bone->head); + zero_v3(bone->tail); + + if (view_aligned) + bone->tail[1] = 1.0f; else - add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z + bone->tail[2] = 1.0f; } diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 12602c10955..90c1a439a19 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -78,11 +78,10 @@ void ED_armature_apply_transform(Object *ob, float mat[4][4]) /* Do the rotations */ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - float delta[3], tmat[3][3]; + float tmat[3][3]; /* find the current bone's roll matrix */ - sub_v3_v3v3(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, tmat); + ED_armature_ebone_to_mat3(ebone, tmat); /* transform the roll matrix */ mul_m3_m3m3(tmat, mat3, tmat); @@ -282,15 +281,14 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) mul_m3_v3(imat, vec); } else if (type == CALC_ROLL_ACTIVE) { - float mat[3][3], nor[3]; + float mat[3][3]; ebone = (EditBone *)arm->act_edbone; if (ebone == NULL) { BKE_report(op->reports, RPT_ERROR, "No active bone set"); return OPERATOR_CANCELLED; } - sub_v3_v3v3(nor, ebone->tail, ebone->head); - vec_roll_to_mat3(nor, ebone->roll, mat); + ED_armature_ebone_to_mat3(ebone, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index bfebc68ea46..e58d8fd2380 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -63,6 +63,8 @@ void ARMATURE_OT_parent_clear(struct wmOperatorType *ot); void ARMATURE_OT_select_all(struct wmOperatorType *ot); void ARMATURE_OT_select_inverse(struct wmOperatorType *ot); +void ARMATURE_OT_select_more(struct wmOperatorType *ot); +void ARMATURE_OT_select_less(struct wmOperatorType *ot); void ARMATURE_OT_select_hierarchy(struct wmOperatorType *ot); void ARMATURE_OT_select_linked(struct wmOperatorType *ot); void ARMATURE_OT_select_similar(struct wmOperatorType *ot); diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 568178802bd..0090522d1e1 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -59,6 +59,8 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_select_all); WM_operatortype_append(ARMATURE_OT_select_inverse); + WM_operatortype_append(ARMATURE_OT_select_more); + WM_operatortype_append(ARMATURE_OT_select_less); WM_operatortype_append(ARMATURE_OT_select_hierarchy); WM_operatortype_append(ARMATURE_OT_select_linked); WM_operatortype_append(ARMATURE_OT_select_similar); @@ -258,6 +260,9 @@ void ED_keymap_armature(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "direction", BONE_SELECT_CHILD); RNA_boolean_set(kmi->ptr, "extend", TRUE); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_select_linked", LKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index d5dbe80538f..79d75c9fcda 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -170,7 +170,7 @@ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChann } /* join armature exec is exported for use in object->join objects operator... */ -int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) +int join_armature_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -180,6 +180,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) bPoseChannel *pchan, *pchann; EditBone *curbone; float mat[4][4], oimat[4][4]; + bool ok = false; /* Ensure we're not in editmode and that the active object is an armature*/ if (!ob || ob->type != OB_ARMATURE) @@ -187,6 +188,21 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) if (!arm || arm->edbo) return OPERATOR_CANCELLED; + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) + { + if (base->object == ob) { + ok = true; + break; + } + } + CTX_DATA_END; + + /* that way the active object is always selected */ + if (ok == false) { + BKE_report(op->reports, RPT_WARNING, "Active object is not a selected armature"); + return OPERATOR_CANCELLED; + } + /* Get editbones of active armature to add editbones to */ ED_armature_to_edit(ob); @@ -226,21 +242,18 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) float difmat[4][4]; float imat[4][4]; float temp[3][3]; - float delta[3]; /* Get the premat */ - sub_v3_v3v3(delta, curbone->tail, curbone->head); - vec_roll_to_mat3(delta, curbone->roll, temp); + ED_armature_ebone_to_mat3(curbone, temp); - unit_m4(premat); /* Mat4MulMat34 only sets 3x3 part */ + unit_m4(premat); /* mul_m4_m3m4 only sets 3x3 part */ mul_m4_m3m4(premat, temp, mat); mul_m4_v3(mat, curbone->head); mul_m4_v3(mat, curbone->tail); /* Get the postmat */ - sub_v3_v3v3(delta, curbone->tail, curbone->head); - vec_roll_to_mat3(delta, curbone->roll, temp); + ED_armature_ebone_to_mat3(curbone, temp); copy_m4_m3(postmat, temp); /* Find the roll */ diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index bbdc0df41a7..f2b3ce206f1 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -244,7 +244,7 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) ot->description = "Select bones related to selected ones by parent/child relationships"; /* api callbacks */ - ot->exec = NULL; + /* leave 'exec' unset */ ot->invoke = armature_select_linked_invoke; ot->poll = armature_select_linked_poll; @@ -434,7 +434,7 @@ void ED_armature_deselect_all_visible(Object *obedit) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { /* first and foremost, bone must be visible and selected */ - if (EBONE_SELECTABLE(arm, ebone)) { + if (EBONE_VISIBLE(arm, ebone)) { ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -597,38 +597,48 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) int action = RNA_enum_get(op->ptr, "action"); if (action == SEL_TOGGLE) { - action = SEL_SELECT; /* Determine if there are any selected bones * And therefore whether we are selecting or deselecting */ - if (CTX_DATA_COUNT(C, selected_bones) > 0) - action = SEL_DESELECT; + action = SEL_SELECT; + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) + { + if (ebone->flag & (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)) { + action = SEL_DESELECT; + break; + } + } + CTX_DATA_END; } /* Set the flags */ CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { - switch (action) { - case SEL_SELECT: + switch (action) { + case SEL_SELECT: + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (ebone->parent) + if (ebone->parent) { ebone->parent->flag |= (BONE_TIPSEL); - break; - case SEL_DESELECT: - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - break; - case SEL_INVERT: - if (ebone->flag & BONE_SELECTED) { - ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } - else { + } + break; + case SEL_DESELECT: + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + break; + case SEL_INVERT: + if (ebone->flag & BONE_SELECTED) { + ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + if ((ebone->flag & BONE_UNSELECTABLE) == 0) { ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - if (ebone->parent) + if (ebone->parent) { ebone->parent->flag |= (BONE_TIPSEL); + } } - break; - } + } + break; } } CTX_DATA_END; @@ -655,6 +665,145 @@ void ARMATURE_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/**************** Select more/less **************/ + +#define EBONE_PREV_FLAG_GET(ebone) ((void)0, (GET_INT_FROM_POINTER(ebone->temp))) +#define EBONE_PREV_FLAG_SET(ebone, val) (ebone->temp = SET_INT_IN_POINTER(val)) + +static void armature_select_more(bArmature *arm, EditBone *ebone) +{ + if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != 0) { + if (EBONE_SELECTABLE(arm, ebone)) { + ED_armature_ebone_select_set(ebone, true); + } + } + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + /* to parent */ + if ((EBONE_PREV_FLAG_GET(ebone) & BONE_ROOTSEL) != 0) { + if (EBONE_SELECTABLE(arm, ebone->parent)) { + ED_armature_ebone_selectflag_enable(ebone->parent, (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)); + } + } + + /* from parent (difference from select less) */ + if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_TIPSEL) != 0) { + if (EBONE_SELECTABLE(arm, ebone)) { + ED_armature_ebone_selectflag_enable(ebone, (BONE_SELECTED | BONE_ROOTSEL)); + } + } + } +} + +static void armature_select_less(bArmature *UNUSED(arm), EditBone *ebone) +{ + if ((EBONE_PREV_FLAG_GET(ebone) & (BONE_ROOTSEL | BONE_TIPSEL)) != (BONE_ROOTSEL | BONE_TIPSEL)) { + ED_armature_ebone_select_set(ebone, false); + } + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + /* to parent */ + if ((EBONE_PREV_FLAG_GET(ebone) & BONE_SELECTED) == 0) { + ED_armature_ebone_selectflag_disable(ebone->parent, (BONE_SELECTED | BONE_TIPSEL)); + } + + /* from parent (difference from select more) */ + if ((EBONE_PREV_FLAG_GET(ebone->parent) & BONE_SELECTED) == 0) { + ED_armature_ebone_selectflag_disable(ebone, (BONE_SELECTED | BONE_ROOTSEL)); + } + } +} + +static void armature_select_more_less(Object* ob, bool more) +{ + bArmature* arm = (bArmature *)ob->data; + EditBone* ebone; + + /* XXX, eventually we shouldn't need this - campbell */ + ED_armature_sync_selection(arm->edbo); + + /* count bones & store selection state */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + EBONE_PREV_FLAG_SET(ebone, ED_armature_ebone_selectflag_get(ebone)); + } + + /* do selection */ + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + if (more) { + armature_select_more(arm, ebone); + } + else { + armature_select_less(arm, ebone); + } + } + } + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + if (more == false) { + if (ebone->flag & BONE_SELECTED) { + ED_armature_ebone_select_set(ebone, true); + } + } + } + ebone->temp = NULL; + } + + ED_armature_sync_selection(arm->edbo); +} + +#undef EBONE_PREV_FLAG_GET +#undef EBONE_PREV_FLAG_SET + +static int armature_de_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + armature_select_more_less(obedit, true); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "ARMATURE_OT_select_more"; + ot->description = "Select those bones connected to the initial selection"; + + /* api callbacks */ + ot->exec = armature_de_select_more_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int armature_de_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + armature_select_more_less(obedit, false); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "ARMATURE_OT_select_less"; + ot->description = "Deselect those bones at the boundary of each selection region"; + + /* api callbacks */ + ot->exec = armature_de_select_less_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + enum { SIMEDBONE_LENGTH = 1, SIMEDBONE_DIRECTION, @@ -672,16 +821,6 @@ static EnumPropertyItem prop_similar_types[] = { {0, NULL, 0, NULL, NULL} }; -/* could be used in more places */ -static void ED_armature_edit_bone_select(EditBone *ebone) -{ - BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); - ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - if ((ebone->flag & BONE_CONNECTED) && (ebone->parent != NULL)) { - ebone->parent->flag |= BONE_TIPSEL; - } -} static void select_similar_length(bArmature *arm, EditBone *ebone_act, const float thresh) { @@ -696,7 +835,7 @@ static void select_similar_length(bArmature *arm, EditBone *ebone_act, const flo if ((ebone->length >= len_min) && (ebone->length <= len_max)) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -714,7 +853,7 @@ static void select_similar_direction(bArmature *arm, EditBone *ebone_act, const sub_v3_v3v3(dir, ebone->head, ebone->tail); if (angle_v3v3(dir_act, dir) / (float)M_PI < thresh) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -727,7 +866,7 @@ static void select_similar_layer(bArmature *arm, EditBone *ebone_act) for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (EBONE_SELECTABLE(arm, ebone)) { if (ebone->layer & ebone_act->layer) { - ED_armature_edit_bone_select(ebone); + ED_armature_ebone_select_set(ebone, true); } } } @@ -750,8 +889,8 @@ static void select_similar_prefix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char prefix_other[MAX_VGROUP_NAME]; BKE_deform_split_prefix(ebone->name, prefix_other, body_tmp); - if (!strcmp(prefix_act, prefix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(prefix_act, prefix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } @@ -774,8 +913,8 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) if (EBONE_SELECTABLE(arm, ebone)) { char suffix_other[MAX_VGROUP_NAME]; BKE_deform_split_suffix(ebone->name, body_tmp, suffix_other); - if (!strcmp(suffix_act, suffix_other)) { - ED_armature_edit_bone_select(ebone); + if (STREQ(suffix_act, suffix_other)) { + ED_armature_ebone_select_set(ebone, true); } } } diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 0a9cff3dc90..22bd22c8561 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -362,7 +362,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); if (dm->foreachMappedVert) { - dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts); + dm->foreachMappedVert(dm, add_vgroups__mapFunc, (void *)verts, DM_FOREACH_NOP); vertsfilled = 1; } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 4120be08b46..4991ef63cf5 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -156,6 +156,25 @@ bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebon return false; } +void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]) +{ + float delta[3]; + + /* Find the current bone matrix */ + sub_v3_v3v3(delta, ebone->tail, ebone->head); + vec_roll_to_mat3(delta, ebone->roll, mat); +} + +void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]) +{ + float m3[3][3]; + + ED_armature_ebone_to_mat3(ebone, m3); + + copy_m4_m3(mat, m3); + copy_v3_v3(mat[3], ebone->head); +} + /* *************************************************************** */ /* Mirroring */ @@ -337,18 +356,9 @@ EditBone *make_boneList(ListBase *edbo, ListBase *bones, EditBone *parent, Bone } else { /* if the bone is not selected, but connected to its parent - * copy the parents tip selection state */ + * always use the parents tip selection state */ if (eBone->parent && (eBone->flag & BONE_CONNECTED)) { - /* selecting with the mouse gives this behavior */ - if (eBone->parent->flag & BONE_TIPSEL) { - eBone->flag |= BONE_ROOTSEL; - } - else { - eBone->flag &= ~BONE_ROOTSEL; - } - - /* probably not selected but just in case */ - eBone->flag &= ~BONE_TIPSEL; + eBone->flag &= ~BONE_ROOTSEL; } } @@ -398,7 +408,6 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist) float postmat[3][3]; float difmat[3][3]; float imat[3][3]; - float delta[3]; for (curBone = bonelist->first; curBone; curBone = curBone->next) { /* sets local matrix and arm_mat (restpos) */ @@ -411,8 +420,7 @@ static void fix_bonelist_roll(ListBase *bonelist, ListBase *editbonelist) if (ebone) { /* Get the ebone premat */ - sub_v3_v3v3(delta, ebone->tail, ebone->head); - vec_roll_to_mat3(delta, ebone->roll, premat); + ED_armature_ebone_to_mat3(ebone, premat); /* Get the bone postmat */ copy_m3_m4(postmat, curBone->arm_mat); @@ -512,11 +520,9 @@ void ED_armature_from_edit(Object *obedit) { float M_parentRest[3][3]; float iM_parentRest[3][3]; - float delta[3]; /* Get the parent's matrix (rotation only) */ - sub_v3_v3v3(delta, eBone->parent->tail, eBone->parent->head); - vec_roll_to_mat3(delta, eBone->parent->roll, M_parentRest); + ED_armature_ebone_to_mat3(eBone->parent, M_parentRest); /* Invert the parent matrix */ invert_m3_m3(iM_parentRest, M_parentRest); @@ -588,6 +594,60 @@ void ED_armature_to_edit(Object *ob) /* *************************************************************** */ /* Undo for Armature EditMode*/ +/* free's bones and their properties */ + +static void ED_armature_ebone_listbase_free(ListBase *lb) +{ + EditBone *ebone, *ebone_next; + + for (ebone = lb->first; ebone; ebone = ebone_next) { + ebone_next = ebone->next; + + if (ebone->prop) { + IDP_FreeProperty(ebone->prop); + MEM_freeN(ebone->prop); + } + + MEM_freeN(ebone); + } + + lb->first = NULL; + lb->last = NULL; +} + +static void ED_armature_ebone_listbase_copy(ListBase *lb_dst, ListBase *lb_src) +{ + EditBone *ebone_src; + EditBone *ebone_dst; + + BLI_assert(lb_dst->first == NULL); + + for (ebone_src = lb_src->first; ebone_src; ebone_src = ebone_src->next) { + ebone_dst = MEM_dupallocN(ebone_src); + if (ebone_dst->prop) { + ebone_dst->prop = IDP_CopyProperty(ebone_dst->prop); + } + ebone_src->temp = ebone_dst; + BLI_addtail(lb_dst, ebone_dst); + } + + /* set pointers */ + for (ebone_dst = lb_dst->first; ebone_dst; ebone_dst = ebone_dst->next) { + if (ebone_dst->parent) { + ebone_dst->parent = ebone_dst->parent->temp; + } + } +} + +static void ED_armature_ebone_listbase_temp_clear(ListBase *lb) +{ + EditBone *ebone; + /* be sure they don't hang ever */ + for (ebone = lb->first; ebone; ebone = ebone->next) { + ebone->temp = NULL; + } +} + typedef struct UndoArmature { EditBone *act_edbone; ListBase lb; @@ -597,60 +657,40 @@ static void undoBones_to_editBones(void *uarmv, void *armv, void *UNUSED(data)) { UndoArmature *uarm = uarmv; bArmature *arm = armv; - EditBone *ebo, *newebo; + EditBone *ebone; - BLI_freelistN(arm->edbo); - - /* copy */ - for (ebo = uarm->lb.first; ebo; ebo = ebo->next) { - newebo = MEM_dupallocN(ebo); - ebo->temp = newebo; - BLI_addtail(arm->edbo, newebo); - } + ED_armature_ebone_listbase_free(arm->edbo); + ED_armature_ebone_listbase_copy(arm->edbo, &uarm->lb); /* active bone */ if (uarm->act_edbone) { - ebo = uarm->act_edbone; - arm->act_edbone = ebo->temp; + ebone = uarm->act_edbone; + arm->act_edbone = ebone->temp; } - else + else { arm->act_edbone = NULL; - - /* set pointers */ - for (newebo = arm->edbo->first; newebo; newebo = newebo->next) { - if (newebo->parent) newebo->parent = newebo->parent->temp; - } - /* be sure they don't hang ever */ - for (newebo = arm->edbo->first; newebo; newebo = newebo->next) { - newebo->temp = NULL; } + + ED_armature_ebone_listbase_temp_clear(arm->edbo); } static void *editBones_to_undoBones(void *armv, void *UNUSED(obdata)) { bArmature *arm = armv; UndoArmature *uarm; - EditBone *ebo, *newebo; + EditBone *ebone; uarm = MEM_callocN(sizeof(UndoArmature), "listbase undo"); - /* copy */ - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - newebo = MEM_dupallocN(ebo); - ebo->temp = newebo; - BLI_addtail(&uarm->lb, newebo); - } + ED_armature_ebone_listbase_copy(&uarm->lb, arm->edbo); /* active bone */ if (arm->act_edbone) { - ebo = arm->act_edbone; - uarm->act_edbone = ebo->temp; + ebone = arm->act_edbone; + uarm->act_edbone = ebone->temp; } - /* set pointers */ - for (newebo = uarm->lb.first; newebo; newebo = newebo->next) { - if (newebo->parent) newebo->parent = newebo->parent->temp; - } + ED_armature_ebone_listbase_temp_clear(&uarm->lb); return uarm; } @@ -659,7 +699,8 @@ static void free_undoBones(void *uarmv) { UndoArmature *uarm = uarmv; - BLI_freelistN(&uarm->lb); + ED_armature_ebone_listbase_free(&uarm->lb); + MEM_freeN(uarm); } @@ -678,3 +719,62 @@ void undo_push_armature(bContext *C, const char *name) // XXX solve getdata() undo_editmode_push(C, name, get_armature_edit, free_undoBones, undoBones_to_editBones, editBones_to_undoBones, NULL); } + +/* *************************************************************** */ +/* Low level selection functions which hide connected-parent + * flag behavior which gets tricky to handle in selection operators. + * (no flushing in ED_armature_ebone_select.*, that should be explicit) */ + +int ED_armature_ebone_selectflag_get(const EditBone *ebone) +{ + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + return ((ebone->flag & (BONE_SELECTED | BONE_TIPSEL)) | + ((ebone->parent->flag & BONE_TIPSEL) ? BONE_ROOTSEL : 0)); + } + else { + return (ebone->flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)); + } +} + +void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag) +{ + flag = flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + + if (ebone->parent && (ebone->flag & BONE_CONNECTED)) { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->parent->flag &= ~BONE_TIPSEL; + + ebone->flag |= flag; + ebone->parent->flag |= (flag & BONE_ROOTSEL) ? BONE_TIPSEL : 0; + } + else { + ebone->flag &= ~(BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); + ebone->flag |= flag; + } +} + +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag | flag); +} + +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag) +{ + BLI_assert((flag & (BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL)) != 0); + ED_armature_ebone_selectflag_set(ebone, ebone->flag & ~flag); +} + +/* could be used in more places */ +void ED_armature_ebone_select_set(EditBone *ebone, bool select) +{ + int flag; + if (select) { + BLI_assert((ebone->flag & BONE_UNSELECTABLE) == 0); + flag = (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); + } + else { + flag = 0; + } + ED_armature_ebone_selectflag_set(ebone, flag); +} diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index c599e978e58..9449b5a49bf 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -271,7 +271,7 @@ void POSE_OT_select_linked(wmOperatorType *ot) ot->description = "Select bones related to selected ones by parent/child relationships"; /* api callbacks */ - ot->exec = NULL; + /* leave 'exec' unset */ ot->invoke = pose_select_connected_invoke; ot->poll = pose_select_linked_poll; diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 0ff0e0d498c..ec1662c7fa6 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -238,9 +238,8 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val) while (iters-- > 0) { (*val) = (-((sVal * w2) + (eVal * w1)) + ((*val) * 6.0f) ) / 5.0f; } + break; } - break; - case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */ { /* perform a weighted average here, favoring the middle pose @@ -252,16 +251,15 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val) while (iters-- > 0) { (*val) = ( ((sVal * w2) + (eVal * w1)) + ((*val) * 5.0f) ) / 6.0f; } + break; } - break; - case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */ { /* perform simple linear interpolation - coefficient for start must come from pso->percentage... */ /* TODO: make this use some kind of spline interpolation instead? */ (*val) = ((sVal * w2) + (eVal * w1)); + break; } - break; } } @@ -327,8 +325,8 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl) float tval = RNA_property_float_get(&ptr, prop); pose_slide_apply_val(pso, fcu, &tval); RNA_property_float_set(&ptr, prop, tval); + break; } - break; case PROP_BOOLEAN: case PROP_ENUM: case PROP_INT: @@ -336,8 +334,8 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl) float tval = (float)RNA_property_int_get(&ptr, prop); pose_slide_apply_val(pso, fcu, &tval); RNA_property_int_set(&ptr, prop, (int)tval); + break; } - break; default: /* cannot handle */ //printf("Cannot Pose Slide non-numerical property\n"); @@ -672,9 +670,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) /* apply... */ pose_slide_apply(C, pso); + break; } - break; - default: /* unhandled event (maybe it was some view manip? */ /* allow to pass through */ return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH; diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c index a5e51ccf32a..014a64170db 100644 --- a/source/blender/editors/armature/pose_utils.c +++ b/source/blender/editors/armature/pose_utils.c @@ -239,7 +239,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa * - only do this if keyframes should have been added * - do not calculate unless there are paths already to update... */ - if (C && (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { + if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) { //ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear ED_pose_recalculate_paths(scene, ob); } diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 0521297d049..d197697e60b 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -88,7 +88,9 @@ void CURVE_OT_shade_flat(struct wmOperatorType *ot); void CURVE_OT_tilt_clear(struct wmOperatorType *ot); void CURVE_OT_smooth(struct wmOperatorType *ot); +void CURVE_OT_smooth_weight(struct wmOperatorType *ot); void CURVE_OT_smooth_radius(struct wmOperatorType *ot); +void CURVE_OT_smooth_tilt(struct wmOperatorType *ot); void CURVE_OT_primitive_bezier_curve_add(struct wmOperatorType *ot); void CURVE_OT_primitive_bezier_circle_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 5b525a089b3..2452a5d1a4b 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -112,7 +112,9 @@ void ED_operatortypes_curve(void) WM_operatortype_append(SURFACE_OT_primitive_nurbs_surface_torus_add); WM_operatortype_append(CURVE_OT_smooth); + WM_operatortype_append(CURVE_OT_smooth_weight); WM_operatortype_append(CURVE_OT_smooth_radius); + WM_operatortype_append(CURVE_OT_smooth_tilt); WM_operatortype_append(CURVE_OT_de_select_first); WM_operatortype_append(CURVE_OT_de_select_last); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 3327d4a07e9..660f8098a38 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2260,29 +2260,33 @@ void CURVE_OT_smooth(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/**************** smooth curve radius operator *************/ +/* -------------------------------------------------------------------- */ +/* Smooth radius/weight/tilt + * + * TODO: make smoothing distance based + * TODO: support cyclic curves + */ -/* TODO, make smoothing distance based */ -static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) +static void curve_smooth_value(ListBase *editnurb, + const int bezt_offsetof, const int bp_offset) { - Object *obedit = CTX_data_edit_object(C); - ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - + /* use for smoothing */ int last_sel; int start_sel, end_sel; /* selection indices, inclusive */ float start_rad, end_rad, fac, range; - + for (nu = editnurb->first; nu; nu = nu->next) { if (nu->bezt) { - +#define BEZT_VALUE(bezt) (*((float *)((char *)bezt + bezt_offsetof))) + for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { /* loop over selection segments of a curve, smooth each */ - + /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ start_sel = -1; for (bezt = &nu->bezt[last_sel], a = last_sel; a < nu->pntsu; a++, bezt++) { @@ -2299,57 +2303,60 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) } end_sel = a; } - + if (start_sel == -1) { last_sel = nu->pntsu; /* next... */ } else { last_sel = end_sel; /* before we modify it */ - + /* now blend between start and end sel */ - start_rad = end_rad = -1.0; - + start_rad = end_rad = FLT_MAX; + if (start_sel == end_sel) { /* simple, only 1 point selected */ - if (start_sel > 0) start_rad = nu->bezt[start_sel - 1].radius; - if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bezt[start_sel + 1].radius; - - if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bezt[start_sel].radius = (start_rad + end_rad) / 2.0f; - else if (start_rad >= 0.0f) nu->bezt[start_sel].radius = start_rad; - else if (end_rad >= 0.0f) nu->bezt[start_sel].radius = end_rad; + if (start_sel > 0) start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); + if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BEZT_VALUE(&nu->bezt[start_sel + 1]); + + if (start_rad != FLT_MAX && end_rad >= FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = (start_rad + end_rad) / 2.0f; + else if (start_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = start_rad; + else if (end_rad != FLT_MAX) BEZT_VALUE(&nu->bezt[start_sel]) = end_rad; } else { /* if endpoints selected, then use them */ if (start_sel == 0) { - start_rad = nu->bezt[start_sel].radius; + start_rad = BEZT_VALUE(&nu->bezt[start_sel]); start_sel++; /* we don't want to edit the selected endpoint */ } else { - start_rad = nu->bezt[start_sel - 1].radius; + start_rad = BEZT_VALUE(&nu->bezt[start_sel - 1]); } if (end_sel == nu->pntsu - 1) { - end_rad = nu->bezt[end_sel].radius; + end_rad = BEZT_VALUE(&nu->bezt[end_sel]); end_sel--; /* we don't want to edit the selected endpoint */ } else { - end_rad = nu->bezt[end_sel + 1].radius; + end_rad = BEZT_VALUE(&nu->bezt[end_sel + 1]); } - + /* Now Blend between the points */ range = (float)(end_sel - start_sel) + 2.0f; for (bezt = &nu->bezt[start_sel], a = start_sel; a <= end_sel; a++, bezt++) { fac = (float)(1 + a - start_sel) / range; - bezt->radius = start_rad * (1.0f - fac) + end_rad * fac; + BEZT_VALUE(bezt) = start_rad * (1.0f - fac) + end_rad * fac; } } } } +#undef BEZT_VALUE } else if (nu->bp) { +#define BP_VALUE(bp) (*((float *)((char *)bp + bp_offset))) + /* Same as above, keep these the same! */ for (last_sel = 0; last_sel < nu->pntsu; last_sel++) { /* loop over selection segments of a curve, smooth each */ - + /* Start BezTriple code, this is duplicated below for points, make sure these functions stay in sync */ start_sel = -1; for (bp = &nu->bp[last_sel], a = last_sel; a < nu->pntsu; a++, bp++) { @@ -2366,53 +2373,90 @@ static int smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) } end_sel = a; } - + if (start_sel == -1) { last_sel = nu->pntsu; /* next... */ } else { last_sel = end_sel; /* before we modify it */ - + /* now blend between start and end sel */ - start_rad = end_rad = -1.0; - + start_rad = end_rad = FLT_MAX; + if (start_sel == end_sel) { /* simple, only 1 point selected */ - if (start_sel > 0) start_rad = nu->bp[start_sel - 1].radius; - if (end_sel != -1 && end_sel < nu->pntsu) end_rad = nu->bp[start_sel + 1].radius; - - if (start_rad >= 0.0f && end_rad >= 0.0f) nu->bp[start_sel].radius = (start_rad + end_rad) / 2; - else if (start_rad >= 0.0f) nu->bp[start_sel].radius = start_rad; - else if (end_rad >= 0.0f) nu->bp[start_sel].radius = end_rad; + if (start_sel > 0) start_rad = BP_VALUE(&nu->bp[start_sel - 1]); + if (end_sel != -1 && end_sel < nu->pntsu) end_rad = BP_VALUE(&nu->bp[start_sel + 1]); + + if (start_rad != FLT_MAX && end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = (start_rad + end_rad) / 2; + else if (start_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = start_rad; + else if (end_rad != FLT_MAX) BP_VALUE(&nu->bp[start_sel]) = end_rad; } else { /* if endpoints selected, then use them */ if (start_sel == 0) { - start_rad = nu->bp[start_sel].radius; + start_rad = BP_VALUE(&nu->bp[start_sel]); start_sel++; /* we don't want to edit the selected endpoint */ } else { - start_rad = nu->bp[start_sel - 1].radius; + start_rad = BP_VALUE(&nu->bp[start_sel - 1]); } if (end_sel == nu->pntsu - 1) { - end_rad = nu->bp[end_sel].radius; + end_rad = BP_VALUE(&nu->bp[end_sel]); end_sel--; /* we don't want to edit the selected endpoint */ } else { - end_rad = nu->bp[end_sel + 1].radius; + end_rad = BP_VALUE(&nu->bp[end_sel + 1]); } - + /* Now Blend between the points */ range = (float)(end_sel - start_sel) + 2.0f; for (bp = &nu->bp[start_sel], a = start_sel; a <= end_sel; a++, bp++) { fac = (float)(1 + a - start_sel) / range; - bp->radius = start_rad * (1.0f - fac) + end_rad * fac; + BP_VALUE(bp) = start_rad * (1.0f - fac) + end_rad * fac; } } } } +#undef BP_VALUE } } +} + +static int curve_smooth_weight_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, weight), offsetof(BPoint, weight)); + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_smooth_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Smooth Curve Weight"; + ot->description = "Interpolate weight of selected points"; + ot->idname = "CURVE_OT_smooth_weight"; + + /* api clastbacks */ + ot->exec = curve_smooth_weight_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int curve_smooth_radius_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, radius), offsetof(BPoint, radius)); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); DAG_id_tag_update(obedit->data, 0); @@ -2424,17 +2468,45 @@ void CURVE_OT_smooth_radius(wmOperatorType *ot) { /* identifiers */ ot->name = "Smooth Curve Radius"; - ot->description = "Flatten radii of selected points"; + ot->description = "Interpolate radii of selected points"; ot->idname = "CURVE_OT_smooth_radius"; /* api clastbacks */ - ot->exec = smooth_radius_exec; + ot->exec = curve_smooth_radius_exec; ot->poll = ED_operator_editsurfcurve; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int curve_smooth_tilt_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + ListBase *editnurb = object_editcurve_get(obedit); + + curve_smooth_value(editnurb, offsetof(BezTriple, alfa), offsetof(BPoint, alfa)); + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + DAG_id_tag_update(obedit->data, 0); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_smooth_tilt(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Smooth Curve Tilt"; + ot->description = "Interpolate tilt of selected points"; + ot->idname = "CURVE_OT_smooth_tilt"; + + /* api clastbacks */ + ot->exec = curve_smooth_tilt_exec; + ot->poll = ED_operator_editsurfcurve; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /***************** selection utility *************************/ /* next == 1 -> select next */ @@ -2842,7 +2914,7 @@ static void subdividenurb(Object *obedit, int number_cuts) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; Nurb *nu; - BezTriple *prevbezt, *bezt, *beztnew, *beztn; + BezTriple *bezt, *beztnew, *beztn; BPoint *bp, *prevbp, *bpnew, *bpn; float vec[15]; int a, b, sel, amount, *usel, *vsel, i; @@ -2853,25 +2925,25 @@ static void subdividenurb(Object *obedit, int number_cuts) for (nu = editnurb->nurbs.first; nu; nu = nu->next) { amount = 0; if (nu->type == CU_BEZIER) { + BezTriple *nextbezt; + /* * Insert a point into a 2D Bezier curve. * Endpoints are preserved. Otherwise, all selected and inserted points are * newly created. Old points are discarded. */ /* count */ - if (nu->flagu & CU_NURB_CYCLIC) { - a = nu->pntsu; - bezt = nu->bezt; - prevbezt = bezt + (a - 1); - } - else { - a = nu->pntsu - 1; - prevbezt = nu->bezt; - bezt = prevbezt + 1; - } + a = nu->pntsu; + bezt = nu->bezt; while (a--) { - if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) amount += number_cuts; - prevbezt = bezt; + nextbezt = BKE_nurb_bezt_get_next(nu, bezt); + if (nextbezt == NULL) { + break; + } + + if (BEZSELECTED_HIDDENHANDLES(cu, bezt) && BEZSELECTED_HIDDENHANDLES(cu, nextbezt)) { + amount += number_cuts; + } bezt++; } @@ -2879,35 +2951,32 @@ static void subdividenurb(Object *obedit, int number_cuts) /* insert */ beztnew = (BezTriple *)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb"); beztn = beztnew; - if (nu->flagu & CU_NURB_CYCLIC) { - a = nu->pntsu; - bezt = nu->bezt; - prevbezt = bezt + (a - 1); - } - else { - a = nu->pntsu - 1; - prevbezt = nu->bezt; - bezt = prevbezt + 1; - } + a = nu->pntsu; + bezt = nu->bezt; while (a--) { - memcpy(beztn, prevbezt, sizeof(BezTriple)); - keyIndex_updateBezt(editnurb, prevbezt, beztn, 1); + memcpy(beztn, bezt, sizeof(BezTriple)); + keyIndex_updateBezt(editnurb, bezt, beztn, 1); beztn++; - if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + nextbezt = BKE_nurb_bezt_get_next(nu, bezt); + if (nextbezt == NULL) { + break; + } + + if (BEZSELECTED_HIDDENHANDLES(cu, bezt) && BEZSELECTED_HIDDENHANDLES(cu, nextbezt)) { float prevvec[3][3]; - memcpy(prevvec, prevbezt->vec, sizeof(float) * 9); + memcpy(prevvec, bezt->vec, sizeof(float) * 9); for (i = 0; i < number_cuts; i++) { factor = 1.0f / (number_cuts + 1 - i); - memcpy(beztn, bezt, sizeof(BezTriple)); + memcpy(beztn, nextbezt, sizeof(BezTriple)); /* midpoint subdividing */ interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor); - interp_v3_v3v3(vec + 3, prevvec[2], bezt->vec[0], factor); - interp_v3_v3v3(vec + 6, bezt->vec[0], bezt->vec[1], factor); + interp_v3_v3v3(vec + 3, prevvec[2], nextbezt->vec[0], factor); + interp_v3_v3v3(vec + 6, nextbezt->vec[0], nextbezt->vec[1], factor); interp_v3_v3v3(vec + 9, vec, vec + 3, factor); interp_v3_v3v3(vec + 12, vec + 3, vec + 6, factor); @@ -2920,24 +2989,18 @@ static void subdividenurb(Object *obedit, int number_cuts) copy_v3_v3(beztn->vec[2], vec + 12); /* handle of next bezt */ if (a == 0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) { copy_v3_v3(beztnew->vec[0], vec + 6); } - else { copy_v3_v3(bezt->vec[0], vec + 6); } + else { copy_v3_v3(nextbezt->vec[0], vec + 6); } - beztn->radius = (prevbezt->radius + bezt->radius) / 2; - beztn->weight = (prevbezt->weight + bezt->weight) / 2; + beztn->radius = (bezt->radius + nextbezt->radius) / 2; + beztn->weight = (bezt->weight + nextbezt->weight) / 2; memcpy(prevvec, beztn->vec, sizeof(float) * 9); beztn++; } } - prevbezt = bezt; bezt++; } - /* last point */ - if ((nu->flagu & CU_NURB_CYCLIC) == 0) { - memcpy(beztn, prevbezt, sizeof(BezTriple)); - keyIndex_updateBezt(editnurb, prevbezt, beztn, 1); - } MEM_freeN(nu->bezt); nu->bezt = beztnew; @@ -2947,6 +3010,8 @@ static void subdividenurb(Object *obedit, int number_cuts) } } /* End of 'if (nu->type == CU_BEZIER)' */ else if (nu->pntsv == 1) { + BPoint *nextbp; + /* * All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves * are handled together with the regular NURB plane division, as it @@ -2954,19 +3019,17 @@ static void subdividenurb(Object *obedit, int number_cuts) * stable... nzc 30-5-'00 */ /* count */ - if (nu->flagu & CU_NURB_CYCLIC) { - a = nu->pntsu; - bp = nu->bp; - prevbp = bp + (a - 1); - } - else { - a = nu->pntsu - 1; - prevbp = nu->bp; - bp = prevbp + 1; - } + a = nu->pntsu; + bp = nu->bp; while (a--) { - if ( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) amount += number_cuts; - prevbp = bp; + nextbp = BKE_nurb_bpoint_get_next(nu, bp); + if (nextbp == NULL) { + break; + } + + if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) { + amount += number_cuts; + } bp++; } @@ -2975,39 +3038,33 @@ static void subdividenurb(Object *obedit, int number_cuts) bpnew = (BPoint *)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2"); bpn = bpnew; - if (nu->flagu & CU_NURB_CYCLIC) { - a = nu->pntsu; - bp = nu->bp; - prevbp = bp + (a - 1); - } - else { - a = nu->pntsu - 1; - prevbp = nu->bp; - bp = prevbp + 1; - } + a = nu->pntsu; + bp = nu->bp; + while (a--) { - memcpy(bpn, prevbp, sizeof(BPoint)); - keyIndex_updateBP(editnurb, prevbp, bpn, 1); + /* Copy "old" point. */ + memcpy(bpn, bp, sizeof(BPoint)); + keyIndex_updateBP(editnurb, bp, bpn, 1); bpn++; - if ((bp->f1 & SELECT) && (prevbp->f1 & SELECT)) { + nextbp = BKE_nurb_bpoint_get_next(nu, bp); + if (nextbp == NULL) { + break; + } + + if ((bp->f1 & SELECT) && (nextbp->f1 & SELECT)) { // printf("*** subdivideNurb: insert 'linear' point\n"); for (i = 0; i < number_cuts; i++) { factor = (float)(i + 1) / (number_cuts + 1); - memcpy(bpn, bp, sizeof(BPoint)); - interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor); + memcpy(bpn, nextbp, sizeof(BPoint)); + interp_v4_v4v4(bpn->vec, bp->vec, nextbp->vec, factor); bpn++; } } - prevbp = bp; bp++; } - if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* last point */ - memcpy(bpn, prevbp, sizeof(BPoint)); - keyIndex_updateBP(editnurb, prevbp, bpn, 1); - } MEM_freeN(nu->bp); nu->bp = bpnew; @@ -5151,7 +5208,7 @@ static int select_more_exec(bContext *C, wmOperator *UNUSED(op)) /* may not be optimal always (example: end of NURBS sphere) */ if (obedit->type == OB_SURF) { for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap selbpoints; + BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; selbpoints = BLI_BITMAP_NEW(a, "selectlist"); @@ -5237,7 +5294,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op)) if (obedit->type == OB_SURF) { for (nu = editnurb->first; nu; nu = nu->next) { - BLI_bitmap selbpoints; + BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; selbpoints = BLI_BITMAP_NEW(a, "selectlist"); @@ -6077,7 +6134,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot) /************** join operator, to be used externally? ****************/ /* TODO: shape keys - as with meshes */ -int join_curve_exec(bContext *C, wmOperator *UNUSED(op)) +int join_curve_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -6089,6 +6146,22 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op)) ListBase tempbase; float imat[4][4], cmat[4][4]; int a; + bool ok = false; + + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) + { + if (base->object == ob) { + ok = true; + break; + } + } + CTX_DATA_END; + + /* that way the active object is always selected */ + if (ok == false) { + BKE_report(op->reports, RPT_WARNING, "Active object is not a selected curve"); + return OPERATOR_CANCELLED; + } tempbase.first = tempbase.last = NULL; diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 5b2cc49d106..b9759e16f20 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -380,7 +380,7 @@ static int paste_file(bContext *C, ReportList *reports, const char *filename) if (cu->len + filelen < MAXTEXT) { int tmplen; - wchar_t *mem = MEM_callocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary"); + wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * filelen) + (4 * sizeof(wchar_t)), "temporary"); tmplen = BLI_strncpy_wchar_from_utf8(mem, strp, filelen + 1); wcscat(ef->textbuf, mem); MEM_freeN(mem); @@ -446,7 +446,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float Object *obedit; Base *base; struct TextLine *tmp; - int nchars = 0, a; + int nchars = 0, nbytes = 0; + char *s; + int a; float rot[3] = {0.f, 0.f, 0.f}; obedit = BKE_object_add(bmain, scene, OB_FONT); @@ -463,26 +465,38 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float cu->vfont = BKE_vfont_builtin_get(); cu->vfont->id.us++; - for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) - nchars += strlen(tmp->line) + 1; + for (tmp = firstline, a = 0; nbytes < MAXTEXT && a < totline; tmp = tmp->next, a++) { + size_t nchars_line, nbytes_line; + nchars_line = BLI_strlen_utf8_ex(tmp->line, &nbytes_line); + nchars += nchars_line + 1; + nbytes += nbytes_line + 1; + } if (cu->str) MEM_freeN(cu->str); if (cu->strinfo) MEM_freeN(cu->strinfo); - cu->str = MEM_callocN(nchars + 4, "str"); + cu->str = MEM_mallocN(nbytes + 4, "str"); cu->strinfo = MEM_callocN((nchars + 4) * sizeof(CharInfo), "strinfo"); - cu->str[0] = '\0'; cu->len = 0; cu->pos = 0; - + + s = cu->str; + *s = '\0'; + for (tmp = firstline, a = 0; cu->len < MAXTEXT && a < totline; tmp = tmp->next, a++) { - strcat(cu->str, tmp->line); - cu->len += strlen(tmp->line); + size_t nbytes_line; + + nbytes_line = BLI_strcpy_rlen(s, tmp->line); + + s += nbytes_line; + cu->len += nbytes_line; if (tmp->next) { - strcat(cu->str, "\n"); - cu->len++; + nbytes_line = BLI_strcpy_rlen(s, "\n"); + + s += nbytes_line; + cu->len += nbytes_line; } cu->pos = cu->len; @@ -1273,7 +1287,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event) accentcode = 0; } else if (event->utf8_buf[0]) { - BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 1); + BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 2); ascii = inserted_text[0]; insert_into_textbuf(obedit, ascii); accentcode = 0; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 50c348a015f..bb0a753d9c6 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -706,8 +706,8 @@ void draw_gpencil_2dimage(const bContext *C) wmOrtho2(ar->v2d.cur.xmin, ar->v2d.cur.xmax, ar->v2d.cur.ymin, ar->v2d.cur.ymax); dflag |= GP_DRAWDATA_ONLYV2D | GP_DRAWDATA_IEDITHACK; + break; } - break; case SPACE_SEQ: /* sequence */ { /* just draw using standard scaling (settings here are currently ignored anyways) */ @@ -720,8 +720,8 @@ void draw_gpencil_2dimage(const bContext *C) * and everything moved to standard View2d */ dflag |= GP_DRAWDATA_ONLYV2D; + break; } - break; default: /* for spacetype not yet handled */ offsx = 0; offsy = 0; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 2d24b34e60b..99157b074fd 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -112,9 +112,8 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) if (ptr) RNA_id_pointer_create(&ob->id, ptr); return &ob->gpd; } + break; } - break; - case SPACE_NODE: /* Nodes Editor */ { SpaceNode *snode = (SpaceNode *)CTX_wm_space_data(C); @@ -125,13 +124,10 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) if (ptr) RNA_id_pointer_create(&snode->nodetree->id, ptr); return &snode->nodetree->gpd; } - else { - /* even when there is no node-tree, don't allow this to flow to scene */ - return NULL; - } + + /* even when there is no node-tree, don't allow this to flow to scene */ + return NULL; } - break; - case SPACE_SEQ: /* Sequencer */ { SpaceSeq *sseq = (SpaceSeq *)CTX_wm_space_data(C); @@ -141,8 +137,6 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceSequenceEditor, sseq, ptr); return &sseq->gpd; } - break; - case SPACE_IMAGE: /* Image/UV Editor */ { SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C); @@ -152,8 +146,6 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) if (ptr) RNA_pointer_create(screen_id, &RNA_SpaceImageEditor, sima, ptr); return &sima->gpd; } - break; - case SPACE_CLIP: /* Nodes Editor */ { SpaceClip *sc = (SpaceClip *)CTX_wm_space_data(C); @@ -178,9 +170,8 @@ bGPdata **gpencil_data_get_pointers(const bContext *C, PointerRNA *ptr) return &clip->gpd; } } + break; } - break; - default: /* unsupported space */ return NULL; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index dc5e12df766..4c5727f16ed 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1084,9 +1084,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: 3D-View active region doesn't have any region data, so cannot be drawable\n"); return 0; } + break; } - break; - case SPACE_NODE: { /* SpaceNode *snode = curarea->spacedata.first; */ @@ -1095,8 +1094,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->sa = curarea; p->ar = ar; p->v2d = &ar->v2d; + break; } - break; case SPACE_SEQ: { SpaceSeq *sseq = curarea->spacedata.first; @@ -1113,8 +1112,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: In active view (sequencer), active mode doesn't support Grease Pencil\n"); return 0; } + break; } - break; case SPACE_IMAGE: { /* SpaceImage *sima = curarea->spacedata.first; */ @@ -1123,8 +1122,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->sa = curarea; p->ar = ar; p->v2d = &ar->v2d; + break; } - break; case SPACE_CLIP: { SpaceClip *sc = curarea->spacedata.first; @@ -1151,9 +1150,8 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->imat[3][0] -= marker->pos[0]; p->imat[3][1] -= marker->pos[1]; } + break; } - break; - /* unsupported views */ default: { @@ -1162,7 +1160,6 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) printf("Error: Active view not appropriate for Grease Pencil drawing\n"); return 0; } - break; } /* get gp-data */ @@ -1295,21 +1292,18 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) case SPACE_VIEW3D: { p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE; + break; } - break; - case SPACE_NODE: { p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + break; } - break; - case SPACE_SEQ: { p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + break; } - break; - case SPACE_IMAGE: { SpaceImage *sima = (SpaceImage *)p->sa->spacedata.first; @@ -1324,16 +1318,16 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode) p->gpd->sbuffer_sflag &= ~GP_STROKE_2DSPACE; p->gpd->flag &= ~GP_DATA_VIEWALIGN; } - else + else { p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + } + break; } - break; - case SPACE_CLIP: { p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + break; } - break; } } } diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index dfb02fa9c1b..352a74cf172 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -55,7 +55,6 @@ void fdrawXORcirc(float xofs, float yofs, float rad); void fdrawcheckerboard(float x1, float y1, float x2, float y2); /* OpenGL stipple defines */ -/* OpenGL stipple defines */ extern const unsigned char stipple_halftone[128]; extern const unsigned char stipple_quarttone[128]; extern const unsigned char stipple_diag_stripes_pos[128]; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 3367dcb9c4c..fab179da7bc 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -132,11 +132,15 @@ EditBone *ED_armature_bone_get_mirrored(struct ListBase *edbo, EditBone *ebo); / void ED_armature_sync_selection(struct ListBase *edbo); void ED_armature_validate_active(struct bArmature *arm); -void add_primitive_bone(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d); +void add_primitive_bone(struct Object *obedit_arm, bool view_aligned); struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name); void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone); + bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child); +void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]); +void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]); + void transform_armature_mirror_update(struct Object *obedit); void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around); @@ -153,6 +157,13 @@ void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const void undo_push_armature(struct bContext *C, const char *name); +/* low level selection functions which handle */ +int ED_armature_ebone_selectflag_get(const EditBone *ebone); +void ED_armature_ebone_selectflag_set(EditBone *ebone, int flag); +void ED_armature_ebone_select_set(EditBone *ebone, bool select); +void ED_armature_ebone_selectflag_enable(EditBone *ebone, int flag); +void ED_armature_ebone_selectflag_disable(EditBone *ebone, int flag); + /* poseobject.c */ void ED_armature_exit_posemode(struct bContext *C, struct Base *base); void ED_armature_enter_posemode(struct bContext *C, struct Base *base); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 807d94b56b0..f24f9098fcd 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -92,9 +92,10 @@ void EDBM_mesh_normals_update(struct BMEditMesh *em); void EDBM_mesh_clear(struct BMEditMesh *em); void EDBM_selectmode_to_scene(struct bContext *C); -void EDBM_mesh_make(struct ToolSettings *ts, struct Scene *scene, struct Object *ob); +void EDBM_mesh_make(struct ToolSettings *ts, struct Object *ob); void EDBM_mesh_free(struct BMEditMesh *em); void EDBM_mesh_load(struct Object *ob); +struct DerivedMesh *EDBM_mesh_deform_dm_get(struct BMEditMesh *em); void EDBM_index_arrays_ensure(struct BMEditMesh *em, const char htype); void EDBM_index_arrays_init(struct BMEditMesh *em, const char htype); @@ -233,6 +234,7 @@ void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); #define WEIGHT_ADD 2 #define WEIGHT_SUBTRACT 3 +bool ED_vgroup_sync_from_pose(struct Object *ob); struct bDeformGroup *ED_vgroup_add(struct Object *ob); struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name); void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup); diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index c1ddd9a6294..bdfbbbb9c74 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -52,6 +52,8 @@ void ED_render_engine_changed(struct Main *bmain); void ED_render_engine_area_exit(struct ScrArea *sa); void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated); +void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database); + /* render_preview.c */ /* stores rendered preview - is also used for icons */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b997d0ef6a0..2daab072435 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -236,6 +236,8 @@ typedef enum { BUT_NORMAL = (31 << 9), BUT_CURVE = (32 << 9), ICONTOGN = (34 << 9), + LISTBOX = (35 << 9), + LISTROW = (36 << 9), TOGBUT = (37 << 9), OPTION = (38 << 9), OPTIONN = (39 << 9), @@ -244,8 +246,6 @@ typedef enum { SEARCH_MENU = (41 << 9), BUT_EXTRA = (42 << 9), HSVCIRCLE = (43 << 9), - LISTBOX = (44 << 9), - LISTROW = (45 << 9), HOTKEYEVT = (46 << 9), BUT_IMAGE = (47 << 9), HISTOGRAM = (48 << 9), @@ -327,7 +327,11 @@ typedef void (*uiMenuHandleFunc)(struct bContext *C, void *arg, int event); typedef struct uiPopupMenu uiPopupMenu; -struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon); +struct uiPopupMenu *uiPupMenuBegin(struct bContext *C, const char *title, int icon) +#ifdef __GNUC__ +__attribute__((nonnull)) +#endif +; void uiPupMenuEnd(struct bContext *C, struct uiPopupMenu *head); struct uiLayout *uiPupMenuLayout(uiPopupMenu *head); @@ -534,7 +538,8 @@ enum { BUT_GET_TIP, BUT_GET_RNA_TIP, BUT_GET_RNAENUM_TIP, - BUT_GET_OP_KEYMAP + BUT_GET_OP_KEYMAP, + BUT_GET_PROP_KEYMAP }; typedef struct uiStringInfo { diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 19eb978a01e..21a63183c1a 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -559,19 +559,19 @@ static void ui_draw_links(uiBlock *block) /* ************** BLOCK ENDING FUNCTION ************* */ /* NOTE: if but->poin is allocated memory for every defbut, things fail... */ -static bool ui_but_equals_old(uiBut *but, uiBut *oldbut) +static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) { /* various properties are being compared here, hopefully sufficient * to catch all cases, but it is simple to add more checks later */ if (but->retval != oldbut->retval) return false; if (but->rnapoin.data != oldbut->rnapoin.data) return false; - if (but->rnaprop != oldbut->rnaprop) - if (but->rnaindex != oldbut->rnaindex) return false; + if (but->rnaprop != oldbut->rnaprop && but->rnaindex != oldbut->rnaindex) return false; if (but->func != oldbut->func) return false; if (but->funcN != oldbut->funcN) return false; if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return false; if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return false; - if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || but->pointype != oldbut->pointype)) return false; + if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || + (but->pointype != oldbut->pointype))) return false; if (but->optype != oldbut->optype) return false; return true; @@ -620,7 +620,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut return found; for (oldbut = oldblock->buttons.first; oldbut; oldbut = oldbut->next) { - if (ui_but_equals_old(oldbut, but)) { + if (ui_but_equals_old(but, oldbut)) { if (oldbut->active) { #if 0 // but->flag = oldbut->flag; @@ -901,6 +901,114 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu return found; } +static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len) +{ + /* context toggle operator names to check... */ + const char *ctx_toggle_opnames[] = { + "WM_OT_context_toggle", + "WM_OT_context_toggle_enum", + "WM_OT_context_cycle_int", + "WM_OT_context_cycle_enum", + "WM_OT_context_cycle_array", + "WM_OT_context_menu_enum", + NULL + }; + const size_t num_ops = sizeof(ctx_toggle_opnames) / sizeof(const char *); + + bool found = false; + + /* this version is only for finding hotkeys for properties (which get set via context using operators) */ + if (but->rnaprop) { + /* to avoid massive slowdowns on property panels, for now, we only check the + * hotkeys for Editor / Scene settings... + * + * TODO: userpref settings? + */ + // TODO: value (for enum stuff)? + char *data_path = NULL; + + if (but->rnapoin.id.data) { + ID *id = but->rnapoin.id.data; + + if (GS(id->name) == ID_SCR) { + /* screen/editor property + * NOTE: in most cases, there is actually no info for backwards tracing + * how to get back to ID from the editor data we may be dealing with + */ + if (RNA_struct_is_a(but->rnapoin.type, &RNA_Space)) { + /* data should be directly on here... */ + data_path = BLI_sprintfN("space_data.%s", RNA_property_identifier(but->rnaprop)); + } + else { + /* special exceptions for common nested data in editors... */ + if (RNA_struct_is_a(but->rnapoin.type, &RNA_DopeSheet)) { + /* dopesheet filtering options... */ + data_path = BLI_sprintfN("space_data.dopesheet.%s", RNA_property_identifier(but->rnaprop)); + } + } + } + else if (GS(id->name) == ID_SCE) { + if (RNA_struct_is_a(but->rnapoin.type, &RNA_ToolSettings)) { + /* toolsettings property + * NOTE: toolsettings is usually accessed directly (i.e. not through scene) + */ + data_path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop); + } + else { + /* scene property */ + char *path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop); + + if (path) { + data_path = BLI_sprintfN("scene.%s", path); + MEM_freeN(path); + } + /*else { + printf("ERROR in %s(): Couldn't get path for scene property - %s\n", + __func__, RNA_property_identifier(but->rnaprop)); + }*/ + } + } + else { + //puts("other id"); + } + + //printf("prop shortcut: '%s' (%s)\n", RNA_property_identifier(but->rnaprop), data_path); + } + + /* we have a datapath! */ + if (data_path) { + size_t i; + + /* create a property to host the "datapath" property we're sending to the operators */ + IDProperty *prop_path; + IDProperty *prop_path_value; + + IDPropertyTemplate val = {0}; + prop_path = IDP_New(IDP_GROUP, &val, __func__); + prop_path_value = IDP_NewString(data_path, "data_path", strlen(data_path) + 1); /* len + 1, or else will be truncated */ + IDP_AddToGroup(prop_path, prop_path_value); + + /* check each until one works... */ + for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); i++) { + //printf("\t%s\n", ctx_toggle_opnames[i]); + if (WM_key_event_operator_string(C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, + buf, buf_len)) + { + found = true; + break; + } + } + + /* cleanup */ + IDP_FreeProperty(prop_path); + MEM_freeN(prop_path); + MEM_freeN(data_path); + } + } + + return found; +} + static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) { uiBut *but; @@ -915,6 +1023,9 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) { ui_but_add_shortcut(but, buf, FALSE); } + else if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { + ui_but_add_shortcut(but, buf, FALSE); + } } } @@ -2056,6 +2167,15 @@ static void ui_set_but_soft_range(uiBut *but) but->softmin = softmin; but->softmax = softmax; } + else if (but->poin && (but->pointype & UI_BUT_POIN_TYPES)) { + float value = ui_get_but_val(but); + CLAMP(value, but->hardmin, but->hardmax); + but->softmin = min_ff(but->softmin, value); + but->softmax = max_ff(but->softmax, value); + } + else { + BLI_assert(0); + } } /* ******************* Free ********************/ @@ -2257,8 +2377,12 @@ void ui_check_but(uiBut *but) ui_check_but_select(but, &value); /* only update soft range while not editing */ - if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) { - ui_set_but_soft_range(but); + if (!(but->editval || but->editstr || but->editvec)) { + if ((but->rnaprop != NULL) || + (but->poin && (but->pointype & UI_BUT_POIN_TYPES))) + { + ui_set_but_soft_range(but); + } } /* test for min and max, icon sliders, etc */ @@ -2302,35 +2426,37 @@ void ui_check_but(uiBut *but) case NUM: case NUMSLI: - UI_GET_BUT_VALUE_INIT(but, value); + if (!but->editstr) { + UI_GET_BUT_VALUE_INIT(but, value); - if (ui_is_but_float(but)) { - if (value == (double) FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str); - } - else if (value == (double) -FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str); - } - /* support length type buttons */ - else if (ui_is_but_unit(but)) { - char new_str[sizeof(but->drawstr)]; - ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1); - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str); + if (ui_is_but_float(but)) { + if (value == (double) FLT_MAX) { + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str); + } + else if (value == (double) -FLT_MAX) { + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str); + } + /* support length type buttons */ + else if (ui_is_but_unit(but)) { + char new_str[sizeof(but->drawstr)]; + ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str); + } + else { + const int prec = ui_but_float_precision(but, value); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); + } } else { - const int prec = ui_but_float_precision(but, value); - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); + BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value); + } + + if (but->rnaprop) { + PropertySubType pstype = RNA_property_subtype(but->rnaprop); + + if (pstype == PROP_PERCENTAGE) + strcat(but->drawstr, "%"); } - } - else { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value); - } - - if (but->rnaprop) { - PropertySubType pstype = RNA_property_subtype(but->rnaprop); - - if (pstype == PROP_PERCENTAGE) - strcat(but->drawstr, "%"); } break; @@ -2353,29 +2479,30 @@ void ui_check_but(uiBut *but) if (!but->editstr) { char str[UI_MAX_DRAW_STR]; - ui_get_but_string(but, str, UI_MAX_DRAW_STR - strlen(but->str)); - + ui_get_but_string(but, str, UI_MAX_DRAW_STR); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, str); } break; case KEYEVT: - BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); + { + const char *str; if (but->flag & UI_SELECT) { - strcat(but->drawstr, "Press a key"); + str = "Press a key"; } else { UI_GET_BUT_VALUE_INIT(but, value); - strcat(but->drawstr, WM_key_event_string((short)value)); + str = WM_key_event_string((short)value); } + BLI_snprintf(but->drawstr, UI_MAX_DRAW_STR, "%s%s", but->str, str); break; - + } case HOTKEYEVT: if (but->flag & UI_SELECT) { - but->drawstr[0] = '\0'; if (but->modifier_key) { char *str = but->drawstr; + but->drawstr[0] = '\0'; if (but->modifier_key & KM_SHIFT) str += BLI_strcpy_rlen(str, "Shift "); @@ -2388,8 +2515,9 @@ void ui_check_but(uiBut *but) (void)str; /* UNUSED */ } - else - strcat(but->drawstr, "Press a key "); + else { + BLI_strncpy(but->drawstr, "Press a key", UI_MAX_DRAW_STR); + } } else BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); @@ -2401,6 +2529,7 @@ void ui_check_but(uiBut *but) break; default: BLI_strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR); + break; } @@ -2646,13 +2775,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, uiBut *but; int slen; - BLI_assert(width >= 0); - BLI_assert(height >= 0); + BLI_assert(width >= 0 && height >= 0); /* we could do some more error checks here */ if ((type & BUTTYPE) == LABEL) { - if ((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f))) - printf("blah\n"); BLI_assert((poin != NULL || min != 0.0f || max != 0.0f || (a1 == 0.0f && a2 != 0.0f) || (a1 != 0.0f && a1 != 1.0f)) == FALSE); } @@ -2740,7 +2866,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {} + if (ELEM8(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, BUTM, SCROLL, SEPR)) {} else if (but->type >= SEARCH_MENU) {} else but->flag |= UI_BUT_UNDO; @@ -3838,7 +3964,8 @@ void uiButSetFocusOnEnter(wmWindow *win, uiBut *but) { wmEvent event; - event = *(win->eventstate); + wm_event_init_from_window(win, &event); + event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -4011,9 +4138,17 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) } } } + else if (type == BUT_GET_PROP_KEYMAP) { + /* for properties that are bound to one of the context cycle, etc. keys... */ + char buf[128]; + if (ui_but_event_property_operator_string(C, but, buf, sizeof(buf))) { + tmp = BLI_strdup(buf); + } + } si->strinfo = tmp; } + va_end(args); if (free_items && items) MEM_freeN(items); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 4c1ad2e41c4..b3df719d95a 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -875,6 +875,10 @@ static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__); ARegion *ar_prev; + /* call here because regular mouse-up event wont run, + * typically 'button_activate_exit()' handles this */ + ui_apply_autokey(C, but); + drag_info->is_set = ui_is_but_push(but); drag_info->but_cent_start[0] = BLI_rctf_cent_x(&but->rect); drag_info->but_cent_start[1] = BLI_rctf_cent_y(&but->rect); @@ -1297,9 +1301,14 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { ID *id = (ID *)wmd->poin; - if (but->poin == NULL && but->rnapoin.data == NULL) {} button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(data->str, id->name + 2, data->maxlen); + + if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { + but->changed = true; + ui_searchbox_update(C, data->searchbox, but, true); + } + button_activate_state(C, but, BUTTON_STATE_EXIT); } } @@ -1420,6 +1429,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* else uiSearchboxData.active member is not updated [#26856] */ + but->changed = true; ui_searchbox_update(C, data->searchbox, but, true); } button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -1852,7 +1862,6 @@ enum { static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const int mode) { - char buf[UI_MAX_DRAW_STR] = {0}; char *str, *p, *pbuf; int x; bool changed = false; @@ -1868,6 +1877,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in p = pbuf = WM_clipboard_text_get(0); if (p && p[0]) { + char buf[UI_MAX_DRAW_STR] = {0}; unsigned int y; buf_len = 0; while (*p && *p != '\r' && *p != '\n' && buf_len < UI_MAX_DRAW_STR - 1) { @@ -1904,14 +1914,12 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in /* cut & copy */ else if (ELEM(mode, UI_TEXTEDIT_COPY, UI_TEXTEDIT_CUT)) { /* copy the contents to the copypaste buffer */ - for (x = but->selsta; x <= but->selend; x++) { - if (x == but->selend) - buf[x] = '\0'; - else - buf[(x - but->selsta)] = str[x]; - } + int sellen = but->selend - but->selsta; + char *buf = MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste"); + BLI_strncpy(buf, str + but->selsta, sellen + 1); WM_clipboard_text_set(buf, 0); + MEM_freeN(buf); /* for cut only, delete the selection afterwards */ if (mode == UI_TEXTEDIT_CUT) { @@ -2175,7 +2183,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle ui_searchbox_event(C, data->searchbox, but, event); break; } - /* pass on purposedly */ + /* fall-through */ case ENDKEY: ui_textedit_move(but, data, STRCUR_DIR_NEXT, event->shift, STRCUR_JUMP_ALL); @@ -2190,7 +2198,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle ui_searchbox_event(C, data->searchbox, but, event); break; } - /* pass on purposedly */ + /* fall-through */ case HOMEKEY: ui_textedit_move(but, data, STRCUR_DIR_PREV, event->shift, STRCUR_JUMP_ALL); @@ -2597,7 +2605,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { if (data->state == BUTTON_STATE_HIGHLIGHT) { - if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { if (but->dt == UI_EMBOSSN && !event->ctrl) { /* pass */ } @@ -2622,7 +2630,7 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { /* unlink icon is on right */ - if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { + if (ELEM4(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS) { ARegion *ar = data->region; rcti rect; int x = event->x, y = event->y; @@ -3713,7 +3721,8 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, break; default: - assert(!"invalid hsv type"); + BLI_assert(0); + break; } hsv_to_rgb_v(hsv, rgb); @@ -3783,8 +3792,10 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOF hsv[2] += ndof->rx * sensitivity; CLAMP(hsv[2], but->softmin, but->softmax); + break; default: assert(!"invalid hsv type"); + break; } hsv_to_rgb_v(hsv, rgb); @@ -4933,7 +4944,6 @@ static bool ui_but_menu(bContext *C, uiBut *but) uiPopupMenu *pup; uiLayout *layout; bool is_array, is_array_component; - const char *name; uiStringInfo label = {BUT_GET_LABEL, NULL}; /* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/ @@ -4946,12 +4956,11 @@ static bool ui_but_menu(bContext *C, uiBut *but) button_timers_tooltip_remove(C, but); + /* highly unlikely getting the label ever fails */ uiButGetStrInfo(C, but, &label, NULL); - name = label.strinfo; - pup = uiPupMenuBegin(C, name, ICON_NONE); + pup = uiPupMenuBegin(C, label.strinfo ? label.strinfo : "", ICON_NONE); layout = uiPupMenuLayout(pup); - if (label.strinfo) MEM_freeN(label.strinfo); @@ -6184,7 +6193,7 @@ void ui_button_activate_do(bContext *C, ARegion *ar, uiBut *but) button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -6291,11 +6300,11 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) case MIDDLEMOUSE: case MOUSEPAN: button_timers_tooltip_remove(C, but); - - /* pass on purposedly */ + /* fall-through */ default: /* handle button type specific events */ retval = ui_do_button(C, block, but, event); + break; } } else if (data->state == BUTTON_STATE_WAIT_RELEASE) { @@ -6345,6 +6354,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) if (event->customdata == data->flashtimer) { button_activate_state(C, but, BUTTON_STATE_EXIT); } + break; } } @@ -6415,7 +6425,6 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) { uiBut *but = ui_list_find_mouse_over(ar, event->x, event->y); int retval = WM_UI_HANDLER_CONTINUE; - int value, min, max; int type = event->type, val = event->val; if (but) { @@ -6438,8 +6447,11 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) if (ELEM(type, UPARROWKEY, DOWNARROWKEY) || ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt))) { + const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop); + int value, min, max; + /* activate up/down the list */ - value = RNA_property_int_get(&but->rnapoin, but->rnaprop); + value = value_orig; if (ELEM(type, UPARROWKEY, WHEELUPMOUSE)) value--; @@ -6456,9 +6468,13 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max); value = CLAMPIS(value, min, max); - RNA_property_int_set(&but->rnapoin, but->rnaprop, value); - RNA_property_update(C, &but->rnapoin, but->rnaprop); - ED_region_tag_redraw(ar); + if (value != value_orig) { + RNA_property_int_set(&but->rnapoin, but->rnaprop, value); + RNA_property_update(C, &but->rnapoin, but->rnaprop); + + ui_apply_undo(but); + ED_region_tag_redraw(ar); + } retval = WM_UI_HANDLER_BREAK; } @@ -6563,6 +6579,8 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force) { + BLI_assert(((uiBlock *)menu->region->uiblocks.first)->flag & UI_BLOCK_MOVEMOUSE_QUIT); + if (!menu->dotowards || force) { menu->dotowards = true; menu->towards_xy[0] = xy[0]; @@ -6595,6 +6613,25 @@ static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *me const float margin = MENU_TOWARDS_MARGIN; rctf rect_px; + BLI_assert(block->flag & UI_BLOCK_MOVEMOUSE_QUIT); + + + /* annoying fix for [#36269], this is a bit odd but in fact works quite well + * don't mouse-out of a menu if another menu has been created after it. + * if this causes problems we could remove it and check on a different fix - campbell */ + if (menu->region->next) { + /* am I the last menu (test) */ + ARegion *ar = menu->region->next; + do { + uiBlock *block = ar->uiblocks.first; + if (block && ui_block_is_menu(block)) { + return true; + } + } while ((ar = ar->next)); + } + /* annoying fix end! */ + + if (!menu->dotowards) { return false; } @@ -6819,10 +6856,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH but = ui_but_find_activated(ar); if (but && button_modal_state(but->active->state)) { - /* if a button is activated modal, always reset the start mouse - * position of the towards mechanism to avoid loosing focus, - * and don't handle events */ - ui_mouse_motion_towards_reinit(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* if a button is activated modal, always reset the start mouse + * position of the towards mechanism to avoid loosing focus, + * and don't handle events */ + ui_mouse_motion_towards_reinit(menu, &event->x); + } } else if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) @@ -6831,7 +6870,9 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH else { /* for ui_mouse_motion_towards_block */ if (event->type == MOUSEMOVE) { - ui_mouse_motion_towards_init(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + ui_mouse_motion_towards_init(menu, &event->x); + } /* add menu scroll timer, if needed */ if (ui_menu_scroll_test(block, my)) @@ -7136,11 +7177,12 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH menu->menuretval = UI_RETURN_CANCEL | UI_RETURN_POPUP_OK; } else { - ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false); /* check mouse moving outside of the menu */ if (inside == 0 && (block->flag & UI_BLOCK_MOVEMOUSE_QUIT)) { uiSafetyRct *saferct; + + ui_mouse_motion_towards_check(block, menu, &event->x, is_parent_inside == false); /* check for all parent rects, enables arrowkeys to be used */ for (saferct = block->saferct.first; saferct; saferct = saferct->next) { @@ -7229,9 +7271,11 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo submenu->menuretval = 0; } - /* for cases where close does not cascade, allow the user to - * move the mouse back towards the menu without closing */ - ui_mouse_motion_towards_reinit(menu, &event->x); + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* for cases where close does not cascade, allow the user to + * move the mouse back towards the menu without closing */ + ui_mouse_motion_towards_reinit(menu, &event->x); + } if (menu->menuretval) return WM_UI_HANDLER_CONTINUE; @@ -7286,12 +7330,16 @@ static int ui_handle_menus_recursive(bContext *C, const wmEvent *event, uiPopupB } if (do_but_search) { + uiBlock *block = menu->region->uiblocks.first; + retval = ui_handle_menu_button(C, event, menu); - /* when there is a active search button and we close it, - * we need to reinit the mouse coords [#35346] */ - if (ui_but_find_activated(menu->region) != but) { - do_towards_reinit = true; + if (block->flag & UI_BLOCK_MOVEMOUSE_QUIT) { + /* when there is a active search button and we close it, + * we need to reinit the mouse coords [#35346] */ + if (ui_but_find_activated(menu->region) != but) { + do_towards_reinit = true; + } } } else { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 82352cee05e..d2a8c47b347 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -427,6 +427,8 @@ struct uiKeyNavLock { struct uiPopupBlockHandle { /* internal */ struct ARegion *region; + + /* use only for 'UI_BLOCK_MOVEMOUSE_QUIT' popups */ float towards_xy[2]; double towardstime; bool dotowards; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 2a6a9600582..2e80af1b3ad 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2429,6 +2429,11 @@ uiLayout *uiLayoutListBox(uiLayout *layout, uiList *ui_list, PointerRNA *ptr, Pr but->rnapoin = *actptr; but->rnaprop = actprop; + /* only for the undo string */ + if (but->flag & UI_BUT_UNDO) { + but->tip = RNA_property_description(actprop); + } + return (uiLayout *)box; } @@ -3077,12 +3082,14 @@ void uiLayoutOperatorButs(const bContext *C, uiLayout *layout, wmOperator *op, /* no undo for buttons for operator redo panels */ uiButClearFlag(but, UI_BUT_UNDO); +#if 0 /* broken, causes freedback loop, see [#36109] */ /* if button is operator's default property, and a text-field, enable focus for it * - this is used for allowing operators with popups to rename stuff with fewer clicks */ if ((but->rnaprop == op->type->prop) && (but->type == TEX)) { uiButSetFocusOnEnter(CTX_wm_window(C), but); } +#endif } } } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 9f7d1435195..5910909142c 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -148,7 +148,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { if (sa->spacetype == SPACE_IMAGE) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceImage *sima = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -160,7 +160,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int } else if (sa->spacetype == SPACE_NODE) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceNode *snode = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -172,7 +172,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int } else if (sa->spacetype == SPACE_CLIP) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (BLI_rcti_isect_pt(&ar->winrct, mx, my)) { + if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { SpaceClip *sc = sa->spacedata.first; int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; @@ -917,7 +917,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch /* First, full lang code. */ BLI_snprintf(tstr, sizeof(tstr), "%s.po", uilng); BLI_join_dirfile(path, maxlen, root, uilng); - BLI_join_dirfile(path, maxlen, path, tstr); + BLI_path_append(path, maxlen, tstr); if (BLI_is_file(path)) return; @@ -941,7 +941,7 @@ static void edittranslation_find_po_file(const char *root, const char *uilng, ch BLI_join_dirfile(path, maxlen, root, tstr); strcat(tstr, ".po"); - BLI_join_dirfile(path, maxlen, path, tstr); + BLI_path_append(path, maxlen, tstr); if (BLI_is_file(path)) return; } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index b13de64d0c7..3fe11ad3a6b 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -255,7 +255,7 @@ Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int pa->sizey = 0; } - BLI_strncpy(pa->drawname, drawname, UI_MAX_NAME_STR); + BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname)); /* if a new panel is added, we insert it right after the panel * that was last added. this way new panels are inserted in the diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index fbe23b1a1ed..95f47be0b70 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -439,6 +439,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL}; + uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, NULL}; uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; @@ -448,7 +449,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create tooltip data */ data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &rna_struct, &rna_prop, NULL); + uiButGetStrInfo(C, but, &but_tip, &enum_label, &enum_tip, &op_keymap, &prop_keymap, &rna_struct, &rna_prop, NULL); /* special case, enum rna buttons only have enum item description, * use general enum description too before the specific one */ @@ -480,6 +481,13 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) data->color_id[data->totline] = UI_TIP_LC_NORMAL; data->totline++; } + + /* Property context-toggle shortcut */ + if (prop_keymap.strinfo) { + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Shortcut: %s"), prop_keymap.strinfo); + data->color_id[data->totline] = UI_TIP_LC_NORMAL; + data->totline++; + } if (ELEM3(but->type, TEX, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* full string */ @@ -516,7 +524,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if (but->rnapoin.id.data) { ID *id = but->rnapoin.id.data; - if (id->lib && id->lib->name) { + if (id->lib) { BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Library: %s"), id->lib->name); data->color_id[data->totline] = UI_TIP_LC_NORMAL; data->totline++; @@ -582,7 +590,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* never fails */ id_path = RNA_path_full_ID_py(id); - if (ptr->id.data && ptr->data && prop) { + if (ptr->data && prop) { data_path = RNA_path_from_ID_to_property(ptr, prop); } @@ -614,6 +622,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) MEM_freeN(enum_tip.strinfo); if (op_keymap.strinfo) MEM_freeN(op_keymap.strinfo); + if (prop_keymap.strinfo) + MEM_freeN(prop_keymap.strinfo); if (rna_struct.strinfo) MEM_freeN(rna_struct.strinfo); if (rna_prop.strinfo) @@ -2106,7 +2116,7 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper static char tip[50]; static char hexcol[128]; float rgb_gamma[3]; - float min, max, step, precision; + float softmin, softmax, hardmin, hardmax, step, precision; float *hsv = ui_block_hsv_get(block); int yco; @@ -2132,7 +2142,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper /* sneaky way to check for alpha */ rgba[3] = FLT_MAX; - RNA_property_float_ui_range(ptr, prop, &min, &max, &step, &precision); + RNA_property_float_ui_range(ptr, prop, &softmin, &softmax, &step, &precision); + RNA_property_float_range(ptr, prop, &hardmin, &hardmax); RNA_property_float_get_array(ptr, prop, rgba); switch (U.color_picker_type) { @@ -2186,7 +2197,8 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); bt = uiDefButF(block, NUMSLI, 0, IFACE_("S "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 1, 0.0, 1.0, 10, 3, TIP_("Saturation")); uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, max, 10, 3, TIP_("Value")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("V "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, hsv + 2, 0.0, softmax, 10, 3, TIP_("Value")); + bt->hardmax = hardmax; /* not common but rgb may be over 1.0 */ uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv); uiBlockEndAlign(block); @@ -2256,10 +2268,8 @@ uiBlock *ui_block_func_COLOR(bContext *C, uiPopupBlockHandle *handle, void *arg_ block = uiBeginBlock(C, handle->region, __func__, UI_EMBOSS); - if (but->rnaprop) { - if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { - block->color_profile = FALSE; - } + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + block->color_profile = false; } if (but->block) { @@ -2516,7 +2526,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) uiStyle *style = UI_GetStyleDraw(); uiPopupMenu *pup = MEM_callocN(sizeof(uiPopupMenu), "popup menu"); uiBut *but; - + pup->block = uiBeginBlock(C, NULL, __func__, UI_EMBOSSP); pup->block->flag |= UI_BLOCK_POPUP_MEMORY; pup->block->puphash = ui_popup_menu_hash(title); @@ -2530,7 +2540,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) pup->block->handle = MEM_callocN(sizeof(uiPopupBlockHandle), "uiPopupBlockHandle"); /* create title button */ - if (title && title[0]) { + if (title[0]) { char titlestr[256]; if (icon) { diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 57392c60f80..f45bd1c3463 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2646,7 +2646,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co sub = uiLayoutRow(overlap, FALSE); but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, - active_dataptr, activeprop, 0, 0, i, 0, 0, ""); + active_dataptr, activeprop, 0, 0, i, 0, 0, NULL); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -2660,6 +2660,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co if (i == activei) { ui_layout_list_set_labels_active(sub); } + + uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM); } i++; } @@ -2734,7 +2736,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co sub = uiLayoutRow(overlap, FALSE); but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, - active_dataptr, activeprop, 0, 0, i, 0, 0, ""); + active_dataptr, activeprop, 0, 0, i, 0, 0, NULL); uiButSetFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -2747,6 +2749,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co ui_layout_list_set_labels_active(sub); } + uiBlockClearFlag(subblock, UI_BLOCK_LIST_ITEM); + i++; } RNA_PROP_END; @@ -3018,16 +3022,16 @@ static void template_keymap_item_properties(uiLayout *layout, const char *title, /* recurse for nested properties */ if (RNA_property_type(prop) == PROP_POINTER) { PointerRNA propptr = RNA_property_pointer_get(ptr, prop); - const char *name = RNA_property_ui_name(prop); if (propptr.data && RNA_struct_is_a(propptr.type, &RNA_OperatorProperties)) { + const char *name = RNA_property_ui_name(prop); template_keymap_item_properties(layout, name, &propptr); continue; } } /* add property */ - uiItemR(flow, ptr, RNA_property_identifier(prop), 0, NULL, ICON_NONE); + uiItemFullR(flow, ptr, prop, -1, 0, 0, NULL, ICON_NONE); } RNA_STRUCT_END; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 9b736eb1bf4..594d3e40dcd 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -96,8 +96,7 @@ typedef struct uiWidgetBase { float inner_v[WIDGET_SIZE_MAX][2]; float inner_uv[WIDGET_SIZE_MAX][2]; - short inner, outline, emboss; /* set on/off */ - short shadedir; + bool inner, outline, emboss, shadedir; uiWidgetTrias tria1; uiWidgetTrias tria2; @@ -209,9 +208,9 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y /* for each AA step */ for (j = 0; j < WIDGET_AA_JITTER; j++) { - glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); + glTranslatef(jit[j][0], jit[j][1], 0.0f); glDrawArrays(GL_TRIANGLES, 0, 3); - glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); + glTranslatef(-jit[j][0], -jit[j][1], 0.0f); } glDisableClientState(GL_VERTEX_ARRAY); @@ -232,9 +231,9 @@ void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float m glColor4fv(color); for (j = 0; j < WIDGET_AA_JITTER; j++) { - glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); + glTranslatef(jit[j][0], jit[j][1], 0.0f); uiDrawBox(mode, minx, miny, maxx, maxy, rad); - glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); + glTranslatef(-jit[j][0], -jit[j][1], 0.0f); } glDisable(GL_BLEND); @@ -778,7 +777,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glEnableClientState(GL_VERTEX_ARRAY); for (j = 0; j < WIDGET_AA_JITTER; j++) { - glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); + glTranslatef(jit[j][0], jit[j][1], 0.0f); /* outline */ glColor4ubv(tcol); @@ -794,7 +793,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glDrawArrays(GL_QUAD_STRIP, 0, wtb->halfwayvert * 2); } - glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); + glTranslatef(-jit[j][0], -jit[j][1], 0.0f); } glDisableClientState(GL_VERTEX_ARRAY); @@ -808,7 +807,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) (unsigned char)((float)wcol->item[3] / WIDGET_AA_JITTER)}; /* for each AA step */ for (j = 0; j < WIDGET_AA_JITTER; j++) { - glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); + glTranslatef(jit[j][0], jit[j][1], 0.0f); if (wtb->tria1.tot) { glColor4ubv(tcol); @@ -819,7 +818,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) widget_trias_draw(&wtb->tria2); } - glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); + glTranslatef(-jit[j][0], -jit[j][1], 0.0f); } } @@ -2061,6 +2060,7 @@ void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, cons copy_v3_v3(col1[0], col1[2]); copy_v3_v3(col1[1], col1[2]); copy_v3_v3(col1[3], col1[2]); + break; } /* old below */ @@ -2365,7 +2365,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slid uiWidgetBase wtb; int horizontal; float rad; - short outline = 0; + bool outline = false; widget_init(&wtb); @@ -2409,8 +2409,9 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slid wtb.emboss = 0; /* only emboss once */ /* exception for progress bar */ - if (state & UI_SCROLL_NO_OUTLINE) - SWAP(short, outline, wtb.outline); + if (state & UI_SCROLL_NO_OUTLINE) { + SWAP(bool, outline, wtb.outline); + } round_box_edges(&wtb, UI_CNR_ALL, slider, rad); @@ -2431,8 +2432,9 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, const rcti *rect, const rcti *slid } widgetbase_draw(&wtb, wcol); - if (state & UI_SCROLL_NO_OUTLINE) - SWAP(short, outline, wtb.outline); + if (state & UI_SCROLL_NO_OUTLINE) { + SWAP(bool, outline, wtb.outline); + } } } @@ -2968,7 +2970,7 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) case UI_WTYPE_LISTLABEL: wt.wcol_theme = &btheme->tui.wcol_list_item; - /* No break, we use usual label code too. */ + /* fall-through */ /* we use usual label code too. */ case UI_WTYPE_LABEL: wt.draw = NULL; break; @@ -3197,9 +3199,9 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case SEPR: ui_draw_separator(rect, &tui->wcol_menu_item); break; - default: wt = widget_type(UI_WTYPE_MENU_ITEM); + break; } } else if (but->dt == UI_EMBOSSN) { @@ -3384,6 +3386,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct default: wt = widget_type(UI_WTYPE_REGULAR); + break; } } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index becffb64ae6..dc780d6a4f1 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1353,7 +1353,8 @@ void UI_make_axis_color(const unsigned char src_col[3], unsigned char dst_col[3] UI_GetColorPtrBlendShade3ubv(src_col, col, dst_col, 0.5f, -10); break; default: - BLI_assert(!"invalid axis arg"); + BLI_assert(0); + break; } } @@ -2094,8 +2095,7 @@ void init_userdef_do_versions(void) if (U.ndof_sensitivity == 0.0f) { U.ndof_sensitivity = 1.0f; - U.ndof_flag = NDOF_LOCK_HORIZON | - NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE; + U.ndof_flag = (NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM | NDOF_SHOULD_ROTATE); } if (U.ndof_orbit_sensitivity == 0.0f) { diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index fe5b129e938..f656d22fc64 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -209,9 +209,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) } /* scrollers - should we have these by default? */ /* XXX for now, we don't override this, or set it either! */ + break; } - break; - /* 'list/channel view' - zoom, aspect ratio, and alignment restrictions are set here */ case V2D_COMMONVIEW_LIST: { @@ -225,9 +224,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) tot_changed = do_init; /* scroller settings are currently not set here... that is left for regions... */ + break; } - break; - /* 'stack view' - practically the same as list/channel view, except is located in the pos y half instead. * zoom, aspect ratio, and alignment restrictions are set here */ case V2D_COMMONVIEW_STACK: @@ -242,9 +240,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) tot_changed = do_init; /* scroller settings are currently not set here... that is left for regions... */ + break; } - break; - /* 'header' regions - zoom, aspect ratio, alignment, and panning restrictions are set here */ case V2D_COMMONVIEW_HEADER: { @@ -272,10 +269,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) /* absolutely no scrollers allowed */ v2d->scroll = 0; - + break; } - break; - /* panels view, with horizontal/vertical align */ case V2D_COMMONVIEW_PANELS_UI: { @@ -308,9 +303,8 @@ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) v2d->cur.ymax = 0.0f; v2d->cur.ymin = (-winy) * panelzoom; } + break; } - break; - /* other view types are completely defined using their own settings already */ default: /* we don't do anything here, as settings should be fine, but just make sure that rect */ @@ -1739,9 +1733,8 @@ void UI_view2d_scrollers_draw(const bContext *C, View2D *v2d, View2DScrollers *v fac2 = fac2 - time; scroll_printstr(scene, fac, h, time + (float)FPS * fac2 / 100.0f, grid->powerx, V2D_UNIT_SECONDSSEQ, 'h'); + break; } - break; - case V2D_UNIT_DEGREES: /* Graph Editor for rotation Drivers */ /* HACK: although we're drawing horizontal, we make this draw as 'vertical', just to get degree signs */ scroll_printstr(scene, fac, h, val, grid->powerx, V2D_UNIT_DEGREES, 'v'); diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index e12817262f8..929b7ae2a5d 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -247,8 +247,8 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event) vpd->lasty = event->y; view_pan_apply(op); + break; } - break; /* XXX - Mode switching isn't implemented. See comments in 36818. * switch to zoom */ #if 0 @@ -1288,7 +1288,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar, fac = smooth_view_rect_to_fac(&v2d->cur, cur); } - if (C && U.smooth_viewtx && fac > FLT_EPSILON) { + if (U.smooth_viewtx && fac > FLT_EPSILON) { int changed = FALSE; if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == FALSE) @@ -1674,9 +1674,8 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *e vsm->lasty = event->y; scroller_activate_apply(C, op); + break; } - break; - case LEFTMOUSE: case MIDDLEMOUSE: if (event->val == KM_RELEASE) { diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index 33a6aa2d43d..9c270144a0a 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -387,6 +387,7 @@ static int add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2] /* TODO - we could pass the spline! */ BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); + masklay->act_spline = spline; masklay->act_point = new_point; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c index cd2995be439..9ae5b436fb3 100644 --- a/source/blender/editors/mask/mask_edit.c +++ b/source/blender/editors/mask/mask_edit.c @@ -390,6 +390,8 @@ void ED_operatortypes_mask(void) WM_operatortype_append(MASK_OT_select_circle); WM_operatortype_append(MASK_OT_select_linked_pick); WM_operatortype_append(MASK_OT_select_linked); + WM_operatortype_append(MASK_OT_select_more); + WM_operatortype_append(MASK_OT_select_less); /* hide/reveal */ WM_operatortype_append(MASK_OT_hide_view_clear); @@ -466,6 +468,9 @@ void ED_keymap_mask(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); RNA_boolean_set(kmi->ptr, "deselect", TRUE); + WM_keymap_add_item(keymap, "MASK_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); + /* hide/reveal */ WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index fcfcfb237e9..bd148c48980 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -88,6 +88,8 @@ void MASK_OT_select_lasso(struct wmOperatorType *ot); void MASK_OT_select_circle(struct wmOperatorType *ot); void MASK_OT_select_linked_pick(struct wmOperatorType *ot); void MASK_OT_select_linked(struct wmOperatorType *ot); +void MASK_OT_select_more(struct wmOperatorType *ot); +void MASK_OT_select_less(struct wmOperatorType *ot); int ED_mask_spline_select_check(struct MaskSpline *spline); int ED_mask_layer_select_check(struct MaskLayer *masklay); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 134806cf5bd..5c2aacf0713 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -655,8 +655,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = (event->val == KM_PRESS); - /* no break! update CV position */ - + /* fall-through */ /* update CV position */ case MOUSEMOVE: { ScrArea *sa = CTX_wm_area(C); diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 997f170c9f9..c524aeb06ee 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -470,7 +470,7 @@ void MASK_OT_select_border(wmOperatorType *ot) { /* identifiers */ ot->name = "Border Select"; - ot->description = "Select markers using border selection"; + ot->description = "Select curve points using border selection"; ot->idname = "MASK_OT_select_border"; /* api callbacks */ @@ -521,7 +521,7 @@ static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, float screen_co[2]; - /* marker in screen coords */ + /* point in screen coords */ ED_mask_point_pos__reverse(sa, ar, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], &screen_co[0], &screen_co[1]); @@ -569,7 +569,7 @@ void MASK_OT_select_lasso(wmOperatorType *ot) { /* identifiers */ ot->name = "Lasso Select"; - ot->description = "Select markers using lasso selection"; + ot->description = "Select curve points using lasso selection"; ot->idname = "MASK_OT_select_lasso"; /* api callbacks */ @@ -670,7 +670,7 @@ void MASK_OT_select_circle(wmOperatorType *ot) { /* identifiers */ ot->name = "Circle Select"; - ot->description = "Select markers using circle selection"; + ot->description = "Select curve points using circle selection"; ot->idname = "MASK_OT_select_circle"; /* api callbacks */ @@ -784,7 +784,7 @@ void MASK_OT_select_linked(wmOperatorType *ot) /* identifiers */ ot->name = "Select Linked All"; ot->idname = "MASK_OT_select_linked"; - ot->description = "Select all vertices linked to the active mesh"; + ot->description = "Select all curve points linked to already selected ones"; /* api callbacks */ ot->exec = mask_select_linked_exec; @@ -793,3 +793,115 @@ void MASK_OT_select_linked(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/**************** Select more/less **************/ + +static int mask_select_more_less(bContext *C, bool more) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + bool start_sel, end_sel, prev_sel, cur_sel, cyclic = spline->flag & MASK_SPLINE_CYCLIC; + + /* reselect point if any handle is selected to make the result more predictable */ + for (i = 0; i < spline->tot_point; i++) { + BKE_mask_point_select_set(spline->points + i, MASKPOINT_ISSEL_ANY(spline->points + i)); + } + + /* select more/less does not affect empty/single point splines */ + if (spline->tot_point < 2) { + continue; + } + + if (cyclic) { + start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points); + end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]); + } + + for (i = 0; i < spline->tot_point; i++) { + if (i == 0 && !cyclic) { + continue; + } + + prev_sel = (i > 0) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i - 1]) : end_sel; + cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]); + + if (cur_sel != more) { + if (prev_sel == more) { + BKE_mask_point_select_set(&spline->points[i], more); + } + i++; + } + } + + for (i = spline->tot_point - 1; i >= 0; i--) { + if (i == spline->tot_point - 1 && !cyclic) { + continue; + } + + prev_sel = (i < spline->tot_point - 1) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i + 1]) : start_sel; + cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]); + + if (cur_sel != more) { + if (prev_sel == more) { + BKE_mask_point_select_set(&spline->points[i], more); + } + i--; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; +} + +static int mask_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return mask_select_more_less(C, true); +} + +void MASK_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->idname = "MASK_OT_select_more"; + ot->description = "Select more spline points connected to initial selection"; + + /* api callbacks */ + ot->exec = mask_select_more_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return mask_select_more_less(C, false); +} + +void MASK_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->idname = "MASK_OT_select_less"; + ot->description = "Deselect spline points at the boundary of each selection region"; + + /* api callbacks */ + ot->exec = mask_select_less_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index b2c7846ab6c..db5635d6ea3 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -95,9 +95,11 @@ void paintface_flush_flags(Object *ob) /* loop over tessfaces */ for (i = 0; i < totface; i++) { - /* Copy flags onto the original tessface from its original poly */ - mp_orig = me->mpoly + index_array[i]; - faces[i].flag = mp_orig->flag; + if (index_array[i] != ORIGINDEX_NONE) { + /* Copy flags onto the original tessface from its original poly */ + mp_orig = me->mpoly + index_array[i]; + faces[i].flag = mp_orig->flag; + } } } @@ -107,9 +109,11 @@ void paintface_flush_flags(Object *ob) /* loop over final derived polys */ for (i = 0; i < totpoly; i++) { - /* Copy flags onto the final derived poly from the original mesh poly */ - mp_orig = me->mpoly + index_array[i]; - polys[i].flag = mp_orig->flag; + if (index_array[i] != ORIGINDEX_NONE) { + /* Copy flags onto the final derived poly from the original mesh poly */ + mp_orig = me->mpoly + index_array[i]; + polys[i].flag = mp_orig->flag; + } } } @@ -120,9 +124,11 @@ void paintface_flush_flags(Object *ob) /* loop over tessfaces */ for (i = 0; i < totface; i++) { - /* Copy flags onto the final tessface from its final poly */ - mp_orig = polys + index_array[i]; - faces[i].flag = mp_orig->flag; + if (index_array[i] != ORIGINDEX_NONE) { + /* Copy flags onto the final tessface from its final poly */ + mp_orig = polys + index_array[i]; + faces[i].flag = mp_orig->flag; + } } } } @@ -192,8 +198,8 @@ static void select_linked_tfaces_with_seams(Mesh *me, const unsigned int index, bool do_it = true; bool mark = false; - BLI_bitmap edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); - BLI_bitmap poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); + BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); + BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); if (index != (unsigned int)-1) { /* only put face under cursor in array */ diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index e544592365d..f372053db55 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -118,9 +118,10 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Plane"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", - 1, 1, RNA_float_get(op->ptr, "radius"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", + 1, 1, RNA_float_get(op->ptr, "radius"), mat)) { return OPERATOR_CANCELLED; } @@ -162,8 +163,10 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Cube"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_cube matrix=%m4 size=%f", - mat, RNA_float_get(op->ptr, "radius") * 2.0f)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_cube matrix=%m4 size=%f", + mat, RNA_float_get(op->ptr, "radius") * 2.0f)) { return OPERATOR_CANCELLED; } @@ -216,10 +219,11 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Circle"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), - cap_end, cap_tri, mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b matrix=%m4", + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), + cap_end, cap_tri, mat)) { return OPERATOR_CANCELLED; } @@ -269,7 +273,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), @@ -329,7 +333,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) @@ -385,11 +389,12 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Grid"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", - RNA_int_get(op->ptr, "x_subdivisions"), - RNA_int_get(op->ptr, "y_subdivisions"), - RNA_float_get(op->ptr, "radius"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_grid x_segments=%i y_segments=%i size=%f matrix=%m4", + RNA_int_get(op->ptr, "x_subdivisions"), + RNA_int_get(op->ptr, "y_subdivisions"), + RNA_float_get(op->ptr, "radius"), mat)) { return OPERATOR_CANCELLED; } @@ -444,7 +449,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", "create_monkey matrix=%m4", mat)) { + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_monkey matrix=%m4", mat)) + { return OPERATOR_CANCELLED; } @@ -485,10 +493,11 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Sphere"), &dia, mat, &was_editmode, loc, rot, layer); em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_call_and_selectf(em, op, "verts.out", - "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4", - RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), - RNA_float_get(op->ptr, "size"), mat)) + if (!EDBM_op_call_and_selectf( + em, op, "verts.out", false, + "create_uvsphere u_segments=%i v_segments=%i diameter=%f matrix=%m4", + RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), + RNA_float_get(op->ptr, "size"), mat)) { return OPERATOR_CANCELLED; } @@ -538,7 +547,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) em = BKE_editmesh_from_object(obedit); if (!EDBM_op_call_and_selectf( - em, op, "verts.out", + em, op, "verts.out", false, "create_icosphere subdivisions=%i diameter=%f matrix=%m4", RNA_int_get(op->ptr, "subdivisions"), RNA_float_get(op->ptr, "size"), mat)) diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c index 65c528dbe03..b38f09b1dec 100644 --- a/source/blender/editors/mesh/editmesh_extrude.c +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -713,7 +713,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; BMOperator spinop; - float cent[3], axis[3], imat[3][3]; + float cent[3], axis[3]; float d[3] = {0.0f, 0.0f, 0.0f}; int steps, dupli; float angle; @@ -726,15 +726,10 @@ static int edbm_spin_exec(bContext *C, wmOperator *op) angle = -angle; dupli = RNA_boolean_get(op->ptr, "dupli"); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - + /* keep the values in worldspace since we're passing the obmat */ if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, d, steps, angle, obedit->obmat, dupli)) { return OPERATOR_CANCELLED; } @@ -800,8 +795,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) BMVert *eve, *v1, *v2; BMIter iter, eiter; BMOperator spinop; - float dvec[3], nor[3], cent[3], axis[3]; - float imat[3][3]; + float dvec[3], nor[3], cent[3], axis[3], v1_co_global[3], v2_co_global[3]; int steps, turns; int valence; @@ -811,13 +805,6 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) RNA_float_get_array(op->ptr, "center", cent); RNA_float_get_array(op->ptr, "axis", axis); - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - - /* find two vertices with valence count == 1, more or less is wrong */ v1 = NULL; v2 = NULL; @@ -850,15 +837,17 @@ static int edbm_screw_exec(bContext *C, wmOperator *op) } /* calculate dvec */ - sub_v3_v3v3(dvec, v1->co, v2->co); + mul_v3_m4v3(v1_co_global, obedit->obmat, v1->co); + mul_v3_m4v3(v2_co_global, obedit->obmat, v2->co); + sub_v3_v3v3(dvec, v1_co_global, v2_co_global); mul_v3_fl(dvec, 1.0f / steps); - if (dot_v3v3(nor, dvec) > 0.000f) + if (dot_v3v3(nor, dvec) > 0.0f) negate_v3(dvec); if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), false)) + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f space=%m4 use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), obedit->obmat, false)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 50db460e5bc..d61f6712a8f 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -38,6 +38,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_array.h" +#include "BLI_alloca.h" #include "BLI_linklist.h" #include "BLI_math.h" #include "BLI_smallhash.h" @@ -2623,15 +2624,15 @@ static bool knife_edge_in_face(KnifeTool_OpData *UNUSED(kcd), KnifeEdge *kfe, BM /* Split face f with KnifeEdges on chain. f remains as one side, the face formed is put in *newface. * The new face will be on the left side of the chain as viewed from the normal-out side of f. */ -static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **newface) +static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *chain, BMFace **r_f_new) { BMesh *bm = kcd->em->bm; KnifeEdge *kfe, *kfelast; BMVert *v1, *v2; - BMFace *fnew; + BMFace *f_new; Ref *ref; KnifeVert *kfv, *kfvprev; - BMLoop *lnew, *l_iter; + BMLoop *l_new, *l_iter; int i; int nco = BLI_countlist(chain) - 1; float (*cos)[3] = BLI_array_alloca(cos, nco); @@ -2652,23 +2653,21 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha kfvprev = kfv; } BLI_assert(i == nco); - lnew = NULL; + l_new = NULL; if (nco == 0) { /* Want to prevent creating two-sided polygons */ if (BM_edge_exists(v1, v2)) { - *newface = NULL; + f_new = NULL; } else { - *newface = BM_face_split(bm, f, v1, v2, &lnew, NULL, true); + f_new = BM_face_split(bm, f, v1, v2, &l_new, NULL, true); } } else { - fnew = BM_face_split_n(bm, f, v1, v2, cos, nco, &lnew, NULL); - *newface = fnew; - - if (fnew) { + f_new = BM_face_split_n(bm, f, v1, v2, cos, nco, &l_new, NULL); + if (f_new) { /* Now go through lnew chain matching up chain kv's and assign real v's to them */ - for (l_iter = lnew->next, i = 0; i < nco; l_iter = l_iter->next, i++) { + for (l_iter = l_new->next, i = 0; i < nco; l_iter = l_iter->next, i++) { BLI_assert(equals_v3v3(cos[i], l_iter->v->co)); if (kcd->select_result) { BM_edge_select_set(bm, l_iter->e, true); @@ -2680,10 +2679,15 @@ static void knife_make_chain_cut(KnifeTool_OpData *kcd, BMFace *f, ListBase *cha /* the select chain above doesnt account for the first loop */ if (kcd->select_result) { - if (lnew) { - BM_edge_select_set(bm, lnew->e, true); + if (l_new) { + BM_edge_select_set(bm, l_new->e, true); } } + else { + BM_elem_select_copy(bm, bm, f, f_new); + } + + *r_f_new = f_new; } static void knife_make_face_cuts(KnifeTool_OpData *kcd, BMFace *f, ListBase *kfedges) @@ -2887,6 +2891,7 @@ static void knifetool_finish_ex(KnifeTool_OpData *kcd) knife_make_cuts(kcd); #endif + EDBM_selectmode_flush(kcd->em); EDBM_mesh_normals_update(kcd->em); EDBM_update_generic(kcd->em, true, true); } diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 2829aed4999..3c1b210d171 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -42,6 +42,7 @@ #include "BKE_modifier.h" #include "BKE_report.h" #include "BKE_editmesh.h" +#include "BKE_DerivedMesh.h" #include "BIF_gl.h" @@ -61,6 +62,7 @@ #include "mesh_intern.h" /* own include */ #define SUBD_SMOOTH_MAX 4.0f +#define SUBD_CUTS_MAX 500 /* ringsel operator */ @@ -155,9 +157,30 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed, } } +static void edgering_vcos_get(DerivedMesh *dm, BMVert *v[2][2], float r_cos[2][2][3]) +{ + if (dm) { + int j, k; + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + dm->getVertCo(dm, BM_elem_index_get(v[j][k]), r_cos[j][k]); + } + } + } + else { + int j, k; + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + copy_v3_v3(r_cos[j][k], v[j][k]->co); + } + } + } +} + static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select) { BMEditMesh *em = lcd->em; + DerivedMesh *dm = EDBM_mesh_deform_dm_get(em); BMEdge *eed_start = lcd->eed; BMEdge *eed, *eed_last; BMVert *v[2][2], *v_last; @@ -195,6 +218,10 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select) return; } + if (dm) { + EDBM_index_arrays_ensure(lcd->em, BM_VERT); + } + BMW_init(&walker, em->bm, BMW_EDGERING, BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP, BMW_FLAG_TEST_HIDDEN, @@ -222,19 +249,26 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select) for (i = 1; i <= previewlines; i++) { const float fac = (i / ((float)previewlines + 1)); - interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac); - interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac); + float v_cos[2][2][3]; + + edgering_vcos_get(dm, v, v_cos); + + interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac); + interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac); tot++; } } eed_last = eed; } + if ((eed_last != eed_start) && #ifdef BMW_EDGERING_NGON - if (lasteed != startedge && BM_edge_share_face_check(lasteed, startedge)) { + BM_edge_share_face_check(eed_last, eed_start) #else - if (eed_last != eed_start && BM_edge_share_quad_check(eed_last, eed_start)) { + BM_edge_share_quad_check(eed_last, eed_start) #endif + ) + { v[1][0] = v[0][0]; v[1][1] = v[0][1]; @@ -244,13 +278,16 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select) for (i = 1; i <= previewlines; i++) { const float fac = (i / ((float)previewlines + 1)); + float v_cos[2][2][3]; if (!v[0][0] || !v[0][1] || !v[1][0] || !v[1][1]) { continue; } - interp_v3_v3v3(edges[tot][0], v[0][0]->co, v[0][1]->co, fac); - interp_v3_v3v3(edges[tot][1], v[1][0]->co, v[1][1]->co, fac); + edgering_vcos_get(dm, v, v_cos); + + interp_v3_v3v3(edges[tot][0], v_cos[0][0], v_cos[0][1], fac); + interp_v3_v3v3(edges[tot][1], v_cos[1][0], v_cos[1][1], fac); tot++; } } @@ -545,6 +582,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) break; if (event->alt == 0) { cuts++; + cuts = CLAMPIS(cuts, 0, SUBD_CUTS_MAX); RNA_int_set(op->ptr, "number_cuts", cuts); ringsel_find_edge(lcd, cuts); show_cuts = true; @@ -598,7 +636,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event) /* allow zero so you can backspace and type in a value * otherwise 1 as minimum would make more sense */ - cuts = CLAMPIS(value, 0, 130); + cuts = CLAMPIS(value, 0, SUBD_CUTS_MAX); RNA_int_set(op->ptr, "number_cuts", cuts); ringsel_find_edge(lcd, cuts); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index e9694b8a8f3..a1f1f6bd83f 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -460,7 +460,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const bool sel, c 0, NULL, NULL); } - eve = BM_vert_at_index(vc->em->bm, index - 1); + eve = index ? BM_vert_at_index(vc->em->bm, index - 1) : NULL; if (eve && distance < *r_dist) { *r_dist = distance; @@ -552,7 +552,7 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) view3d_validate_backbuf(vc); index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); - eed = BM_edge_at_index(vc->em->bm, index - 1); + eed = index ? BM_edge_at_index(vc->em->bm, index - 1) : NULL; if (eed && distance < *r_dist) { *r_dist = distance; @@ -625,7 +625,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) view3d_validate_backbuf(vc); index = view3d_sample_backbuf(vc, vc->mval[0], vc->mval[1]); - efa = BM_face_at_index(vc->em->bm, index - 1); + efa = index ? BM_face_at_index(vc->em->bm, index - 1) : NULL; if (efa) { struct { float mval_fl[2]; float dist; BMFace *toFace; } data; @@ -927,10 +927,11 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS } else if (em->selectmode & SCE_SELECT_FACE) { #ifdef WITH_FREESTYLE - for (a = SIMFACE_MATERIAL; a <= SIMFACE_FREESTYLE; a++) { + const int a_end = SIMFACE_FREESTYLE; #else - for (a = SIMFACE_MATERIAL; a <= SIMFACE_COPLANAR; a++) { + const int a_end = SIMFACE_COPLANAR; #endif + for (a = SIMFACE_MATERIAL; a <= a_end; a++) { RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a); } } @@ -1589,8 +1590,7 @@ void EDBM_selectmode_set(BMEditMesh *em) } if (em->bm->totfacesel) { - efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter)) { + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_face_select_set(em->bm, efa, true); } @@ -1705,6 +1705,7 @@ bool EDBM_selectmode_toggle(bContext *C, const short selectmode_new, break; default: BLI_assert(0); + break; } switch (selectmode_new) { @@ -2425,9 +2426,6 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { - BMVert *v; - BMEdge *e; - BMFace *f; BMIter iter; BMElem *ele; @@ -2438,7 +2436,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, EDBM_selectmode_flush(em); ele = BM_mesh_active_elem_get(em->bm); - if (ele) { + if (ele && BM_elem_flag_test(ele, BM_ELEM_SELECT)) { switch (ele->head.htype) { case BM_VERT: *r_eve = (BMVert *)ele; @@ -2453,6 +2451,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } if (em->selectmode & SCE_SELECT_VERTEX) { + BMVert *v; BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { *r_eve = v; @@ -2461,6 +2460,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } } else if (em->selectmode & SCE_SELECT_EDGE) { + BMEdge *e; BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { *r_eed = e; @@ -2469,8 +2469,8 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } } else if (em->selectmode & SCE_SELECT_FACE) { - f = BM_mesh_active_face_get(em->bm, true, false); - if (f) { + BMFace *f = BM_mesh_active_face_get(em->bm, true, false); + if (f && BM_elem_flag_test(f, BM_ELEM_SELECT)) { *r_efa = f; return; } @@ -2617,7 +2617,7 @@ static int edbm_select_linked_flat_faces_exec(bContext *C, wmOperator *op) BMLoop *l, *l2; const float angle_limit = RNA_float_get(op->ptr, "sharpness"); - BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); + BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { @@ -3074,10 +3074,10 @@ void MESH_OT_region_to_loop(wmOperatorType *ot) static int loop_find_region(BMLoop *l, int flag, SmallHash *fhash, BMFace ***region_out) { - BLI_array_declare(region); - BLI_array_declare(stack); BMFace **region = NULL; BMFace **stack = NULL; + BLI_array_declare(region); + BLI_array_declare(stack); BMFace *f; BLI_array_append(stack, l->f); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 2fa6812d131..868db4fa746 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -635,7 +635,7 @@ void MESH_OT_edge_face_add(wmOperatorType *ot) /* ************************* SEAMS AND EDGES **************** */ -static int edbm_mark_seam(bContext *C, wmOperator *op) +static int edbm_mark_seam_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); @@ -681,7 +681,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot) ot->description = "(Un)mark selected edges as a seam"; /* api callbacks */ - ot->exec = edbm_mark_seam; + ot->exec = edbm_mark_seam_exec; ot->poll = ED_operator_editmesh; /* flags */ @@ -690,7 +690,7 @@ void MESH_OT_mark_seam(wmOperatorType *ot) RNA_def_boolean(ot->srna, "clear", 0, "Clear", ""); } -static int edbm_mark_sharp(bContext *C, wmOperator *op) +static int edbm_mark_sharp_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Mesh *me = ((Mesh *)obedit->data); @@ -735,7 +735,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot) ot->description = "(Un)mark selected edges as sharp"; /* api callbacks */ - ot->exec = edbm_mark_sharp; + ot->exec = edbm_mark_sharp_exec; ot->poll = ED_operator_editmesh; /* flags */ @@ -745,7 +745,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot) } -static int edbm_vert_connect(bContext *C, wmOperator *op) +static int edbm_vert_connect_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -795,13 +795,58 @@ void MESH_OT_vert_connect(wmOperatorType *ot) ot->description = "Connect 2 vertices of a face by an edge, splitting the face in two"; /* api callbacks */ - ot->exec = edbm_vert_connect; + ot->exec = edbm_vert_connect_exec; ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +static int edbm_vert_connect_nonplaner_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + + const float angle_limit = RNA_float_get(op->ptr, "angle_limit"); + + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "connect_verts_nonplanar faces=%hf angle_limit=%f", + BM_ELEM_SELECT, angle_limit)) + { + return OPERATOR_CANCELLED; + } + + + EDBM_update_generic(em, true, true); + return OPERATOR_FINISHED; +} + +void MESH_OT_vert_connect_nonplanar(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Split Non-Planar Faces"; + ot->idname = "MESH_OT_vert_connect_nonplanar"; + ot->description = "Split non-planar faces that exceed the angle threshold"; + + /* api callbacks */ + ot->exec = edbm_vert_connect_nonplaner_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, NULL, 0.0f, DEG2RADF(180.0f), + "Max Angle", "Angle limit", 0.0f, DEG2RADF(180.0f)); + RNA_def_property_float_default(prop, DEG2RADF(5.0f)); +} + + static int edbm_edge_split_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -1066,7 +1111,7 @@ static int edbm_normals_make_consistent_exec(bContext *C, wmOperator *op) /* doflip has to do with bmesh_rationalize_normals, it's an internal * thing */ - if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf use_face_tag=%b", BM_ELEM_SELECT, true)) + if (!EDBM_op_callf(em, op, "recalc_face_normals faces=%hf", BM_ELEM_SELECT)) return OPERATOR_CANCELLED; if (RNA_boolean_get(op->ptr, "inside")) @@ -1622,6 +1667,7 @@ static int edbm_merge_exec(bContext *C, wmOperator *op) break; default: BLI_assert(0); + break; } if (!ok) { @@ -2276,7 +2322,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) /* store percentage of edge cut for KNIFE_EXACT here.*/ slot_edge_percents = BMO_slot_get(bmop.slots_in, "edge_percents"); - for (be = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); be; be = BM_iter_step(&iter)) { + BM_ITER_MESH (be, &iter, bm, BM_EDGES_OF_MESH) { bool is_cut = false; if (BM_elem_flag_test(be, BM_ELEM_SELECT)) { const float *sco_a = screen_vert_coords[BM_elem_index_get(be->v1)]; @@ -2751,15 +2797,56 @@ void MESH_OT_fill_grid(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int edbm_fill_holes_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + const int sides = RNA_int_get(op->ptr, "sides"); + + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "holes_fill edges=%he sides=%i", + BM_ELEM_SELECT, sides)) + { + return OPERATOR_CANCELLED; + } + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; + +} + +void MESH_OT_fill_holes(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Fill Holes"; + ot->idname = "MESH_OT_fill_holes"; + ot->description = "Fill in holes (boundary edge loops)"; + + /* api callbacks */ + ot->exec = edbm_fill_holes_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides (zero disables)", 0, 100); +} static int edbm_beautify_fill_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); - if (!EDBM_op_callf(em, op, "beautify_fill faces=%hf edges=ae", BM_ELEM_SELECT)) + if (!EDBM_op_call_and_selectf( + em, op, "geom.out", true, + "beautify_fill faces=%hf edges=ae", + BM_ELEM_SELECT)) + { return OPERATOR_CANCELLED; + } EDBM_update_generic(em, true, true); @@ -2854,11 +2941,14 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) EDBM_op_init(em, &bmop, op, "triangulate faces=%hf use_beauty=%b", BM_ELEM_SELECT, use_beauty); BMO_op_exec(em->bm, &bmop); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + /* now call beauty fill */ if (use_beauty) { - EDBM_op_callf(em, op, - "beautify_fill faces=%S edges=%S", - &bmop, "faces.out", &bmop, "edges.out"); + EDBM_op_call_and_selectf( + em, op, "geom.out", true, + "beautify_fill faces=%S edges=%S", + &bmop, "faces.out", &bmop, "edges.out"); } if (!EDBM_op_finish(em, &bmop, op, true)) { @@ -2900,9 +2990,11 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op) dovcols = RNA_boolean_get(op->ptr, "vcols"); domaterials = RNA_boolean_get(op->ptr, "materials"); - if (!EDBM_op_callf(em, op, - "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b", - BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials)) + if (!EDBM_op_call_and_selectf( + em, op, + "faces.out", true, + "join_triangles faces=%hf limit=%f cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b", + BM_ELEM_SELECT, limit, dosharp, douvs, dovcols, domaterials)) { return OPERATOR_CANCELLED; } @@ -3093,12 +3185,10 @@ static int edbm_dissolve_limited_exec(bContext *C, wmOperator *op) dissolve_flag = BM_ELEM_SELECT; } - if (!EDBM_op_callf(em, op, - "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i", - dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit)) - { - return OPERATOR_CANCELLED; - } + EDBM_op_call_and_selectf( + em, op, "region.out", true, + "dissolve_limit edges=%he verts=%hv angle_limit=%f use_dissolve_boundaries=%b delimit=%i", + dissolve_flag, dissolve_flag, angle_limit, use_dissolve_boundaries, delimit); EDBM_update_generic(em, true, true); @@ -3935,6 +4025,7 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) const bool use_cyclic = (type == 1); const bool use_merge = RNA_boolean_get(op->ptr, "use_merge"); const float merge_factor = RNA_float_get(op->ptr, "merge_factor"); + const int twist_offset = RNA_int_get(op->ptr, "twist_offset"); const bool use_faces = (em->bm->totfacesel != 0); char edge_hflag; @@ -3962,8 +4053,8 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } EDBM_op_init(em, &bmop, op, - "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f", - edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor); + "bridge_loops edges=%he use_pairs=%b use_cyclic=%b use_merge=%b merge_factor=%f twist_offset=%i", + edge_hflag, use_pairs, use_cyclic, use_merge, merge_factor, twist_offset); BMO_op_exec(em->bm, &bmop); @@ -3990,14 +4081,23 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) mesh_operator_edgering_props_get(op, &op_props); if (op_props.cuts) { + BMOperator bmop_subd; /* we only need face normals updated */ EDBM_mesh_normals_update(em); - BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, - "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f " - "profile_shape=%i profile_shape_factor=%f", - &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth, - op_props.profile_shape, op_props.profile_shape_factor); + BMO_op_initf( + em->bm, &bmop_subd, op->flag, + "subdivide_edgering edges=%S interp_mode=%i cuts=%i smooth=%f " + "profile_shape=%i profile_shape_factor=%f", + &bmop, "edges.out", op_props.interp_mode, op_props.cuts, op_props.smooth, + op_props.profile_shape, op_props.profile_shape_factor + ); + BMO_op_exec(em->bm, &bmop_subd); + + BMO_slot_buffer_hflag_enable(em->bm, bmop_subd.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + + BMO_op_finish(em->bm, &bmop_subd); + } } } @@ -4007,8 +4107,9 @@ static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) } if (!EDBM_op_finish(em, &bmop, op, true)) { - return OPERATOR_CANCELLED; - + /* grr, need to return finished so the user can select different options */ + //return OPERATOR_CANCELLED; + return OPERATOR_FINISHED; } else { EDBM_update_generic(em, true, true); @@ -4042,6 +4143,7 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_merge", false, "Merge", "Merge rather than creating faces"); RNA_def_float(ot->srna, "merge_factor", 0.5f, 0.0f, 1.0f, "Merge Factor", "", 0.0f, 1.0f); + RNA_def_int(ot->srna, "twist_offset", 0, -1000, 1000, "Twist", "Twist offset for closed loops", -1000, 1000); mesh_operator_edgering_props(ot, 0); } @@ -4380,7 +4482,7 @@ void MESH_OT_symmetry_snap(struct wmOperatorType *ot) #ifdef WITH_FREESTYLE -static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) +static int edbm_mark_freestyle_edge_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Mesh *me = (Mesh *)obedit->data; @@ -4433,7 +4535,7 @@ void MESH_OT_mark_freestyle_edge(wmOperatorType *ot) ot->idname = "MESH_OT_mark_freestyle_edge"; /* api callbacks */ - ot->exec = edbm_mark_freestyle_edge; + ot->exec = edbm_mark_freestyle_edge_exec; ot->poll = ED_operator_editmesh; /* flags */ diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index effbe3a619d..44cc89cb23c 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -35,7 +35,7 @@ #include "DNA_object_types.h" #include "BLI_math.h" -#include "BLI_array.h" +#include "BLI_alloca.h" #include "BKE_DerivedMesh.h" #include "BKE_context.h" @@ -171,6 +171,13 @@ void EDBM_stats_update(BMEditMesh *em) } } +DerivedMesh *EDBM_mesh_deform_dm_get(BMEditMesh *em) +{ + return ((em->derivedFinal != NULL) && + (em->derivedFinal->type == DM_TYPE_EDITBMESH) && + (em->derivedFinal->deformedOnly != false)) ? em->derivedFinal : NULL; +} + bool EDBM_op_init(BMEditMesh *em, BMOperator *bmop, wmOperator *op, const char *fmt, ...) { BMesh *bm = em->bm; @@ -263,7 +270,9 @@ bool EDBM_op_callf(BMEditMesh *em, wmOperator *op, const char *fmt, ...) return EDBM_op_finish(em, &bmop, op, true); } -bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select_slot_out, const char *fmt, ...) +bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, + const char *select_slot_out, const bool select_extend, + const char *fmt, ...) { BMOpSlot *slot_select_out; BMesh *bm = em->bm; @@ -287,8 +296,11 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em, wmOperator *op, const char *select slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out); hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP; + BLI_assert(hflag != 0); - BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + if (select_extend == false) { + BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); + } BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, select_slot_out, hflag, BM_ELEM_SELECT, true); @@ -334,7 +346,7 @@ void EDBM_selectmode_to_scene(bContext *C) WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, scene); } -void EDBM_mesh_make(ToolSettings *ts, Scene *UNUSED(scene), Object *ob) +void EDBM_mesh_make(ToolSettings *ts, Object *ob) { Mesh *me = ob->data; BMesh *bm; @@ -361,8 +373,10 @@ void EDBM_mesh_make(ToolSettings *ts, Scene *UNUSED(scene), Object *ob) me->edit_btmesh->selectmode = me->edit_btmesh->bm->selectmode = ts->selectmode; me->edit_btmesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0; - me->edit_btmesh->ob = ob; + + /* we need to flush selection because the mode may have changed from when last in editmode */ + EDBM_selectmode_flush(me->edit_btmesh); } void EDBM_mesh_load(Object *ob) diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 21fe51c03ef..e8cbf0926d4 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -37,8 +37,8 @@ #include "DNA_view3d_types.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_path_util.h" -#include "BLI_array.h" #include "BLI_math.h" #include "BKE_context.h" @@ -116,6 +116,7 @@ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_t BLI_assert(0); tot = 0; data = NULL; + break; } *r_tot = tot; @@ -125,98 +126,22 @@ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_t #define GET_CD_DATA(me, data) (me->edit_btmesh ? &me->edit_btmesh->bm->data : &me->data) static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) { + const int type = layer->type; CustomData *data; - void *actlayerdata, *rndlayerdata, *clonelayerdata, *stencillayerdata, *layerdata = layer->data; - int type = layer->type; - int index; - int i, actindex, rndindex, cloneindex, stencilindex, tot; + int layer_index, tot, n; - if (layer->type == CD_MLOOPCOL || layer->type == CD_MLOOPUV) { - data = mesh_customdata_get_type(me, BM_LOOP, &tot); - } - else { - data = mesh_customdata_get_type(me, BM_FACE, &tot); - } - - index = CustomData_get_layer_index(data, type); - - /* ok, deleting a non-active layer needs to preserve the active layer indices. - * to do this, we store a pointer to the .data member of both layer and the active layer, - * (to detect if we're deleting the active layer or not), then use the active - * layer data pointer to find where the active layer has ended up. - * - * this is necessary because the deletion functions only support deleting the active - * layer. */ - actlayerdata = data->layers[CustomData_get_active_layer_index(data, type)].data; - rndlayerdata = data->layers[CustomData_get_render_layer_index(data, type)].data; - clonelayerdata = data->layers[CustomData_get_clone_layer_index(data, type)].data; - stencillayerdata = data->layers[CustomData_get_stencil_layer_index(data, type)].data; - CustomData_set_layer_active(data, type, layer - &data->layers[index]); + data = mesh_customdata_get_type(me, (ELEM(type, CD_MLOOPUV, CD_MLOOPCOL)) ? BM_LOOP : BM_FACE, &tot); + layer_index = CustomData_get_layer_index(data, type); + n = (layer - &data->layers[layer_index]); + BLI_assert(n >= 0 && (n + layer_index) < data->totlayer); if (me->edit_btmesh) { - BM_data_layer_free(me->edit_btmesh->bm, data, type); + BM_data_layer_free_n(me->edit_btmesh->bm, data, type, n); } else { - CustomData_free_layer_active(data, type, tot); + CustomData_free_layer(data, type, tot, layer_index + n); BKE_mesh_update_customdata_pointers(me, true); } - - /* reconstruct active layer */ - if (actlayerdata != layerdata) { - /* find index */ - actindex = CustomData_get_layer_index(data, type); - for (i = actindex; i < data->totlayer; i++) { - if (data->layers[i].data == actlayerdata) { - actindex = i - actindex; - break; - } - } - - /* set index */ - CustomData_set_layer_active(data, type, actindex); - } - - if (rndlayerdata != layerdata) { - /* find index */ - rndindex = CustomData_get_layer_index(data, type); - for (i = rndindex; i < data->totlayer; i++) { - if (data->layers[i].data == rndlayerdata) { - rndindex = i - rndindex; - break; - } - } - - /* set index */ - CustomData_set_layer_render(data, type, rndindex); - } - - if (clonelayerdata != layerdata) { - /* find index */ - cloneindex = CustomData_get_layer_index(data, type); - for (i = cloneindex; i < data->totlayer; i++) { - if (data->layers[i].data == clonelayerdata) { - cloneindex = i - cloneindex; - break; - } - } - - /* set index */ - CustomData_set_layer_clone(data, type, cloneindex); - } - - if (stencillayerdata != layerdata) { - /* find index */ - stencilindex = CustomData_get_layer_index(data, type); - for (i = stencilindex; i < data->totlayer; i++) { - if (data->layers[i].data == stencillayerdata) { - stencilindex = i - stencilindex; - break; - } - } - - /* set index */ - CustomData_set_layer_stencil(data, type, stencilindex); - } } static void mesh_uv_reset_array(float **fuv, const int len) @@ -642,7 +567,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *e obedit = base->object; me = obedit->data; if (me->edit_btmesh == NULL) { - EDBM_mesh_make(scene->toolsettings, scene, obedit); + EDBM_mesh_make(scene->toolsettings, obedit); exitmode = 1; } if (me->edit_btmesh == NULL) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 69f471670ed..b2d6e872206 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -59,7 +59,8 @@ struct LinkNode; /* Calls a bmesh op, reporting errors to the user, etc */ bool EDBM_op_callf(struct BMEditMesh *em, struct wmOperator *op, const char *fmt, ...); bool EDBM_op_call_and_selectf(struct BMEditMesh *em, struct wmOperator *op, - const char *selectslot, const char *fmt, ...); + const char *select_slot, const bool select_replace, + const char *fmt, ...); /* Same as above, but doesn't report errors.*/ bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...); @@ -165,6 +166,7 @@ void MESH_OT_normals_make_consistent(struct wmOperatorType *ot); void MESH_OT_vertices_smooth(struct wmOperatorType *ot); void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot); void MESH_OT_vert_connect(struct wmOperatorType *ot); +void MESH_OT_vert_connect_nonplanar(struct wmOperatorType *ot); void MESH_OT_edge_split(struct wmOperatorType *ot); void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); void MESH_OT_wireframe(struct wmOperatorType *ot); @@ -195,6 +197,7 @@ void MESH_OT_knife_cut(struct wmOperatorType *ot); void MESH_OT_separate(struct wmOperatorType *ot); void MESH_OT_fill(struct wmOperatorType *ot); void MESH_OT_fill_grid(struct wmOperatorType *ot); +void MESH_OT_fill_holes(struct wmOperatorType *ot); void MESH_OT_beautify_fill(struct wmOperatorType *ot); void MESH_OT_quads_convert_to_tris(struct wmOperatorType *ot); void MESH_OT_tris_convert_to_quads(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 4f2924293ea..90dc803ea50 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -102,6 +102,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_fill); WM_operatortype_append(MESH_OT_fill_grid); + WM_operatortype_append(MESH_OT_fill_holes); WM_operatortype_append(MESH_OT_beautify_fill); WM_operatortype_append(MESH_OT_quads_convert_to_tris); WM_operatortype_append(MESH_OT_tris_convert_to_quads); @@ -155,6 +156,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_solidify); WM_operatortype_append(MESH_OT_select_nth); WM_operatortype_append(MESH_OT_vert_connect); + WM_operatortype_append(MESH_OT_vert_connect_nonplanar); WM_operatortype_append(MESH_OT_knife_tool); WM_operatortype_append(MESH_OT_knife_project); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 51b5e30bc3f..059f8de7108 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -88,9 +88,10 @@ int join_mesh_exec(bContext *C, wmOperator *op) Key *key, *nkey = NULL; KeyBlock *kb, *okb, *kbn; float imat[4][4], cmat[4][4], *fp1, *fp2; - int a, b, totcol, totmat = 0, totedge = 0, totvert = 0, ok = 0; + int a, b, totcol, totmat = 0, totedge = 0, totvert = 0; int totloop = 0, totpoly = 0, vertofs, *matmap = NULL; int i, j, index, haskey = 0, edgeofs, loopofs, polyofs; + bool ok = false; bDeformGroup *dg, *odg; MDeformVert *dvert; CustomData vdata, edata, fdata, ldata, pdata; @@ -119,7 +120,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) totmat += base->object->totcol; if (base->object == ob) - ok = 1; + ok = true; /* check for shapekeys */ if (me->key) @@ -129,7 +130,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* that way the active object is always selected */ - if (ok == 0) { + if (ok == false) { BKE_report(op->reports, RPT_WARNING, "Active object is not a selected mesh"); return OPERATOR_CANCELLED; } @@ -569,7 +570,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR | EM_DO_UNDO); #else /* toggle editmode using lower level functions so this can be called from python */ - EDBM_mesh_make(scene->toolsettings, scene, ob); + EDBM_mesh_make(scene->toolsettings, ob); EDBM_mesh_load(ob); EDBM_mesh_free(me->edit_btmesh); MEM_freeN(me->edit_btmesh); @@ -1199,7 +1200,7 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index = view3d_sample_backbuf(&vc, mval[0], mval[1]); } - if ((*index) <= 0 || (*index) > (unsigned int)me->totpoly) + if ((*index) == 0 || (*index) > (unsigned int)me->totpoly) return false; (*index)--; @@ -1320,7 +1321,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index = view3d_sample_backbuf(&vc, mval[0], mval[1]); } - if ((*index) <= 0 || (*index) > (unsigned int)me->totvert) + if ((*index) == 0 || (*index) > (unsigned int)me->totvert) return false; (*index)--; @@ -1350,7 +1351,7 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int data.len_best = FLT_MAX; data.v_idx_best = -1; - dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data); + dm->foreachMappedVert(dm, ed_mesh_pick_vert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index d6f48b4d350..ce61b4fce50 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -226,7 +226,7 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, return dia; } - return 1.0f; + // return 1.0f; } /********************* Add Object Operator ********************/ @@ -265,6 +265,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl bool *enter_editmode, unsigned int *layer, bool *is_view_aligned) { View3D *v3d = CTX_wm_view3d(C); + unsigned int _layer; /* Switch to Edit mode? */ if (RNA_struct_find_property(op->ptr, "enter_editmode")) { /* optional */ @@ -283,7 +284,6 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl /* Get layers! */ { int a, layer_values[20]; - unsigned int _layer; if (!layer) layer = &_layer; @@ -342,7 +342,7 @@ int ED_object_add_generic_get_opts(bContext *C, wmOperator *op, float loc[3], fl else if (RNA_struct_property_is_set(op->ptr, "view_align")) *is_view_aligned = RNA_boolean_get(op->ptr, "view_align"); else { - *is_view_aligned = U.flag & USER_ADD_VIEWALIGNED; + *is_view_aligned = (U.flag & USER_ADD_VIEWALIGNED) != 0; RNA_boolean_set(op->ptr, "view_align", *is_view_aligned); } @@ -657,12 +657,12 @@ void OBJECT_OT_text_add(wmOperatorType *ot) static int object_armature_add_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); - View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); bool newob = false; bool enter_editmode; unsigned int layer; float loc[3], rot[3]; + bool view_aligned = rv3d && (U.flag & USER_ADD_VIEWALIGNED); if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -681,8 +681,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* v3d and rv3d are allowed to be NULL */ - add_primitive_bone(CTX_data_scene(C), v3d, rv3d); + add_primitive_bone(obedit, view_aligned); /* userdef */ if (newob && !enter_editmode) @@ -1432,7 +1431,7 @@ static int convert_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - Base *basen = NULL, *basact = NULL, *basedel = NULL; + Base *basen = NULL, *basact = NULL; Object *ob, *ob1, *newob, *obact = CTX_data_active_object(C); DerivedMesh *dm; Curve *cu; @@ -1688,14 +1687,6 @@ static int convert_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); ((ID *)ob->data)->flag &= ~LIB_DOIT; /* flag not to convert this datablock again */ } - - /* delete original if needed */ - if (basedel) { - if (!keep_original) - ED_base_object_free_and_unlink(bmain, scene, basedel); - - basedel = NULL; - } } CTX_DATA_END; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 3f1ceb7327c..8b674cf1e50 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -107,13 +107,14 @@ typedef struct { int threads; } MultiresBakeJob; -static int multiresbake_check(bContext *C, wmOperator *op) +static bool multiresbake_check(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob; Mesh *me; MultiresModifierData *mmd; - int ok = 1, a; + bool ok = true; + int a; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { @@ -122,7 +123,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (ob->type != OB_MESH) { BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); - ok = 0; + ok = false; break; } @@ -137,12 +138,12 @@ static int multiresbake_check(bContext *C, wmOperator *op) for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) { if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { - ok = 0; + ok = false; } } } else { - ok = 0; + ok = false; } if (!ok) { @@ -153,14 +154,14 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (mmd->lvl == 0) { BKE_report(op->reports, RPT_ERROR, "Multires data baking is not supported for preview subdivision level 0"); - + ok = false; break; } if (!me->mtpoly) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); - ok = 0; + ok = false; } else { a = me->totpoly; @@ -170,7 +171,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); - ok = 0; + ok = false; } else { ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); @@ -178,14 +179,14 @@ static int multiresbake_check(bContext *C, wmOperator *op) if (!ibuf) { BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); - ok = 0; + ok = false; } else { if (ibuf->rect == NULL && ibuf->rect_float == NULL) - ok = 0; + ok = false; if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) - ok = 0; + ok = false; if (!ok) BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 0a69306928a..aed1d9a1a6c 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -478,7 +478,7 @@ void ED_object_editmode_enter(bContext *C, int flag) ok = 1; scene->obedit = ob; /* context sees this */ - EDBM_mesh_make(CTX_data_tool_settings(C), scene, ob); + EDBM_mesh_make(scene->toolsettings, ob); em = BKE_editmesh_from_object(ob); if (LIKELY(em)) { @@ -1501,36 +1501,38 @@ static const char *object_mode_op_string(int mode) /* checks the mode to be set is compatible with the object * should be made into a generic function */ -static int object_mode_set_compat(bContext *UNUSED(C), wmOperator *op, Object *ob) +static bool object_mode_set_compat(bContext *UNUSED(C), wmOperator *op, Object *ob) { ObjectMode mode = RNA_enum_get(op->ptr, "mode"); if (ob) { if (mode == OB_MODE_OBJECT) - return 1; + return true; switch (ob->type) { case OB_MESH: if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT)) - return 1; - return 0; + return true; + break; case OB_CURVE: case OB_SURF: case OB_FONT: case OB_MBALL: if (mode & (OB_MODE_EDIT)) - return 1; - return 0; + return true; + break; case OB_LATTICE: if (mode & (OB_MODE_EDIT | OB_MODE_WEIGHT_PAINT)) - return 1; + return true; + break; case OB_ARMATURE: if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) - return 1; + return true; + break; } } - return 0; + return false; } static int object_mode_set_exec(bContext *C, wmOperator *op) @@ -1608,7 +1610,7 @@ void ED_object_toggle_modes(bContext *C, int mode) /************************ Game Properties ***********************/ -static int game_property_new(bContext *C, wmOperator *op) +static int game_property_new_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bProperty *prop; @@ -1638,7 +1640,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) ot->idname = "OBJECT_OT_game_property_new"; /* api callbacks */ - ot->exec = game_property_new; + ot->exec = game_property_new_exec; ot->poll = ED_operator_object_active_editable; /* flags */ @@ -1648,7 +1650,7 @@ void OBJECT_OT_game_property_new(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Name of the game property to add"); } -static int game_property_remove(bContext *C, wmOperator *op) +static int game_property_remove_exec(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); bProperty *prop; @@ -1679,7 +1681,7 @@ void OBJECT_OT_game_property_remove(wmOperatorType *ot) ot->idname = "OBJECT_OT_game_property_remove"; /* api callbacks */ - ot->exec = game_property_remove; + ot->exec = game_property_remove_exec; ot->poll = ED_operator_object_active_editable; /* flags */ diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 1f0163bc391..c8baa0d84dc 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -310,7 +310,7 @@ static bool object_hook_index_array(Scene *scene, Object *obedit, int *tot, int BMEditMesh *em; EDBM_mesh_load(obedit); - EDBM_mesh_make(scene->toolsettings, scene, obedit); + EDBM_mesh_make(scene->toolsettings, obedit); em = me->edit_btmesh; @@ -318,12 +318,10 @@ static bool object_hook_index_array(Scene *scene, Object *obedit, int *tot, int BKE_editmesh_tessface_calc(em); /* check selected vertices first */ - if (return_editmesh_indexar(em, tot, indexar, cent_r)) { - return true; - } - else { + if (return_editmesh_indexar(em, tot, indexar, cent_r) == 0) { return return_editmesh_vgroup(obedit, em, name, cent_r); } + return true; } case OB_CURVE: case OB_SURF: diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 58cca9dca02..4ff3bc9ac06 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -138,7 +138,10 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_lattice.c */ void LATTICE_OT_select_all(struct wmOperatorType *ot); +void LATTICE_OT_select_more(struct wmOperatorType *ot); +void LATTICE_OT_select_less(struct wmOperatorType *ot); void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot); +void LATTICE_OT_select_random(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); void LATTICE_OT_flip(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 0e220357d30..a79b0607421 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -37,6 +37,8 @@ #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_rand.h" +#include "BLI_bitmap.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" @@ -54,6 +56,7 @@ #include "BKE_lattice.h" #include "BKE_deform.h" #include "BKE_report.h" +#include "BKE_utildefines.h" #include "ED_lattice.h" #include "ED_object.h" @@ -170,6 +173,163 @@ void load_editLatt(Object *obedit) } } +/************************** Select Random Operator **********************/ + +static int lattice_select_random_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + const float randfac = RNA_float_get(op->ptr, "percent") / 100.0f; + int tot; + BPoint *bp; + + if (!RNA_boolean_get(op->ptr, "extend")) { + ED_setflagsLatt(obedit, !SELECT); + } + else { + lt->actbp = LT_ACTBP_NONE; + } + + tot = lt->pntsu * lt->pntsv * lt->pntsw; + bp = lt->def; + while (tot--) { + if (!bp->hide) { + if (BLI_frand() < randfac) { + bp->f1 |= SELECT; + } + } + bp++; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_random(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Random"; + ot->description = "Randomly select UVW control points"; + ot->idname = "LATTICE_OT_select_random"; + + /* api callbacks */ + ot->exec = lattice_select_random_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_float_percentage(ot->srna, "percent", 50.f, 0.0f, 100.0f, + "Percent", "Percentage of elements to select randomly", 0.f, 100.0f); + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); +} + +/************************** Select More/Less Operator *************************/ + +static bool lattice_test_bitmap_uvw(Lattice *lt, BLI_bitmap *selpoints, int u, int v, int w, const bool selected) +{ + if ((u < 0 || u >= lt->pntsu) || + (v < 0 || v >= lt->pntsv) || + (w < 0 || w >= lt->pntsw)) + { + return false; + } + else { + int i = BKE_lattice_index_from_uvw(lt, u, v, w); + if (lt->def[i].hide == 0) { + return (BLI_BITMAP_GET(selpoints, i) != 0) == selected; + } + return false; + } +} + +static int lattice_select_more_less(bContext *C, const bool select) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + BPoint *bp; + const int tot = lt->pntsu * lt->pntsv * lt->pntsw; + int i, w, u, v; + BLI_bitmap *selpoints; + + lt->actbp = LT_ACTBP_NONE; + + bp = lt->def; + selpoints = BLI_BITMAP_NEW(tot, __func__); + for (i = 0; i < tot; i++, bp++) { + if (bp->f1 & SELECT) { + BLI_BITMAP_SET(selpoints, i); + } + } + + bp = lt->def; + for (w = 0; w < lt->pntsw; w++) { + for (v = 0; v < lt->pntsv; v++) { + for (u = 0; u < lt->pntsu; u++) { + if ((bp->hide == 0) && (((bp->f1 & SELECT) == 0) == select)) { + if (lattice_test_bitmap_uvw(lt, selpoints, u + 1, v, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u - 1, v, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v + 1, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v - 1, w, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v, w + 1, select) || + lattice_test_bitmap_uvw(lt, selpoints, u, v, w - 1, select)) + { + BKE_BIT_TEST_SET(bp->f1, select, SELECT); + } + } + bp++; + } + } + } + + MEM_freeN(selpoints); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + return OPERATOR_FINISHED; +} + +static int lattice_select_more_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return lattice_select_more_less(C, true); +} + +static int lattice_select_less_exec(bContext *C, wmOperator *UNUSED(op)) +{ + return lattice_select_more_less(C, false); +} + +void LATTICE_OT_select_more(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select More"; + ot->description = "Select vertex directly linked to already selected ones"; + ot->idname = "LATTICE_OT_select_more"; + + /* api callbacks */ + ot->exec = lattice_select_more_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +void LATTICE_OT_select_less(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Less"; + ot->description = "Deselect vertices at the boundary of each selection region"; + ot->idname = "LATTICE_OT_select_less"; + + /* api callbacks */ + ot->exec = lattice_select_less_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /************************** Select All Operator *************************/ void ED_setflagsLatt(Object *obedit, int flag) @@ -510,8 +670,8 @@ static int lattice_flip_exec(bContext *C, wmOperator *op) } } } + break; } - break; case LATTICE_FLIP_V: { int u, v, w; @@ -531,8 +691,8 @@ static int lattice_flip_exec(bContext *C, wmOperator *op) } } } + break; } - break; case LATTICE_FLIP_W: { int u, v, w; @@ -551,9 +711,8 @@ static int lattice_flip_exec(bContext *C, wmOperator *op) } } } + break; } - break; - default: /* shouldn't happen, but just in case */ break; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index b1f1f73f493..b9c97c32fc9 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1671,7 +1671,7 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) static void skin_armature_bone_create(Object *skin_ob, MVert *mvert, MEdge *medge, bArmature *arm, - BLI_bitmap edges_visited, + BLI_bitmap *edges_visited, const MeshElemMap *emap, EditBone *parent_bone, int parent_v) @@ -1720,7 +1720,7 @@ static void skin_armature_bone_create(Object *skin_ob, static Object *modifier_skin_armature_create(Main *bmain, Scene *scene, Object *skin_ob) { - BLI_bitmap edges_visited; + BLI_bitmap *edges_visited; DerivedMesh *deform_dm; MVert *mvert; Mesh *me = skin_ob->data; diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 35bfba8b78a..333e5ff3006 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -217,7 +217,10 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_shape_key_move); WM_operatortype_append(LATTICE_OT_select_all); + WM_operatortype_append(LATTICE_OT_select_more); + WM_operatortype_append(LATTICE_OT_select_less); WM_operatortype_append(LATTICE_OT_select_ungrouped); + WM_operatortype_append(LATTICE_OT_select_random); WM_operatortype_append(LATTICE_OT_make_regular); WM_operatortype_append(LATTICE_OT_flip); @@ -427,6 +430,8 @@ void ED_keymap_object(wmKeyConfig *keyconf) RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); kmi = WM_keymap_add_item(keymap, "LATTICE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "LATTICE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 75c1f956f1b..52f51cfcf48 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -136,7 +136,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) BMEditMesh *em; EDBM_mesh_load(obedit); - EDBM_mesh_make(scene->toolsettings, scene, obedit); + EDBM_mesh_make(scene->toolsettings, obedit); em = me->edit_btmesh; @@ -494,23 +494,21 @@ void ED_object_parent_clear(Object *ob, int type) /* clear parenting relationship completely */ ob->parent = NULL; + break; } - break; - case CLEAR_PARENT_KEEP_TRANSFORM: { /* remove parent, and apply the parented transform result as object's local transforms */ ob->parent = NULL; BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); + break; } - break; - case CLEAR_PARENT_INVERSE: { /* object stays parented, but the parent inverse (i.e. offset from parent to retain binding state) is cleared */ unit_m4(ob->parentinv); + break; } - break; } DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); @@ -2051,7 +2049,7 @@ static int make_local_exec(bContext *C, wmOperator *op) if (adt) BKE_animdata_make_local(adt); /* tag indirect data direct */ - matarar = (Material ***)give_matarar(ob); + matarar = give_matarar(ob); if (matarar) { for (a = 0; a < ob->totcol; a++) { ma = (*matarar)[a]; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 424333810a8..366aa72f2b8 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -682,12 +682,17 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); + Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); Object *tob; float cursor[3], cent[3], cent_neg[3], centn[3]; int centermode = RNA_enum_get(op->ptr, "type"); int around = RNA_enum_get(op->ptr, "center"); /* initialized from v3d->around */ + ListBase ctx_data_list; + CollectionPointerLink *ctx_ob; + CollectionPointerLink *ctx_ob_act = NULL; + /* keep track of what is changed */ int tot_change = 0, tot_lib_error = 0, tot_multiuser_arm_error = 0; @@ -746,12 +751,25 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } + CTX_data_selected_editable_objects(C, &ctx_data_list); + /* reset flags */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + for (ctx_ob = ctx_data_list.first; + ctx_ob; + ctx_ob = ctx_ob->next) { + Object *ob = ctx_ob->ptr.data; ob->flag &= ~OB_DONE; + + /* move active first */ + if (ob == obact) { + ctx_ob_act = ctx_ob; + } + } + + if (ctx_ob_act) { + BLI_rotatelist(&ctx_data_list, (LinkData *)ctx_ob_act); } - CTX_DATA_END; for (tob = bmain->object.first; tob; tob = tob->id.next) { if (tob->data) @@ -760,8 +778,12 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ((ID *)tob->dup_group)->flag &= ~LIB_DOIT; } - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + for (ctx_ob = ctx_data_list.first; + ctx_ob; + ctx_ob = ctx_ob->next) { + Object *ob = ctx_ob->ptr.data; + if ((ob->flag & OB_DONE) == 0) { int do_inverse_offset = FALSE; ob->flag |= OB_DONE; @@ -992,7 +1014,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } } - CTX_DATA_END; + BLI_freelistN(&ctx_data_list); for (tob = bmain->object.first; tob; tob = tob->id.next) if (tob->data && (((ID *)tob->data)->flag & LIB_DOIT)) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index da46001bde9..9b3f1a4f3ac 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -109,6 +109,22 @@ static Lattice *vgroup_edit_lattice(Object *ob) return (lt->editlatt) ? lt->editlatt->latt : lt; } +bool ED_vgroup_sync_from_pose(Object *ob) +{ + Object *armobj = BKE_object_pose_armature_get(ob); + if (armobj && (armobj->mode & OB_MODE_POSE)) { + struct bArmature *arm = armobj->data; + if (arm->act_bone) { + int def_num = defgroup_name_index(ob, arm->act_bone->name); + if (def_num != -1) { + ob->actdef = def_num + 1; + return true; + } + } + } + return false; +} + bool ED_vgroup_object_is_edit_mode(Object *ob) { if (ob->type == OB_MESH) @@ -125,13 +141,8 @@ bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name) if (!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) return NULL; - - defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); - BLI_strncpy(defgroup->name, name, sizeof(defgroup->name)); - - BLI_addtail(&ob->defbase, defgroup); - defgroup_unique_name(defgroup, ob); + defgroup = BKE_defgroup_new(ob, name); ob->actdef = BLI_countlist(&ob->defbase); @@ -279,9 +290,7 @@ static bool ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_t return true; } - else { - return false; - } + return false; } case ID_LT: { @@ -309,9 +318,7 @@ static bool ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_t return true; } - else { - return false; - } + return false; } } } @@ -754,15 +761,14 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro unsigned int f_index; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); + bool is_dg_dst_new = false; /* Ensure vertex group on target.*/ - if (!defgroup_find_name(ob_dst, dg_src->name)) { - ED_vgroup_add_name(ob_dst, dg_src->name); + if ((dg_dst = defgroup_find_name(ob_dst, dg_src->name)) == NULL) { + dg_dst = BKE_defgroup_new(ob_dst, dg_src->name); + is_dg_dst_new = true; } - /* Get destination deformgroup.*/ - dg_dst = defgroup_find_name(ob_dst, dg_src->name); - /* Get meshes.*/ dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH); me_dst = ob_dst->data; @@ -812,7 +818,10 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || dv_array_src == NULL || dv_array_dst == NULL) { - ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + if (is_dg_dst_new) { + ED_vgroup_delete(ob_dst, dg_dst); + } + if (dv_array_src) MEM_freeN(dv_array_src); if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); @@ -909,18 +918,16 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro project_v3_plane(tmp_co, normal, mv_src[mf->v1].co); /* Interpolate weights over face.*/ - f_index = mf->v4 ? 3 : 2; - if (f_index == 3) { - interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, - mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); - } - else { - interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, - mv_src[mf->v3].co, NULL, tmp_co); - } + interp_weights_face_v3(tmp_weight, + mv_src[mf->v1].co, + mv_src[mf->v2].co, + mv_src[mf->v3].co, + mf->v4 ? mv_src[mf->v4].co : NULL, + tmp_co); /* Get weights from face.*/ - weight = 0; + f_index = mf->v4 ? 3 : 2; + weight = 0.0f; do { v_index = (&mf->v1)[f_index]; weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); @@ -928,7 +935,7 @@ static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGro /* Copy weight that are not NULL including weight value 0. In relevant cases, existing weights are * overwritten prior to this. See the "Clear weights." step above.*/ - if (weight > 0) { + if (weight > 0.0f) { dw_dst = defvert_verify_index(*dv_dst, index_dst); vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); } @@ -1087,6 +1094,7 @@ static void ED_vgroup_nr_vert_add(Object *ob, /* we checked if the vertex was added before so no need to test again, simply add */ defvert_add_index_notest(dv, def_nr, weight); + break; } } } @@ -2917,6 +2925,17 @@ static int vertex_group_poll(bContext *C) { Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; + + return (ob && !ob->id.lib && + data && !data->lib && + OB_TYPE_SUPPORT_VGROUP(ob->type) && + ob->defbase.first); +} + +static int vertex_group_supported_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib); } @@ -2924,9 +2943,21 @@ static int vertex_group_mesh_poll(bContext *C) { Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; + + return (ob && !ob->id.lib && + data && !data->lib && + ob->type == OB_MESH && + ob->defbase.first); +} + +static int vertex_group_mesh_supported_poll(bContext *C) +{ + Object *ob = ED_object_context(C); + ID *data = (ob) ? ob->data : NULL; return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib); } + static int UNUSED_FUNCTION(vertex_group_poll_edit) (bContext *C) { Object *ob = ED_object_context(C); @@ -2966,7 +2997,7 @@ static int vertex_group_vert_select_unlocked_poll(bContext *C) return 0; } - if (ob->actdef != -1) { + if (ob->actdef != 0) { bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1); if (dg) { return !(dg->flag & DG_LOCK_WEIGHT); @@ -3011,7 +3042,7 @@ void OBJECT_OT_vertex_group_add(wmOperatorType *ot) ot->description = "Add a new vertex group to the active object"; /* api callbacks */ - ot->poll = vertex_group_poll; + ot->poll = vertex_group_supported_poll; ot->exec = vertex_group_add_exec; /* flags */ @@ -3039,7 +3070,7 @@ void OBJECT_OT_vertex_group_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_remove"; - ot->description = "Delete the active vertex group"; + ot->description = "Delete the active or all vertex groups from the active object"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3423,7 +3454,8 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", "Lock action to execute on vertex groups"); + RNA_def_enum(ot->srna, "action", vgroup_lock_actions, VGROUP_TOGGLE, "Action", + "Lock action to execute on vertex groups"); } static int vertex_group_invert_exec(bContext *C, wmOperator *op) @@ -3559,7 +3591,7 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) /* identifiers */ ot->name = "Clean Vertex Group"; ot->idname = "OBJECT_OT_vertex_group_clean"; - ot->description = "Remove Vertex Group assignments which aren't required"; + ot->description = "Remove vertex group assignments which are not required"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3696,7 +3728,7 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Groups to Linked"; ot->idname = "OBJECT_OT_vertex_group_copy_to_linked"; - ot->description = "Copy Vertex Groups to all users of the same Geometry data"; + ot->description = "Copy vertex groups to all users of the same geometry data"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3723,7 +3755,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)", + "Copy vertex groups to selected: %d done, %d failed (object data must have matching indices)", change, fail); } @@ -3735,7 +3767,7 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) /* identifiers */ ot->name = "Copy Vertex Group to Selected"; ot->idname = "OBJECT_OT_vertex_group_copy_to_selected"; - ot->description = "Copy Vertex Groups to other selected objects with matching indices"; + ot->description = "Copy vertex groups to other selected objects with matching indices"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -3749,6 +3781,10 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob_act = CTX_data_active_object(C); + + bDeformGroup *dg_act = BLI_findlink(&ob_act->defbase, (ob_act->actdef - 1)); + char dg_act_name[MAX_VGROUP_NAME]; /* may be freed so copy */ + int fail = 0; bool change = false; @@ -3756,6 +3792,17 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) WT_Method method = RNA_enum_get(op->ptr, "method"); WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "replace_mode"); + if (vertex_group_mode == WT_REPLACE_ACTIVE_VERTEX_GROUP) { + if (!dg_act) { + BKE_report(op->reports, RPT_WARNING, "Failed, active object has no active groups"); + return OPERATOR_FINISHED; /* to get the chance to make changes in the redo panel*/ + } + } + + if (dg_act) { + BLI_strncpy(dg_act_name, dg_act->name, sizeof(dg_act_name)); + } + /* Macro to loop through selected objects and perform operation depending on function, option and method.*/ CTX_DATA_BEGIN (C, Object *, ob_src, selected_editable_objects) { @@ -3767,8 +3814,11 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) continue; } else if (ob_src->type != OB_MESH) { - BKE_reportf(op->reports, RPT_WARNING, - "Skipping object '%s' only copying from meshes is supported", ob_src->id.name + 2); + /* armatures can be in pose mode so ignore them */ + if (ob_src->type != OB_ARMATURE) { + BKE_reportf(op->reports, RPT_WARNING, + "Skipping object '%s' only copying from meshes is supported", ob_src->id.name + 2); + } continue; } @@ -3777,7 +3827,14 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) case WT_REPLACE_ACTIVE_VERTEX_GROUP: { bDeformGroup *dg_src; - dg_src = BLI_findlink(&ob_src->defbase, ob_src->actdef - 1); + dg_src = defgroup_find_name(ob_src, dg_act_name); + + if (dg_src == NULL) { + BKE_reportf(op->reports, RPT_WARNING, + "Skipping object '%s' no group '%s' found", ob_src->id.name + 2, dg_act_name); + continue; + } + if (ed_vgroup_transfer_weight(ob_act, ob_src, dg_src, scene, method, replace_mode, op)) { change = true; } @@ -3808,15 +3865,30 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (change) { + + /* possible the active vertex group changed because of adding/removing */ + /* note!, dg_act may be realloc'd, only check its not NULL */ + if (dg_act) { + ED_vgroup_select_by_name(ob_act, dg_act_name); + } + else { + ED_vgroup_sync_from_pose(ob_act); + } + /* Event notifiers for correct display of data.*/ + + DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_act); /* for buttons */ WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_act); - return OPERATOR_FINISHED; } else { - BKE_report(op->reports, RPT_WARNING, "Failed, no other selected objects with vertex groups found."); - return OPERATOR_CANCELLED; + if (op->reports->list.first == NULL) { + BKE_report(op->reports, RPT_WARNING, "Failed, no other selected objects with vertex groups found"); + } + + return OPERATOR_FINISHED; /* to get the chance to make changes in the redo panel */ } } @@ -3829,7 +3901,7 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) ot->description = "Transfer weight paint to active from selected mesh"; /* API callbacks.*/ - ot->poll = vertex_group_mesh_poll; + ot->poll = vertex_group_mesh_supported_poll; ot->exec = vertex_group_transfer_weight_exec; /* Flags.*/ @@ -3837,7 +3909,7 @@ void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) /* Properties.*/ /* TODO, use vgroup_operator_subset_select_props for group_select_mode */ - ot->prop = RNA_def_enum(ot->srna, "group_select_mode", WT_vertex_group_mode_item, WT_REPLACE_ACTIVE_VERTEX_GROUP, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "group_select_mode", WT_vertex_group_mode_item, WT_REPLACE_ALL_VERTEX_GROUPS, "Group", ""); ot->prop = RNA_def_enum(ot->srna, "method", WT_method_item, WT_BY_NEAREST_FACE, "Method", ""); ot->prop = RNA_def_enum(ot->srna, "replace_mode", WT_replace_mode_item, WT_REPLACE_ALL_WEIGHTS, "Replace", ""); } @@ -4033,7 +4105,7 @@ void OBJECT_OT_vertex_group_sort(wmOperatorType *ot) { ot->name = "Sort Vertex Groups"; ot->idname = "OBJECT_OT_vertex_group_sort"; - ot->description = "Sorts vertex groups alphabetically"; + ot->description = "Sort vertex groups alphabetically"; /* api callbacks */ ot->poll = vertex_group_poll; @@ -4177,12 +4249,12 @@ static bool check_vertex_group_accessible(wmOperator *op, Object *ob, int def_nr bDeformGroup *dg = BLI_findlink(&ob->defbase, def_nr); if (!dg) { - BKE_report(op->reports, RPT_ERROR, "Invalid Weight Group Index"); + BKE_report(op->reports, RPT_ERROR, "Invalid vertex group index"); return false; } if (dg->flag & DG_LOCK_WEIGHT) { - BKE_report(op->reports, RPT_ERROR, "Weight Group is locked"); + BKE_report(op->reports, RPT_ERROR, "Vertex group is locked"); return false; } @@ -4210,9 +4282,9 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot) { PropertyRNA *prop; - ot->name = "Paste weight to Selected"; + ot->name = "Paste Weight to Selected"; ot->idname = "OBJECT_OT_vertex_weight_paste"; - ot->description = "Copy this group's weight to other selected verts (disabled if vertex Group is locked)"; + ot->description = "Copy this group's weight to other selected verts (disabled if vertex group is locked)"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4222,7 +4294,7 @@ void OBJECT_OT_vertex_weight_paste(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4249,7 +4321,7 @@ void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot) ot->name = "Delete Weight"; ot->idname = "OBJECT_OT_vertex_weight_delete"; - ot->description = "Delete this weight from the vertex (disabled if vertex Group is locked)"; + ot->description = "Delete this weight from the vertex (disabled if vertex group is locked)"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4259,7 +4331,7 @@ void OBJECT_OT_vertex_weight_delete(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4283,7 +4355,7 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot) ot->name = "Set Active Group"; ot->idname = "OBJECT_OT_vertex_weight_set_active"; - ot->description = "Set as active Vertex Group"; + ot->description = "Set as active vertex group"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4293,7 +4365,7 @@ void OBJECT_OT_vertex_weight_set_active(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; prop = RNA_def_int(ot->srna, "weight_group", -1, -1, INT_MAX, "Weight Index", - "Index of source weight in active Weight Group", -1, INT_MAX); + "Index of source weight in active vertex group", -1, INT_MAX); RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); } @@ -4316,7 +4388,7 @@ void OBJECT_OT_vertex_weight_normalize_active_vertex(wmOperatorType *ot) ot->name = "Normalize Active"; ot->idname = "OBJECT_OT_vertex_weight_normalize_active_vertex"; - ot->description = "Normalize Active Vert Weights"; + ot->description = "Normalize active vertex's weights"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; @@ -4345,7 +4417,7 @@ void OBJECT_OT_vertex_weight_copy(wmOperatorType *ot) ot->name = "Copy Active"; ot->idname = "OBJECT_OT_vertex_weight_copy"; - ot->description = "Copy weights from Active to selected"; + ot->description = "Copy weights from active to selected"; /* api callbacks */ ot->poll = vertex_group_vert_select_mesh_poll; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 9634acd701a..5cb74e1ca09 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -294,7 +294,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf ED_update_for_newframe(CTX_data_main(C), scene, 1); /* Init surface */ - if (!dynamicPaint_createUVSurface(surface)) return 0; + if (!dynamicPaint_createUVSurface(scene, surface)) return 0; /* Loop through selected frames */ for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index f84521fabbf..d6bb394ff79 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1722,13 +1722,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { - if (select && !(key->flag & PEK_SELECT)) { - key->flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; + if (select) { + if (!(key->flag & PEK_SELECT)) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } } - else if (key->flag & PEK_SELECT) { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; + else { + if (key->flag & PEK_SELECT) { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } } } } @@ -1742,13 +1746,17 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, bool BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { - if (select && !(key->flag & PEK_SELECT)) { - key->flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; + if (select) { + if (!(key->flag & PEK_SELECT)) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } } - else if (key->flag & PEK_SELECT) { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; + else { + if (key->flag & PEK_SELECT) { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } } } } @@ -2963,14 +2971,20 @@ static void brush_puff(PEData *data, int point_index) KEY_K; float mat[4][4], imat[4][4]; - float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], ofs[3] = {0.0f, 0.0f, 0.0f}, fac=0.0f, length=0.0f; - int puff_volume = 0; - int change= 0; + float onor_prev[3]; /* previous normal (particle-space) */ + float ofs_prev[3]; /* accumulate offset for puff_volume (particle-space) */ + float co_root[3], no_root[3]; /* root location and normal (global-space) */ + float co_prev[3], co[3]; /* track key coords as we loop (global-space) */ + float fac = 0.0f, length_accum = 0.0f; + bool puff_volume = false; + bool change = false; + + zero_v3(ofs_prev); { ParticleEditSettings *pset= PE_settings(data->scene); ParticleBrushData *brush= &pset->brush[pset->brushtype]; - puff_volume = brush->flag & PE_BRUSH_DATA_PUFF_VOLUME; + puff_volume = (brush->flag & PE_BRUSH_DATA_PUFF_VOLUME) != 0; } if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { @@ -2983,6 +2997,8 @@ static void brush_puff(PEData *data, int point_index) } LOOP_KEYS { + float kco[3]; + if (k==0) { /* find root coordinate and normal on emitter */ copy_v3_v3(co, key->co); @@ -2992,12 +3008,16 @@ static void brush_puff(PEData *data, int point_index) point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL); if (point_index == -1) return; - copy_v3_v3(rootco, co); - copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]); - mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */ + copy_v3_v3(co_root, co); + copy_v3_v3(no_root, &edit->emitter_cosnos[point_index * 6 + 3]); + mul_mat3_m4_v3(data->ob->obmat, no_root); /* normal into global-space */ + normalize_v3(no_root); - normalize_v3(nor); - length= 0.0f; + if (puff_volume) { + copy_v3_v3(onor_prev, no_root); + mul_mat3_m4_v3(imat, onor_prev); /* global-space into particle space */ + normalize_v3(onor_prev); + } fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->pufffac); fac *= 0.025f; @@ -3007,16 +3027,23 @@ static void brush_puff(PEData *data, int point_index) else { /* compute position as if hair was standing up straight. * */ - copy_v3_v3(lastco, co); + float length; + copy_v3_v3(co_prev, co); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - length += len_v3v3(lastco, co); + length = len_v3v3(co_prev, co); + length_accum += length; + if ((data->select==0 || (key->flag & PEK_SELECT)) && !(key->flag & PEK_HIDE)) { - madd_v3_v3v3fl(kco, rootco, nor, length); + float dco[3]; /* delta temp var */ + + madd_v3_v3v3fl(kco, co_root, no_root, length_accum); /* blend between the current and straight position */ sub_v3_v3v3(dco, kco, co); madd_v3_v3fl(co, dco, fac); + /* keep the same distance from the root or we get glitches [#35406] */ + dist_ensure_v3_v3fl(co, co_root, length_accum); /* re-use dco to compare before and after translation and add to the offset */ copy_v3_v3(dco, key->co); @@ -3026,11 +3053,9 @@ static void brush_puff(PEData *data, int point_index) if (puff_volume) { /* accumulate the total distance moved to apply to unselected * keys that come after */ - ofs[0] += key->co[0] - dco[0]; - ofs[1] += key->co[1] - dco[1]; - ofs[2] += key->co[2] - dco[2]; + sub_v3_v3v3(ofs_prev, key->co, dco); } - change = 1; + change = true; } else { @@ -3040,7 +3065,7 @@ static void brush_puff(PEData *data, int point_index) add_v3_v3(key->co, ofs); #else /* translate (not rotate) the rest of the hair if its not selected */ - if (ofs[0] || ofs[1] || ofs[2]) { + { #if 0 /* kindof works but looks worse then whats below */ /* Move the unselected point on a vector based on the @@ -3070,11 +3095,18 @@ static void brush_puff(PEData *data, int point_index) mul_mat3_m4_v3(data->ob->obmat, onor); /* normal into worldspace */ mul_mat3_m4_v3(imat, onor); /* worldspace into particle space */ normalize_v3(onor); + } + else { + copy_v3_v3(onor, onor_prev); + } + if (!is_zero_v3(ofs_prev)) { + mul_v3_fl(onor, len_v3(ofs_prev)); - mul_v3_fl(onor, len_v3(ofs)); add_v3_v3(key->co, onor); } + + copy_v3_v3(onor_prev, onor); #endif } #endif diff --git a/source/blender/editors/render/render_intern.h b/source/blender/editors/render/render_intern.h index edd61bfc5c3..eb09606e57e 100644 --- a/source/blender/editors/render/render_intern.h +++ b/source/blender/editors/render/render_intern.h @@ -83,7 +83,7 @@ void TEXTURE_OT_envmap_clear_all(struct wmOperatorType *ot); /* render_internal.c */ void RENDER_OT_render(struct wmOperatorType *ot); -void render_view3d(struct RenderEngine *engine, const struct bContext *C); +void render_view3d_update(struct RenderEngine *engine, const struct bContext *C); void render_view3d_draw(struct RenderEngine *engine, const struct bContext *C); /* render_opengl.c uses this */ diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 09138a5523a..bc4ca82392f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -266,6 +266,7 @@ typedef struct RenderJob { SceneRenderLayer *srl; struct Object *camera_override; int lay; + bool v3d_override; short anim, write_still; Image *image; ImageUser iuser; @@ -283,7 +284,7 @@ static void render_freejob(void *rjv) } /* str is IMA_MAX_RENDER_TEXT in size */ -static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) +static void make_renderinfo_string(RenderStats *rs, Scene *scene, bool v3d_override, char *str) { char info_time_str[32]; // used to be extern to header_info.c uintptr_t mem_in_use, mmap_in_use, peak_memory; @@ -300,7 +301,9 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) /* local view */ if (rs->localview) - spos += sprintf(spos, "%s | ", IFACE_("Local View")); + spos += sprintf(spos, "%s | ", IFACE_("3D Local View")); + else if (v3d_override) + spos += sprintf(spos, "%s | ", IFACE_("3D View")); /* frame number */ spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra)); @@ -376,7 +379,7 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs) if (rr->text == NULL) rr->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"); - make_renderinfo_string(rs, rj->scene, rr->text); + make_renderinfo_string(rs, rj->scene, rj->v3d_override, rr->text); } RE_ReleaseResult(rj->re); @@ -643,7 +646,12 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even rj->reports = op->reports; if (v3d) { - rj->lay = v3d->lay; + if (rj->lay != v3d->lay) { + rj->lay = v3d->lay; + rj->v3d_override = true; + } + else if (camera_override && camera_override != scene->camera) + rj->v3d_override = true; if (v3d->localvd) rj->lay |= v3d->localvd->lay; @@ -728,11 +736,13 @@ void RENDER_OT_render(wmOperatorType *ot) #define PR_UPDATE_VIEW 1 #define PR_UPDATE_RENDERSIZE 2 #define PR_UPDATE_MATERIAL 4 +#define PR_UPDATE_DATABASE 8 typedef struct RenderPreview { /* from wmJob */ void *owner; short *stop, *do_update; + wmJob *job; Scene *scene; ScrArea *sa; @@ -743,8 +753,6 @@ typedef struct RenderPreview { RenderEngine *engine; float viewmat[4][4]; - - int keep_data; } RenderPreview; static int render_view3d_disprect(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, rcti *disprect) @@ -823,10 +831,11 @@ static void render_view3d_renderinfo_cb(void *rjp, RenderStats *rs) RenderPreview *rp = rjp; /* during render, rv3d->engine can get freed */ - if (rp->rv3d->render_engine == NULL) + if (rp->rv3d->render_engine == NULL) { *rp->stop = 1; - else if (rp->engine->text) { - make_renderinfo_string(rs, rp->scene, rp->engine->text); + } + else { + make_renderinfo_string(rs, rp->scene, false, rp->engine->text); /* make jobs timer to send notifier */ *(rp->do_update) = TRUE; @@ -845,7 +854,13 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda float clipsta, clipend, pixsize; bool orth, restore = 0; char name[32]; - + int update_flag; + + update_flag = rp->engine->job_update_flag; + rp->engine->job_update_flag = 0; + + //printf("ma %d res %d view %d db %d\n", update_flag & PR_UPDATE_MATERIAL, update_flag & PR_UPDATE_RENDERSIZE, update_flag & PR_UPDATE_VIEW, update_flag & PR_UPDATE_DATABASE); + G.is_break = FALSE; if (false == render_view3d_get_rects(rp->ar, rp->v3d, rp->rv3d, &viewplane, rp->engine, &clipsta, &clipend, &pixsize, &orth)) @@ -860,13 +875,6 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda sprintf(name, "View3dPreview %p", (void *)rp->ar); re = rp->engine->re = RE_GetRender(name); - if (rp->engine->re == NULL) { - - re = rp->engine->re = RE_NewRender(name); - - rp->keep_data = 0; - } - /* set this always, rp is different for each job */ RE_test_break_cb(re, rp, render_view3d_break); RE_display_draw_cb(re, rp, render_view3d_draw_update); @@ -874,7 +882,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda rstats = RE_GetStats(re); - if (rp->keep_data == 0 || rstats->convertdone == 0 || (rp->keep_data & PR_UPDATE_RENDERSIZE)) { + if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) { /* no osa, blur, seq, layers, etc for preview render */ rdata = rp->scene->r; rdata.mode &= ~(R_OSA | R_MBLUR | R_BORDER | R_PANORAMA); @@ -900,11 +908,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda RE_SetPixelSize(re, pixsize); - /* database free can crash on a empty Render... */ - if (rp->keep_data == 0 && rstats->convertdone) - RE_Database_Free(re); - - if (rstats->convertdone == 0) { + if ((update_flag & PR_UPDATE_DATABASE) || rstats->convertdone == 0) { unsigned int lay = rp->scene->lay; /* allow localview render for objects with lights in normal layers */ @@ -913,8 +917,20 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda else lay = rp->v3d->lay; RE_SetView(re, rp->viewmat); - + + /* copying blender data while main thread is locked, to avoid crashes */ + WM_job_main_thread_lock_acquire(rp->job); + RE_Database_Free(re); RE_Database_FromScene(re, rp->bmain, rp->scene, lay, 0); // 0= dont use camera view + WM_job_main_thread_lock_release(rp->job); + + /* do preprocessing like building raytree, shadows, volumes, SSS */ + RE_Database_Preprocess(re); + + /* conversion not completed, need to do it again */ + if (!rstats->convertdone) + rp->engine->job_update_flag |= PR_UPDATE_DATABASE; + // printf("dbase update\n"); } else { @@ -932,8 +948,6 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda /* always rotate back */ if (restore) RE_DataBase_IncrementalView(re, rp->viewmat, 1); - - rp->engine->flag &= ~RE_ENGINE_DO_UPDATE; } } @@ -944,21 +958,99 @@ static void render_view3d_free(void *customdata) MEM_freeN(rp); } -static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_data) +static bool render_view3d_flag_changed(RenderEngine *engine, const bContext *C) +{ + RegionView3D *rv3d = CTX_wm_region_view3d(C); + View3D *v3d = CTX_wm_view3d(C); + ARegion *ar = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + Render *re; + rctf viewplane; + rcti disprect; + float clipsta, clipend; + bool orth; + int job_update_flag = 0; + char name[32]; + + /* ensure render engine exists */ + re = engine->re; + + if (!re) { + sprintf(name, "View3dPreview %p", (void *)ar); + re = engine->re = RE_GetRender(name); + if (!re) + re = engine->re = RE_NewRender(name); + + engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; + } + + /* check update_flag */ + if (engine->update_flag & RE_ENGINE_UPDATE_MA) + job_update_flag |= PR_UPDATE_MATERIAL; + + if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) + job_update_flag |= PR_UPDATE_MATERIAL; + + if (engine->update_flag & RE_ENGINE_UPDATE_DATABASE) { + job_update_flag |= PR_UPDATE_DATABASE; + + /* load editmesh */ + if (scene->obedit) + ED_object_editmode_load(scene->obedit); + } + + engine->update_flag = 0; + + /* check if viewport changed */ + if (engine->last_winx != ar->winx || engine->last_winy != ar->winy) { + engine->last_winx = ar->winx; + engine->last_winy = ar->winy; + job_update_flag |= PR_UPDATE_RENDERSIZE; + } + + if (compare_m4m4(engine->last_viewmat, rv3d->viewmat, 0.00001f) == 0) { + copy_m4_m4(engine->last_viewmat, rv3d->viewmat); + job_update_flag |= PR_UPDATE_VIEW; + } + + render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); + + if (BLI_rctf_compare(&viewplane, &engine->last_viewplane, 0.00001f) == 0) { + engine->last_viewplane = viewplane; + job_update_flag |= PR_UPDATE_VIEW; + } + + render_view3d_disprect(scene, ar, v3d, rv3d, &disprect); + if (BLI_rcti_compare(&disprect, &engine->last_disprect) == 0) { + engine->last_disprect = disprect; + job_update_flag |= PR_UPDATE_RENDERSIZE; + } + + /* any changes? go ahead and rerender */ + if (job_update_flag) { + engine->job_update_flag |= job_update_flag; + return true; + } + + return false; +} + +static void render_view3d_do(RenderEngine *engine, const bContext *C) { wmJob *wm_job; RenderPreview *rp; Scene *scene = CTX_data_scene(C); - if (CTX_wm_window(C) == NULL) { - engine->flag |= RE_ENGINE_DO_UPDATE; + if (CTX_wm_window(C) == NULL) + return; + if (!render_view3d_flag_changed(engine, C)) return; - } wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), CTX_wm_region(C), "Render Preview", WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW); rp = MEM_callocN(sizeof(RenderPreview), "render preview"); - + rp->job = wm_job; + /* customdata for preview thread */ rp->scene = scene; rp->engine = engine; @@ -967,12 +1059,10 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_d rp->v3d = rp->sa->spacedata.first; rp->rv3d = CTX_wm_region_view3d(C); rp->bmain = CTX_data_main(C); - rp->keep_data = keep_data; copy_m4_m4(rp->viewmat, rp->rv3d->viewmat); - /* dont alloc in threads */ - if (engine->text == NULL) - engine->text = MEM_callocN(IMA_MAX_RENDER_TEXT, "rendertext"); + /* clear info text */ + engine->text[0] = '\0'; /* setup job */ WM_jobs_customdata_set(wm_job, rp, render_view3d_free); @@ -982,80 +1072,33 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C, int keep_d WM_jobs_start(CTX_wm_manager(C), wm_job); engine->flag &= ~RE_ENGINE_DO_UPDATE; - } /* callback for render engine , on changes */ -void render_view3d(RenderEngine *engine, const bContext *C) +void render_view3d_update(RenderEngine *engine, const bContext *C) { - render_view3d_do(engine, C, 0); -} - -static int render_view3d_changed(RenderEngine *engine, const bContext *C) -{ - ARegion *ar = CTX_wm_region(C); - Render *re; - int update = 0; - char name[32]; - - sprintf(name, "View3dPreview %p", (void *)ar); - re = RE_GetRender(name); - - if (re) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - rctf viewplane, viewplane1; - rcti disprect, disprect1; - float mat[4][4]; - float clipsta, clipend; - bool orth; - - if (engine->update_flag & RE_ENGINE_UPDATE_MA) - update |= PR_UPDATE_MATERIAL; - - if (engine->update_flag & RE_ENGINE_UPDATE_OTHER) - update |= PR_UPDATE_MATERIAL; - - engine->update_flag = 0; - - if (engine->resolution_x != ar->winx || engine->resolution_y != ar->winy) - update |= PR_UPDATE_RENDERSIZE; + /* this shouldn't be needed and causes too many database rebuilds, but we + * aren't actually tracking updates for all relevent datablocks so this is + * a catch-all for updates */ + engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; - RE_GetView(re, mat); - if (compare_m4m4(mat, rv3d->viewmat, 0.00001f) == 0) { - update |= PR_UPDATE_VIEW; - } - - render_view3d_get_rects(ar, v3d, rv3d, &viewplane, engine, &clipsta, &clipend, NULL, &orth); - RE_GetViewPlane(re, &viewplane1, &disprect1); - - if (BLI_rctf_compare(&viewplane, &viewplane1, 0.00001f) == 0) - update |= PR_UPDATE_VIEW; - - render_view3d_disprect(scene, ar, v3d, rv3d, &disprect); - if (BLI_rcti_compare(&disprect, &disprect1) == 0) - update |= PR_UPDATE_RENDERSIZE; - - if (update) - engine->flag |= RE_ENGINE_DO_UPDATE; - //if (update) - // printf("changed ma %d res %d view %d\n", update & PR_UPDATE_MATERIAL, update & PR_UPDATE_RENDERSIZE, update & PR_UPDATE_VIEW); - } - - return update; + render_view3d_do(engine, C); } void render_view3d_draw(RenderEngine *engine, const bContext *C) { Render *re = engine->re; RenderResult rres; - int keep_data = render_view3d_changed(engine, C); + char name[32]; - if (engine->flag & RE_ENGINE_DO_UPDATE) - render_view3d_do(engine, C, keep_data); - - if (re == NULL) return; + render_view3d_do(engine, C); + + if (re == NULL) { + sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C)); + re = RE_GetRender(name); + + if (re == NULL) return; + } RE_AcquireResultImage(re, &rres); @@ -1105,3 +1148,58 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C) RE_ReleaseResultImage(re); } + +void ED_viewport_render_kill_jobs(const bContext *C, bool free_database) +{ + wmWindowManager *wm = CTX_wm_manager(C); + Main *bmain = CTX_data_main(C); + bScreen *sc; + ScrArea *sa; + ARegion *ar; + + if (!wm) + return; + + /* kill all actively running jobs */ + WM_jobs_kill(wm, NULL, render_view3d_startjob); + + /* loop over 3D view render engines */ + for (sc = bmain->screen.first; sc; sc = sc->id.next) { + for (sa = sc->areabase.first; sa; sa = sa->next) { + if (sa->spacetype != SPACE_VIEW3D) + continue; + + for (ar = sa->regionbase.first; ar; ar = ar->next) { + RegionView3D *rv3d; + + if (ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d = ar->regiondata; + + if (rv3d->render_engine) { + /* free render database now before we change data, because + * RE_Database_Free will also loop over blender data */ + if (free_database) { + char name[32]; + Render *re; + + sprintf(name, "View3dPreview %p", (void *)ar); + re = RE_GetRender(name); + + if (re) + RE_Database_Free(re); + + /* tag render engine to update entire database */ + rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_DATABASE; + } + else { + /* quick shader update */ + rv3d->render_engine->update_flag |= RE_ENGINE_UPDATE_MA; + } + } + } + } + } +} + diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 13379425258..b4532e0571c 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -107,6 +107,10 @@ typedef struct OGLRender { bMovieHandle *mh; int cfrao, nfra; + /* wm vars for timer and progress cursor */ + wmWindowManager *wm; + wmWindow *win; + wmTimer *timer; /* use to check if running modal or not (invoke'd or exec'd)*/ } OGLRender; @@ -327,6 +331,9 @@ static void screen_opengl_render_apply(OGLRender *oglrender) static int screen_opengl_render_init(bContext *C, wmOperator *op) { /* new render clears all callbacks */ + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = CTX_wm_window(C); + Scene *scene = CTX_data_scene(C); ScrArea *prevsa = CTX_wm_area(C); ARegion *prevar = CTX_wm_region(C); @@ -353,7 +360,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) } /* only one render job at a time */ - if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) + if (WM_jobs_test(wm, scene, WM_JOB_TYPE_RENDER)) return 0; if (!is_view_context && scene->camera == NULL) { @@ -367,7 +374,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) } /* stop all running jobs, except screen one. currently previews frustrate Render */ - WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); + WM_jobs_kill_all_except(wm, CTX_wm_screen(C)); /* create offscreen buffer */ sizex = (scene->r.size * scene->r.xsch) / 100; @@ -381,9 +388,6 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) return 0; } - /* handle UI stuff */ - WM_cursor_wait(1); - /* allocate opengl render */ oglrender = MEM_callocN(sizeof(OGLRender), "OGLRender"); op->customdata = oglrender; @@ -441,6 +445,10 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) rr->rectf = MEM_callocN(sizeof(float) * 4 * sizex * sizey, "screen_opengl_render_init rect"); RE_ReleaseResult(oglrender->re); + /* wm vars */ + oglrender->wm = wm; + oglrender->win = win; + return 1; } @@ -458,10 +466,11 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), oglrender->timer); + WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } - WM_cursor_wait(0); + WM_cursor_restore(oglrender->win); + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); U.obcenter_dia = oglrender->obcenter_dia_back; @@ -549,6 +558,8 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) } } + WM_cursor_time(oglrender->win, scene->r.cfra); + BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); if (view_context) { @@ -713,8 +724,11 @@ static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEven oglrender = op->customdata; render_view_open(C, event->x, event->y); + /* view may be changed above (R_OUTPUT_WINDOW) */ + oglrender->win = CTX_wm_window(C); + WM_event_add_modal_handler(C, op); - oglrender->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); + oglrender->timer = WM_event_add_timer(oglrender->wm, oglrender->win, TIMER, 0.01f); return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 76fa79029fd..4bd8a7d426a 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -964,7 +964,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat br->icon_imbuf = get_brush_icon(br); - memset(sp->pr_rect, 0x888888, sp->sizex * sp->sizey * sizeof(unsigned int)); + memset(sp->pr_rect, 0x88, sp->sizex * sp->sizey * sizeof(unsigned int)); if (!(br->icon_imbuf) || !(br->icon_imbuf->rect)) return; @@ -1180,5 +1180,7 @@ void ED_preview_kill_jobs(const struct bContext *C) wmWindowManager *wm = CTX_wm_manager(C); if (wm) WM_jobs_kill(wm, NULL, common_preview_startjob); + + ED_viewport_render_kill_jobs(C, false); } diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 7a274396e86..58c244228ed 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -110,6 +110,7 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) object_add_material_slot(ob); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob); return OPERATOR_FINISHED; } @@ -146,6 +147,7 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob); return OPERATOR_FINISHED; } @@ -1064,21 +1066,21 @@ static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op) } switch (freestyle_get_modifier_type(&ptr)) { - case LS_MODIFIER_TYPE_COLOR: - BKE_remove_linestyle_color_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_ALPHA: - BKE_remove_linestyle_alpha_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_THICKNESS: - BKE_remove_linestyle_thickness_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_GEOMETRY: - BKE_remove_linestyle_geometry_modifier(lineset->linestyle, modifier); - break; - default: - BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); - return OPERATOR_CANCELLED; + case LS_MODIFIER_TYPE_COLOR: + BKE_remove_linestyle_color_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_ALPHA: + BKE_remove_linestyle_alpha_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_THICKNESS: + BKE_remove_linestyle_thickness_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + BKE_remove_linestyle_geometry_modifier(lineset->linestyle, modifier); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; } WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); @@ -1114,21 +1116,21 @@ static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op) } switch (freestyle_get_modifier_type(&ptr)) { - case LS_MODIFIER_TYPE_COLOR: - BKE_copy_linestyle_color_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_ALPHA: - BKE_copy_linestyle_alpha_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_THICKNESS: - BKE_copy_linestyle_thickness_modifier(lineset->linestyle, modifier); - break; - case LS_MODIFIER_TYPE_GEOMETRY: - BKE_copy_linestyle_geometry_modifier(lineset->linestyle, modifier); - break; - default: - BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); - return OPERATOR_CANCELLED; + case LS_MODIFIER_TYPE_COLOR: + BKE_copy_linestyle_color_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_ALPHA: + BKE_copy_linestyle_alpha_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_THICKNESS: + BKE_copy_linestyle_thickness_modifier(lineset->linestyle, modifier); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + BKE_copy_linestyle_geometry_modifier(lineset->linestyle, modifier); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; } WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); @@ -1165,21 +1167,21 @@ static int freestyle_modifier_move_exec(bContext *C, wmOperator *op) } switch (freestyle_get_modifier_type(&ptr)) { - case LS_MODIFIER_TYPE_COLOR: - BKE_move_linestyle_color_modifier(lineset->linestyle, modifier, dir); - break; - case LS_MODIFIER_TYPE_ALPHA: - BKE_move_linestyle_alpha_modifier(lineset->linestyle, modifier, dir); - break; - case LS_MODIFIER_TYPE_THICKNESS: - BKE_move_linestyle_thickness_modifier(lineset->linestyle, modifier, dir); - break; - case LS_MODIFIER_TYPE_GEOMETRY: - BKE_move_linestyle_geometry_modifier(lineset->linestyle, modifier, dir); - break; - default: - BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); - return OPERATOR_CANCELLED; + case LS_MODIFIER_TYPE_COLOR: + BKE_move_linestyle_color_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_ALPHA: + BKE_move_linestyle_alpha_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_THICKNESS: + BKE_move_linestyle_thickness_modifier(lineset->linestyle, modifier, dir); + break; + case LS_MODIFIER_TYPE_GEOMETRY: + BKE_move_linestyle_geometry_modifier(lineset->linestyle, modifier, dir); + break; + default: + BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier"); + return OPERATOR_CANCELLED; } WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene); @@ -1212,7 +1214,7 @@ void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot) #endif /* WITH_FREESTYLE */ -static int texture_slot_move(bContext *C, wmOperator *op) +static int texture_slot_move_exec(bContext *C, wmOperator *op) { ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data; @@ -1290,7 +1292,7 @@ void TEXTURE_OT_slot_move(wmOperatorType *ot) ot->description = "Move texture slots up and down"; /* api callbacks */ - ot->exec = texture_slot_move; + ot->exec = texture_slot_move_exec; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 436aef943e4..5f74bf6576a 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -539,7 +539,7 @@ void ED_render_internal_init(void) { RenderEngineType *ret = RE_engines_find("BLENDER_RENDER"); - ret->view_update = render_view3d; + ret->view_update = render_view3d_update; ret->view_draw = render_view3d_draw; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 4ddacc3254e..1f1da35f823 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -420,7 +420,7 @@ void ED_region_do_draw(bContext *C, ARegion *ar) /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); - UI_SetTheme(sa ? sa->spacetype : 0, ar->type ? ar->type->regionid : 0); + UI_SetTheme(sa ? sa->spacetype : 0, at->regionid); /* optional header info instead? */ if (ar->headerstr) { @@ -908,11 +908,19 @@ static void region_overlap_fix(ScrArea *sa, ARegion *ar) /* overlapping regions only in the following restricted cases */ static int region_is_overlap(wmWindow *win, ScrArea *sa, ARegion *ar) { - if (U.uiflag2 & USER_REGION_OVERLAP) - if (WM_is_draw_triple(win)) - if (ELEM4(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_SEQ, SPACE_CLIP)) + if (U.uiflag2 & USER_REGION_OVERLAP) { + if (WM_is_draw_triple(win)) { + if (ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ)) { if (ELEM3(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS)) return 1; + } + else if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP)) { + if (ELEM4(ar->regiontype, RGN_TYPE_TOOLS, RGN_TYPE_UI, RGN_TYPE_TOOL_PROPS, RGN_TYPE_PREVIEW)) + return 1; + } + } + } + return 0; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c70841ffe82..3066b733fc5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -649,7 +649,8 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type) sad->modifier = RNA_int_get(op->ptr, "modifier"); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); + if (type == AZONE_AREA) event.type = EVT_ACTIONZONE_AREA; else @@ -1154,7 +1155,7 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) /* execute the events */ switch (event->type) { case MOUSEMOVE: - + { x = RNA_int_get(op->ptr, "x"); y = RNA_int_get(op->ptr, "y"); @@ -1164,9 +1165,9 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) area_move_apply(C, op); break; - + } case EVT_MODAL_MAP: - + { switch (event->val) { case KM_MODAL_APPLY: area_move_exit(C, op); @@ -1182,6 +1183,8 @@ static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event) md->step = 0; break; } + break; + } } return OPERATOR_RUNNING_MODAL; @@ -2463,8 +2466,8 @@ static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event) WM_event_add_notifier(C, NC_WINDOW, NULL); } } + break; } - break; case LEFTMOUSE: if (event->val == KM_RELEASE) { ED_area_tag_redraw(jd->sa1); @@ -2562,7 +2565,7 @@ static void SCREEN_OT_area_options(wmOperatorType *ot) /* ******************************* */ -static int spacedata_cleanup(bContext *C, wmOperator *op) +static int spacedata_cleanup_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); bScreen *screen; @@ -2594,7 +2597,7 @@ static void SCREEN_OT_spacedata_cleanup(wmOperatorType *ot) ot->idname = "SCREEN_OT_spacedata_cleanup"; /* api callbacks */ - ot->exec = spacedata_cleanup; + ot->exec = spacedata_cleanup_exec; ot->poll = WM_operator_winactive; } @@ -3182,7 +3185,7 @@ static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEv sound_seek_scene(bmain, scene); /* since we follow drawflags, we can't send notifier but tag regions ourselves */ - ED_update_for_newframe(CTX_data_main(C), scene, 1); + ED_update_for_newframe(bmain, scene, 1); for (window = wm->windows.first; window; window = window->next) { for (sa = window->screen->areabase.first; sa; sa = sa->next) { @@ -3367,7 +3370,7 @@ static void SCREEN_OT_animation_cancel(wmOperatorType *ot) * poll() has to be filled in by user for context */ #if 0 -static int border_select_do(bContext *C, wmOperator *op) +static int border_select_exec(bContext *C, wmOperator *op) { int event_type = RNA_int_get(op->ptr, "event_type"); @@ -3388,7 +3391,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot) ot->idname = "SCREEN_OT_border_select"; /* api callbacks */ - ot->exec = border_select_do; + ot->exec = border_select_exec; ot->invoke = WM_border_select_invoke; ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 3db0bd61f03..db6380e920f 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -154,7 +154,7 @@ static void partialvis_update_grids(Object *ob, { CCGElem **grids; CCGKey key; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int any_visible = 0; int *grid_indices, totgrid, any_changed, i; @@ -171,7 +171,7 @@ static void partialvis_update_grids(Object *ob, for (i = 0; i < totgrid; i++) { int any_hidden = 0; int g = grid_indices[i], x, y; - BLI_bitmap gh = grid_hidden[g]; + BLI_bitmap *gh = grid_hidden[g]; if (!gh) { switch (action) { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 553a5cbe9ac..db55dc271f1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -245,7 +245,8 @@ typedef struct ProjPaintState { float normal_angle_inner; float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */ - short is_ortho; + bool do_face_sel; /* quick access to (me->editflag & ME_EDIT_PAINT_FACE_SEL) */ + bool is_ortho; bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */ bool is_texbrush; /* only to avoid running */ bool is_maskbrush; /* mask brush is applied before masking */ @@ -2809,22 +2810,32 @@ static void project_paint_begin(ProjPaintState *ps) Image *tpage_last = NULL, *tpage; /* Face vars */ + MPoly *mpoly_orig; MFace *mf; MTFace *tf; int a, i; /* generic looping vars */ int image_index = -1, face_index; + + /* double lookup */ + const int *index_mf_to_mpoly = NULL; + const int *index_mp_to_orig = NULL; + MVert *mv; MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush); + bool reset_threads = false; + /* ---- end defines ---- */ if (ps->source == PROJ_SRC_VIEW) ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */ + ps->do_face_sel = ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) != 0); + /* paint onto the derived mesh */ /* Workaround for subsurf selection, try the display mesh first */ @@ -2833,12 +2844,17 @@ static void project_paint_begin(ProjPaintState *ps) ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE); ps->dm_release = TRUE; } - else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) { + else if (ps->ob->derivedFinal && + CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE) && + (ps->do_face_sel == false || CustomData_has_layer(&ps->ob->derivedFinal->polyData, CD_ORIGINDEX))) + { ps->dm = ps->ob->derivedFinal; ps->dm_release = FALSE; } else { - ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE); + ps->dm = mesh_get_derived_final( + ps->scene, ps->ob, + ps->scene->customdata_mask | CD_MASK_MTFACE | (ps->do_face_sel ? CD_ORIGINDEX : 0)); ps->dm_release = TRUE; } @@ -2858,6 +2874,20 @@ static void project_paint_begin(ProjPaintState *ps) ps->dm_totvert = ps->dm->getNumVerts(ps->dm); ps->dm_totface = ps->dm->getNumTessFaces(ps->dm); + if (ps->do_face_sel) { + index_mf_to_mpoly = ps->dm->getTessFaceDataArray(ps->dm, CD_ORIGINDEX); + index_mp_to_orig = ps->dm->getPolyDataArray(ps->dm, CD_ORIGINDEX); + if (index_mf_to_mpoly == NULL) { + index_mp_to_orig = NULL; + } + else { + mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; + } + } + else { + mpoly_orig = NULL; + } + /* use clone mtface? */ @@ -3064,6 +3094,10 @@ static void project_paint_begin(ProjPaintState *ps) /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */ + if (ps->buckets_x > PROJ_BUCKET_RECT_MAX || ps->buckets_y > PROJ_BUCKET_RECT_MAX) { + reset_threads = true; + } + /* really high values could cause problems since it has to allocate a few * (ps->buckets_x*ps->buckets_y) sized arrays */ CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX); @@ -3089,6 +3123,11 @@ static void project_paint_begin(ProjPaintState *ps) ps->thread_tot = BKE_scene_num_threads(ps->scene); + /* workaround for #35057, disable threading if diameter is less than is possible for + * optimum bucket number generation */ + if (reset_threads) + ps->thread_tot = 1; + for (a = 0; a < ps->thread_tot; a++) { ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena"); } @@ -3118,8 +3157,8 @@ static void project_paint_begin(ProjPaintState *ps) } } - for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) { + bool is_face_sel; #ifndef PROJ_DEBUG_NOSEAMBLEED /* add face user if we have bleed enabled, set the UV seam flags later */ @@ -3134,10 +3173,23 @@ static void project_paint_begin(ProjPaintState *ps) } #endif - tpage = project_paint_face_image(ps, ps->dm_mtface, face_index); - - if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) { + if (ps->do_face_sel) { + int orig_index; + if (index_mp_to_orig && ((orig_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, + face_index))) != ORIGINDEX_NONE) + { + MPoly *mp = &mpoly_orig[orig_index]; + is_face_sel = ((mp->flag & ME_FACE_SEL) != 0); + } + else { + is_face_sel = ((mf->flag & ME_FACE_SEL) != 0); + } + } + else { + is_face_sel = true; + } + if (is_face_sel && (tpage = project_paint_face_image(ps, ps->dm_mtface, face_index))) { float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL; v1coSS = ps->screenCoords[mf->v1]; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 6de6734f975..bdf542526ee 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -695,6 +695,7 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_CANCELLED; } + break; case XKEY: if (event->val == KM_PRESS) { @@ -846,7 +847,7 @@ static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot) } -static int stencil_reset_transform(bContext *C, wmOperator *op) +static int stencil_reset_transform_exec(bContext *C, wmOperator *op) { Paint *paint = BKE_paint_get_active_from_context(C); Brush *br = BKE_paint_brush(paint); @@ -888,7 +889,7 @@ static void BRUSH_OT_stencil_reset_transform(wmOperatorType *ot) ot->idname = "BRUSH_OT_stencil_reset_transform"; /* api callbacks */ - ot->exec = stencil_reset_transform; + ot->exec = stencil_reset_transform_exec; ot->poll = stencil_control_poll; /* flags */ diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index d82606f52f0..576bbecb561 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -540,8 +540,9 @@ bool paint_supports_dynamic_size(Brush *br, PaintMode mode) case PAINT_SCULPT: if (sculpt_is_grab_tool(br)) return false; + break; default: - ; + break; } return true; } @@ -559,8 +560,9 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode) case PAINT_SCULPT: if (sculpt_is_grab_tool(br)) return false; + break; default: - ; + break; } return true; } @@ -575,9 +577,10 @@ bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode) case PAINT_SCULPT: if (sculpt_is_grab_tool(br)) return false; + break; default: - ; - } + break; + } return true; } diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 8db9215a376..3ecde56b5d0 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -333,7 +333,7 @@ int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index, /* sample only on the exact position */ *index = view3d_sample_backbuf(vc, mval[0], mval[1]); - if ((*index) <= 0 || (*index) > (unsigned int)totface) { + if ((*index) == 0 || (*index) > (unsigned int)totface) { return 0; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 173a76a54e8..3ac3564ed45 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -380,11 +380,9 @@ static int wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active) flip_side_name(name, defgroup->name, FALSE); mirrdef = defgroup_name_index(ob, name); if (mirrdef == -1) { - int olddef = ob->actdef; /* tsk, ED_vgroup_add sets the active defgroup */ - if (ED_vgroup_add_name(ob, name)) { + if (BKE_defgroup_new(ob, name)) { mirrdef = BLI_countlist(&ob->defbase) - 1; } - ob->actdef = olddef; } /* curdef should never be NULL unless this is @@ -2027,7 +2025,7 @@ static void do_weight_paint_vertex( /* *************** set wpaint operator ****************** */ -static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */ +static int wpaint_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* toggle */ { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); @@ -2049,8 +2047,6 @@ static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */ DAG_id_tag_update(&me->id, 0); if (ob->mode & OB_MODE_WEIGHT_PAINT) { - Object *par; - if (wp == NULL) wp = scene->toolsettings->wpaint = new_vpaint(1); @@ -2059,14 +2055,7 @@ static int set_wpaint(bContext *C, wmOperator *UNUSED(op)) /* toggle */ mesh_octree_table(ob, NULL, NULL, 's'); - /* verify if active weight group is also active bone */ - par = modifiers_isDeformedByArmature(ob); - if (par && (par->mode & OB_MODE_POSE)) { - bArmature *arm = par->data; - - if (arm->act_bone) - ED_vgroup_select_by_name(ob, arm->act_bone->name); - } + ED_vgroup_sync_from_pose(ob); } else { mesh_octree_table(NULL, NULL, NULL, 'e'); @@ -2107,7 +2096,7 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot) ot->description = "Toggle weight paint mode in 3D view"; /* api callbacks */ - ot->exec = set_wpaint; + ot->exec = wpaint_mode_toggle_exec; ot->poll = paint_poll_test; /* flags */ @@ -2653,7 +2642,7 @@ void PAINT_OT_weight_set(wmOperatorType *ot) /* ************ set / clear vertex paint mode ********** */ -static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ +static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) /* toggle */ { Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); @@ -2684,7 +2673,7 @@ static int set_vpaint(bContext *C, wmOperator *op) /* toggle */ ob->mode |= OB_MODE_VERTEX_PAINT; /* Turn off weight painting */ if (ob->mode & OB_MODE_WEIGHT_PAINT) - set_wpaint(C, op); + wpaint_mode_toggle_exec(C, op); if (vp == NULL) vp = scene->toolsettings->vpaint = new_vpaint(0); @@ -2711,7 +2700,7 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) ot->description = "Toggle the vertex paint mode in 3D view"; /* api callbacks */ - ot->exec = set_vpaint; + ot->exec = vpaint_mode_toggle_exec; ot->poll = paint_poll_test; /* flags */ @@ -3424,7 +3413,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) ED_view3d_init_mats_rv3d(ob, ar->regiondata); - dm->foreachMappedVert(dm, gradientVert__mapFunc, &data); + dm->foreachMappedVert(dm, gradientVert__mapFunc, &data, DM_FOREACH_NOP); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_proj.c b/source/blender/editors/sculpt_paint/paint_vertex_proj.c index 2d5de80efeb..4c06cb8ea0d 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_proj.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_proj.c @@ -107,7 +107,7 @@ static void vpaint_proj_dm_map_cosnos_init(Scene *scene, Object *ob, if (dm->foreachMappedVert) { memset(vp_handle->vcosnos, 0, sizeof(DMCoNo) * me->totvert); - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle); + dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_init__map_cb, vp_handle, DM_FOREACH_USE_NORMAL); } else { DMCoNo *v_co_no = vp_handle->vcosnos; @@ -183,7 +183,7 @@ static void vpaint_proj_dm_map_cosnos_update(struct VertProjHandle *vp_handle, if (LIKELY(dm->foreachMappedVert)) { fill_vn_fl(vp_handle->dists, me->totvert, FLT_MAX); - dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update); + dm->foreachMappedVert(dm, vpaint_proj_dm_map_cosnos_update__map_cb, &vp_update, DM_FOREACH_USE_NORMAL); } dm->release(dm); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 8e2a29964ee..4b7c2995ea7 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -1177,6 +1177,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, case SCULPT_DISP_DIR_AREA: calc_area_normal(sd, ob, an, nodes, totnode); + break; default: break; @@ -1528,7 +1529,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no float *tmpgrid_mask, *tmprow_mask; int v1, v2, v3, v4; int thread_num; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int *grid_indices, totgrid, gridsize, i, x, y; sculpt_brush_test_init(ss, &test); @@ -1553,7 +1554,7 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no for (i = 0; i < totgrid; ++i) { int gi = grid_indices[i]; - BLI_bitmap gh = grid_hidden[gi]; + BLI_bitmap *gh = grid_hidden[gi]; data = griddata[gi]; adj = &gridadj[gi]; @@ -2457,6 +2458,7 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn case SCULPT_DISP_DIR_AREA: calc_area_normal_and_flatten_center(sd, ob, nodes, totnode, an, fc); + break; default: break; @@ -3534,7 +3536,14 @@ int sculpt_mode_poll(bContext *C) int sculpt_mode_poll_view3d(bContext *C) { - return (sculpt_mode_poll(C) && CTX_wm_region_view3d(C)); + return (sculpt_mode_poll(C) && + CTX_wm_region_view3d(C)); +} + +int sculpt_poll_view3d(bContext *C) +{ + return (sculpt_poll(C) && + CTX_wm_region_view3d(C)); } int sculpt_poll(bContext *C) @@ -4514,7 +4523,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) /**** Reset the copy of the mesh that is being sculpted on (currently just for the layer brush) ****/ -static int sculpt_set_persistent_base(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) { SculptSession *ss = CTX_data_active_object(C)->sculpt; @@ -4535,7 +4544,7 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot) ot->description = "Reset the copy of the mesh that is being sculpted on"; /* api callbacks */ - ot->exec = sculpt_set_persistent_base; + ot->exec = sculpt_set_persistent_base_exec; ot->poll = sculpt_mode_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -4579,14 +4588,21 @@ void sculpt_dynamic_topology_enable(bContext *C) Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; Mesh *me = ob->data; + const BMAllocTemplate allocsize = {me->totvert, + me->totedge, + me->totloop, + me->totpoly}; sculpt_pbvh_clear(ob); ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags & SCULPT_DYNTOPO_SMOOTH_SHADING); + /* Dynamic topology doesn't ensure selection state is valid, so remove [#36280] */ + BKE_mesh_mselect_clear(me); + /* Create triangles-only BMesh */ - ss->bm = BM_mesh_create(&bm_mesh_allocsize_default); + ss->bm = BM_mesh_create(&allocsize); BM_mesh_bm_from_me(ss->bm, me, true, true, ob->shapenr); sculpt_dynamic_topology_triangulate(ss->bm); @@ -4645,13 +4661,18 @@ void sculpt_dynamic_topology_disable(bContext *C, sculptsession_bm_to_me(ob, TRUE); } - BM_mesh_free(ss->bm); - /* Clear data */ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; - ss->bm = NULL; - BM_log_free(ss->bm_log); - ss->bm_log = NULL; + + /* typically valid but with global-undo they can be NULL, [#36234] */ + if (ss->bm) { + BM_mesh_free(ss->bm); + ss->bm = NULL; + } + if (ss->bm_log) { + BM_log_free(ss->bm_log); + ss->bm_log = NULL; + } /* Refresh */ sculpt_update_after_dynamic_topology_toggle(C); @@ -4879,7 +4900,7 @@ int ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) return ret; } -static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_mode_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); @@ -4951,7 +4972,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op)) BKE_paint_init(&ts->sculpt->paint, PAINT_CURSOR_SCULPT); - paint_cursor_start(C, sculpt_mode_poll_view3d); + paint_cursor_start(C, sculpt_poll_view3d); } WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); @@ -4967,7 +4988,7 @@ static void SCULPT_OT_sculptmode_toggle(wmOperatorType *ot) ot->description = "Toggle sculpt mode in 3D view"; /* api callbacks */ - ot->exec = sculpt_toggle_mode; + ot->exec = sculpt_mode_toggle_exec; ot->poll = ED_operator_object_active_editable_mesh; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 1060999e13f..d904ec3bc96 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -56,7 +56,9 @@ struct MultiresModifierData *sculpt_multires_active(struct Scene *scene, struct int sculpt_mode_poll(struct bContext *C); int sculpt_mode_poll_view3d(struct bContext *C); +/* checks for a brush, not just sculpt mode */ int sculpt_poll(struct bContext *C); +int sculpt_poll_view3d(struct bContext *C); void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, int need_pmap, int need_mask); @@ -98,14 +100,14 @@ typedef struct SculptUndoNode { /* non-multires */ int maxvert; /* to verify if totvert it still the same */ int *index; /* to restore into right location */ - BLI_bitmap vert_hidden; + BLI_bitmap *vert_hidden; /* multires */ int maxgrid; /* same for grid */ int gridsize; /* same for grid */ int totgrid; /* to restore into right location */ int *grids; /* to restore into right location */ - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; /* bmesh */ struct BMLogEntry *bm_entry; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 2cc09ea2aa9..8861777f326 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -210,10 +210,10 @@ static int sculpt_undo_restore_hidden(bContext *C, DerivedMesh *dm, } } else if (unode->maxgrid && dm->getGridData) { - BLI_bitmap *grid_hidden = dm->getGridHidden(dm); + BLI_bitmap **grid_hidden = dm->getGridHidden(dm); for (i = 0; i < unode->totgrid; i++) { - SWAP(BLI_bitmap, + SWAP(BLI_bitmap *, unode->grid_hidden[i], grid_hidden[unode->grids[i]]); @@ -531,7 +531,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode) { PBVHNode *node = unode->node; - BLI_bitmap *grid_hidden; + BLI_bitmap **grid_hidden; int i, *grid_indices, totgrid; grid_hidden = BKE_pbvh_grid_hidden(pbvh); @@ -539,7 +539,7 @@ static void sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL, NULL); - unode->grid_hidden = MEM_mapallocN(sizeof(BLI_bitmap) * totgrid, + unode->grid_hidden = MEM_mapallocN(sizeof(*unode->grid_hidden) * totgrid, "unode->grid_hidden"); for (i = 0; i < totgrid; i++) { diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 4b1954c8889..b5f6fa9a23e 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -226,39 +226,35 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) { /* reddish color from NLA */ UI_ThemeColor4(TH_ANIM_ACTIVE); + break; } - break; - case ANIMTYPE_SCENE: case ANIMTYPE_OBJECT: { if (sel) glColor4ub(col1b[0], col1b[1], col1b[2], 0x45); else glColor4ub(col1b[0], col1b[1], col1b[2], 0x22); + break; } - break; - case ANIMTYPE_FILLACTD: case ANIMTYPE_DSSKEY: case ANIMTYPE_DSWOR: { if (sel) glColor4ub(col2b[0], col2b[1], col2b[2], 0x45); else glColor4ub(col2b[0], col2b[1], col2b[2], 0x22); + break; } - break; - case ANIMTYPE_GROUP: { if (sel) glColor4ub(col1a[0], col1a[1], col1a[2], 0x22); else glColor4ub(col2a[0], col2a[1], col2a[2], 0x22); + break; } - break; - default: { if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22); else glColor4ub(col2[0], col2[1], col2[2], 0x22); + break; } - break; } /* draw region twice: firstly backdrop, then the current range */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 803e7b71c77..7c9d867aad6 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -231,11 +231,12 @@ void ACTION_OT_markers_make_local(wmOperatorType *ot) /* *************************** Calculate Range ************************** */ /* Get the min/max keyframes*/ -static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel) +static bool get_keyframe_extents(bAnimContext *ac, float *min, float *max, const short onlySel) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; + bool found = false; /* get data to filter, from Action or Dopesheet */ /* XXX: what is sel doing here?! @@ -261,6 +262,7 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const const float framenum = (float)gpf->framenum; *min = min_ff(*min, framenum); *max = max_ff(*max, framenum); + found = true; } } else if (ale->datatype == ALE_MASKLAY) { @@ -275,6 +277,7 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const const float framenum = (float)masklay_shape->frame; *min = min_ff(*min, framenum); *max = max_ff(*max, framenum); + found = true; } } else { @@ -282,16 +285,18 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const float tmin, tmax; /* get range and apply necessary scaling before processing */ - calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE); + if (calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE)) { - if (adt) { - tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP); - tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP); - } + if (adt) { + tmin = BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP); + tmax = BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP); + } - /* try to set cur using these values, if they're more extreme than previously set values */ - *min = min_ff(*min, tmin); - *max = max_ff(*max, tmax); + /* try to set cur using these values, if they're more extreme than previously set values */ + *min = min_ff(*min, tmin); + *max = max_ff(*max, tmax); + found = true; + } } } @@ -309,6 +314,8 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const *max = 100; } } + + return found; } /* ****************** Automatic Preview-Range Operator ****************** */ @@ -357,11 +364,12 @@ void ACTION_OT_previewrange_set(wmOperatorType *ot) /* ****************** View-All Operator ****************** */ -static int actkeys_viewall(bContext *C, const short onlySel) +static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xaxis) { bAnimContext ac; View2D *v2d; float extra; + bool found; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) @@ -369,15 +377,20 @@ static int actkeys_viewall(bContext *C, const short onlySel) v2d = &ac.ar->v2d; /* set the horizontal range, with an extra offset so that the extreme keys will be in view */ - get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, onlySel); + found = get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax, only_sel); + + if (only_sel && (found == false)) + return OPERATOR_CANCELLED; extra = 0.1f * BLI_rctf_size_x(&v2d->cur); v2d->cur.xmin -= extra; v2d->cur.xmax += extra; /* set vertical range */ - v2d->cur.ymax = 0.0f; - v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask); + if (only_xaxis == false) { + v2d->cur.ymax = 0.0f; + v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask); + } /* do View2D syncing */ UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY); @@ -393,13 +406,13 @@ static int actkeys_viewall(bContext *C, const short onlySel) static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op)) { /* whole range */ - return actkeys_viewall(C, FALSE); + return actkeys_viewall(C, false, false); } static int actkeys_viewsel_exec(bContext *C, wmOperator *UNUSED(op)) { /* only selected */ - return actkeys_viewall(C, TRUE); + return actkeys_viewall(C, true, true); } void ACTION_OT_view_all(wmOperatorType *ot) diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index eb755e162a3..9d124cf08ee 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -1079,26 +1079,26 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ { Scene *scene = (Scene *)ale->key_data; scene_to_keylist(ads, scene, &anim_keys, NULL); + break; } - break; case ALE_OB: { Object *ob = (Object *)ale->key_data; ob_to_keylist(ads, ob, &anim_keys, NULL); + break; } - break; case ALE_ACT: { bAction *act = (bAction *)ale->key_data; action_to_keylist(adt, act, &anim_keys, NULL); + break; } - break; case ALE_FCURVE: { FCurve *fcu = (FCurve *)ale->key_data; fcurve_to_keylist(adt, fcu, &anim_keys, NULL); + break; } - break; } } else if (ale->type == ANIMTYPE_SUMMARY) { diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index 7b0ff5a656f..a89a02b7e01 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -304,6 +304,7 @@ static void action_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa default: if (wmn->data == ND_KEYS) ED_region_tag_redraw(ar); + break; } } @@ -351,6 +352,7 @@ static void action_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), default: if (wmn->data == ND_KEYS) ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index b01f653837c..d32be692558 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -266,6 +266,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier * break; case ND_POSE: buttons_area_redraw(sa, BCONTEXT_DATA); + break; case ND_BONE_ACTIVE: case ND_BONE_SELECT: buttons_area_redraw(sa, BCONTEXT_BONE); @@ -292,6 +293,7 @@ static void buttons_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier * buttons_area_redraw(sa, BCONTEXT_OBJECT); buttons_area_redraw(sa, BCONTEXT_DATA); buttons_area_redraw(sa, BCONTEXT_PHYSICS); + break; case ND_SHADING: case ND_SHADING_DRAW: case ND_SHADING_LINKS: diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 7a6da5d8896..de19df9abe2 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -50,6 +50,7 @@ #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_threads.h" +#include "BLI_string.h" #include "BLF_translation.h" @@ -250,13 +251,13 @@ static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) clip = ED_space_clip_get_clip(sc); if (clip) { - strncpy(path, clip->name, sizeof(path)); + BLI_strncpy(path, clip->name, sizeof(path)); BLI_path_abs(path, G.main->name); BLI_parent_dir(path); } else { - strncpy(path, U.textudir, sizeof(path)); + BLI_strncpy(path, U.textudir, sizeof(path)); } if (RNA_struct_property_is_set(op->ptr, "files")) diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index 36cf9fc44c6..562a8584560 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -348,7 +348,7 @@ static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) switch (wmn->data) { case ND_FRAME: clip_scopes_tag_refresh(sa); - /* no break! */ + /* fall-through */ case ND_FRAME_RANGE: ED_area_tag_redraw(sa); @@ -368,7 +368,7 @@ static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) case NA_EDITED: case NA_EVALUATED: clip_stabilization_tag_refresh(sa); - /* no break! */ + /* fall-through */ case NA_SELECTED: clip_scopes_tag_refresh(sa); @@ -1019,7 +1019,7 @@ static void clip_refresh(const bContext *C, ScrArea *sa) if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) { ar_channels->flag |= RGN_FLAG_HIDDEN; ar_channels->v2d.flag &= ~V2D_IS_INITIALISED; - WM_event_remove_handlers((bContext *)C, &ar_tools->handlers); + WM_event_remove_handlers((bContext *)C, &ar_channels->handlers); view_changed = TRUE; } if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) { @@ -1353,8 +1353,8 @@ static void clip_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), // if (sc->mode == SC_MODE_MASKEDIT) { ED_region_tag_redraw(ar); + break; } - break; } break; } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 49b16a68dfc..f3d070452a5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -420,7 +420,6 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, float padding, int width, int height) { const float size = 12.0f; - int inside = 0; float min[2], max[2]; float dx, dy; @@ -445,8 +444,6 @@ static int mouse_on_slide_zone(SpaceClip *sc, MovieTrackingMarker *marker, return IN_RANGE_INCL(co[0], slide_zone[0] - dx, slide_zone[0] + dx) && IN_RANGE_INCL(co[1], slide_zone[1] - dy, slide_zone[1] + dy); - - return inside; } static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, @@ -791,8 +788,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event) if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; - /* no break! update area size */ - + /* fall-through */ case MOUSEMOVE: mdelta[0] = event->mval[0] - data->mval[0]; mdelta[1] = event->mval[1] - data->mval[1]; @@ -1230,9 +1226,9 @@ static void track_markers_freejob(void *tmv) BKE_tracking_context_sync(tmj->context); BKE_tracking_context_free(tmj->context); - MEM_freeN(tmj); - WM_main_add_notifier(NC_SCENE | ND_FRAME, tmj->scene); + + MEM_freeN(tmj); } static int track_markers_exec(bContext *C, wmOperator *op) @@ -1715,7 +1711,9 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) if (clear_active) { track = BKE_tracking_track_get_active(tracking); - BKE_tracking_track_path_clear(track, framenr, action); + if (track) { + BKE_tracking_track_path_clear(track, framenr, action); + } } else { track = tracksbase->first; @@ -3480,6 +3478,8 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) track = next; } + BKE_tracking_dopesheet_tag_update(tracking); + WM_event_add_notifier(C, NC_MOVIECLIP | ND_SELECT, clip); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index f1e707f8802..8f25ac38963 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -463,10 +463,7 @@ void folderlist_pushdir(ListBase *folderlist, const char *dir) /* create next folder element */ folder = (FolderList *)MEM_mallocN(sizeof(FolderList), "FolderList"); - folder->foldername = (char *)MEM_mallocN(sizeof(char) * (strlen(dir) + 1), "foldername"); - folder->foldername[0] = '\0'; - - BLI_strncpy(folder->foldername, dir, FILE_MAXDIR); + folder->foldername = BLI_strdup(dir); /* add it to the end of the list */ BLI_addtail(folderlist, folder); @@ -538,6 +535,7 @@ FileList *filelist_new(short type) default: p->readf = filelist_read_dir; p->filterf = is_filtered_file; + break; } return p; @@ -847,7 +845,7 @@ static void filelist_setfiletypes(struct FileList *filelist) } file->flags = file_extension_type(file->relname); - if (filelist->filter_glob && + if (filelist->filter_glob[0] && BLI_testextensie_glob(file->relname, filelist->filter_glob)) { file->flags = OPERATORFILE; @@ -996,6 +994,7 @@ void filelist_sort(struct FileList *filelist, short sort) break; case FILE_SORT_EXTENSION: qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension); + break; } filelist_filter(filelist); diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 8f9893e3bce..93a68be164a 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -74,20 +74,6 @@ /* -------------- */ -static void do_graph_region_buttons(bContext *UNUSED(C), void *UNUSED(arg), int event) -{ - //Scene *scene = CTX_data_scene(C); - - switch (event) { - - } - - /* default for now */ - //WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob); -} - -/* -------------- */ - static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu) { bAnimContext ac; @@ -162,15 +148,16 @@ static void graph_panel_properties(const bContext *C, Panel *pa) PointerRNA fcu_ptr; uiLayout *layout = pa->layout; uiLayout *col, *row, *sub; - uiBlock *block; + // uiBlock *block; // UNUSED char name[256]; int icon = 0; if (!graph_panel_context(C, &ale, &fcu)) return; - block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + // UNUSED + // block = uiLayoutGetBlock(layout); + // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); /* F-Curve pointer */ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); @@ -281,7 +268,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */ /* only show this info if there are keyframes to edit */ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) { @@ -383,8 +370,8 @@ static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int e { /* rebuild depsgraph for the new deps */ DAG_relations_tag_update(bmain); + break; } - break; } /* default for now */ @@ -841,7 +828,7 @@ void graph_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int graph_properties(bContext *C, wmOperator *UNUSED(op)) +static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = graph_has_buttons_region(sa); @@ -858,7 +845,7 @@ void GRAPH_OT_properties(wmOperatorType *ot) ot->idname = "GRAPH_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = graph_properties; + ot->exec = graph_properties_toggle_exec; ot->poll = ED_operator_graphedit_active; /* flags */ diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 765c61b5bed..ccb98dfd13d 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -436,6 +436,7 @@ static void graph_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), AReg default: if (wmn->data == ND_KEYS) ED_region_tag_redraw(ar); + break; } } @@ -518,15 +519,13 @@ static void graph_refresh(const bContext *C, ScrArea *sa) switch (sipo->mode) { case SIPO_MODE_ANIMATION: /* all animation */ { - + break; } - break; case SIPO_MODE_DRIVERS: /* drivers only */ { - + break; } - break; } /* region updates? */ @@ -563,11 +562,12 @@ static void graph_refresh(const bContext *C, ScrArea *sa) /* set color of curve here */ switch (fcu->color_mode) { case FCURVE_COLOR_CUSTOM: + { /* User has defined a custom color for this curve already (we assume it's not going to cause clashes with text colors), * which should be left alone... Nothing needs to be done here. */ break; - + } case FCURVE_COLOR_AUTO_RGB: { /* F-Curve's array index is automatically mapped to RGB values. This works best of 3-value vectors. @@ -590,9 +590,8 @@ static void graph_refresh(const bContext *C, ScrArea *sa) col[0] = 0.3f; col[1] = 0.8f; col[2] = 1.0f; break; } + break; } - break; - case FCURVE_COLOR_AUTO_RAINBOW: default: { @@ -600,8 +599,8 @@ static void graph_refresh(const bContext *C, ScrArea *sa) * of current item index + total items to determine some RGB color */ getcolor_fcurve_rainbow(i, items, fcu->color); + break; } - break; } } diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 4b1975bc058..144d2c14e9f 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -886,7 +886,7 @@ void image_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int image_properties(bContext *C, wmOperator *UNUSED(op)) +static int image_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = image_has_buttons_region(sa); @@ -903,14 +903,14 @@ void IMAGE_OT_properties(wmOperatorType *ot) ot->idname = "IMAGE_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = image_properties; + ot->exec = image_properties_toggle_exec; ot->poll = ED_operator_image_active; /* flags */ ot->flag = 0; } -static int image_scopes(bContext *C, wmOperator *UNUSED(op)) +static int image_scopes_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = image_has_scope_region(sa); @@ -927,7 +927,7 @@ void IMAGE_OT_scopes(wmOperatorType *ot) ot->idname = "IMAGE_OT_scopes"; ot->description = "Toggle display scopes panel"; - ot->exec = image_scopes; + ot->exec = image_scopes_toggle_exec; ot->poll = ED_operator_image_active; /* flags */ diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 20bbfbbf343..2da3f3adb67 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1204,7 +1204,8 @@ static char imtype_best_depth(ImBuf *ibuf, const char imtype) } } -static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, const short guess_path) +static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, Scene *scene, + const bool guess_path, const bool save_as_render) { void *lock; ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock); @@ -1253,13 +1254,20 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, /* check for empty path */ if (guess_path && simopts->filepath[0] == 0) { - if ((G.ima[0] == '/') && (G.ima[1] == '/') && (G.ima[2] == '\0')) { - BLI_strncpy(simopts->filepath, "//untitled", FILE_MAX); + const bool is_prev_save = !STREQ(G.ima, "//"); + if (save_as_render) { + if (is_prev_save) { + BLI_strncpy(simopts->filepath, G.ima, sizeof(simopts->filepath)); + } + else { + BLI_strncpy(simopts->filepath, "//untitled", sizeof(simopts->filepath)); + BLI_path_abs(simopts->filepath, G.main->name); + } } else { - BLI_strncpy(simopts->filepath, G.ima, FILE_MAX); + BLI_snprintf(simopts->filepath, sizeof(simopts->filepath), "//%s", ima->id.name + 2); + BLI_path_abs(simopts->filepath, is_prev_save ? G.ima : G.main->name); } - BLI_path_abs(simopts->filepath, G.main->name); } /* color management */ @@ -1430,7 +1438,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op) /* just in case to initialize values, * these should be set on invoke or by the caller. */ - save_image_options_init(&simopts, sima, CTX_data_scene(C), 0); + save_image_options_init(&simopts, sima, CTX_data_scene(C), false, false); save_image_options_from_op(&simopts, op); @@ -1453,13 +1461,14 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS Image *ima = ED_space_image(sima); Scene *scene = CTX_data_scene(C); SaveImageOptions simopts; + const bool save_as_render = ((ima->source == IMA_SRC_VIEWER) || (ima->flag & IMA_VIEW_AS_RENDER)); if (RNA_struct_property_is_set(op->ptr, "filepath")) return image_save_as_exec(C, op); save_image_options_defaults(&simopts); - if (save_image_options_init(&simopts, sima, scene, TRUE) == 0) + if (save_image_options_init(&simopts, sima, scene, true, save_as_render) == 0) return OPERATOR_CANCELLED; save_image_options_to_op(&simopts, op); @@ -1468,10 +1477,7 @@ static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS RNA_boolean_set(op->ptr, "copy", TRUE); } - if (ima->source == IMA_SRC_VIEWER || (ima->flag & IMA_VIEW_AS_RENDER)) - RNA_boolean_set(op->ptr, "save_as_render", TRUE); - else - RNA_boolean_set(op->ptr, "save_as_render", FALSE); + RNA_boolean_set(op->ptr, "save_as_render", save_as_render); op->customdata = MEM_mallocN(sizeof(simopts.im_format), __func__); memcpy(op->customdata, &simopts.im_format, sizeof(simopts.im_format)); @@ -1570,7 +1576,7 @@ static int image_save_exec(bContext *C, wmOperator *op) SaveImageOptions simopts; save_image_options_defaults(&simopts); - if (save_image_options_init(&simopts, sima, scene, FALSE) == 0) + if (save_image_options_init(&simopts, sima, scene, false, false) == 0) return OPERATOR_CANCELLED; save_image_options_from_op(&simopts, op); @@ -1892,6 +1898,8 @@ static int image_invert_exec(bContext *C, wmOperator *op) void IMAGE_OT_invert(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Invert Channels"; ot->idname = "IMAGE_OT_invert"; @@ -1902,10 +1910,14 @@ void IMAGE_OT_invert(wmOperatorType *ot) ot->poll = image_invert_poll; /* properties */ - RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel"); - RNA_def_boolean(ot->srna, "invert_g", 0, "Green", "Invert Green Channel"); - RNA_def_boolean(ot->srna, "invert_b", 0, "Blue", "Invert Blue Channel"); - RNA_def_boolean(ot->srna, "invert_a", 0, "Alpha", "Invert Alpha Channel"); + prop = RNA_def_boolean(ot->srna, "invert_r", 0, "Red", "Invert Red Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_g", 0, "Green", "Invert Green Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_b", 0, "Blue", "Invert Blue Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "invert_a", 0, "Alpha", "Invert Alpha Channel"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 2b106e13836..c0ef59e9e25 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -492,6 +492,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) break; } case NC_GEOM: + { switch (wmn->data) { case ND_DATA: case ND_SELECT: @@ -500,6 +501,8 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) ED_area_tag_redraw(sa); break; } + break; + } case NC_OBJECT: { Object *ob = (Object *)wmn->reference; @@ -512,6 +515,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) } break; } + break; } } } @@ -872,7 +876,7 @@ static void image_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ED_region_tag_redraw(ar); break; } - + break; } } diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index 10b935502ba..07f4b64d187 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -271,6 +271,7 @@ static void info_header_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi case NC_ID: if (wmn->action == NA_RENAME) ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index a55da0e3b2c..2c521532484 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -50,7 +50,7 @@ #include "interface_intern.h" #include "logic_intern.h" -static int logic_properties(bContext *C, wmOperator *UNUSED(op)) +static int logic_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = logic_has_buttons_region(sa); @@ -67,7 +67,7 @@ void LOGIC_OT_properties(wmOperatorType *ot) ot->description = "Toggle display properties panel"; ot->idname = "LOGIC_OT_properties"; - ot->exec = logic_properties; + ot->exec = logic_properties_toggle_exec; ot->poll = ED_operator_logic_active; /* flags */ diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index 9206f3f024a..d3bef346705 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -125,9 +125,8 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA } found = 1; + break; } - break; - case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */ case ANIMTYPE_OBJECT: case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ @@ -167,8 +166,8 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA */ found = -1; } + break; } - break; } if (found > 0) @@ -553,7 +552,7 @@ void nla_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int nla_properties(bContext *C, wmOperator *UNUSED(op)) +static int nla_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = nla_has_buttons_region(sa); @@ -570,7 +569,7 @@ void NLA_OT_properties(wmOperatorType *ot) ot->idname = "NLA_OT_properties"; ot->description = "Toggle display properties panel"; - ot->exec = nla_properties; + ot->exec = nla_properties_toggle_exec; ot->poll = ED_operator_nla_active; /* flags */ diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c index bf914a05620..c0e559a34cf 100644 --- a/source/blender/editors/space_nla/nla_channels.c +++ b/source/blender/editors/space_nla/nla_channels.c @@ -119,8 +119,8 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; case ANIMTYPE_OBJECT: { bDopeSheet *ads = (bDopeSheet *)ac->data; @@ -161,9 +161,8 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor /* notifiers - channel was selected */ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } + break; } - break; - case ANIMTYPE_FILLACTD: /* Action Expander */ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */ case ANIMTYPE_DSLAM: @@ -200,9 +199,8 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor } notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); + break; } - break; - case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)ale->data; @@ -260,8 +258,8 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor /* notifier flags - channel was selected */ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } + break; } - break; case ANIMTYPE_NLAACTION: { AnimData *adt = BKE_animdata_from_id(ale->id); @@ -316,12 +314,12 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); } } + break; } - break; - default: if (G.debug & G_DEBUG) printf("Error: Invalid channel type in mouse_nla_channels()\n"); + break; } /* free channels */ diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 5f3e1ef88e3..b4c52a5b1ca 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -307,8 +307,8 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri glVertex2f(strip->start, yminc); glEnd(); } - /* no break needed... */ - + /* fall-through */ + /* this only draws after the strip */ case NLASTRIP_EXTEND_HOLD_FORWARD: /* only need to try and draw if the next strip doesn't occur immediately after */ @@ -563,9 +563,8 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) nla_draw_strip_frames_text(nlt, strip, v2d, yminc, ymaxc); } } + break; } - break; - case ANIMTYPE_NLAACTION: { AnimData *adt = ale->adt; @@ -603,8 +602,8 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) fdrawline(v2d->cur.xmin, ymaxc - NLACHANNEL_SKIP, v2d->cur.xmax, ymaxc - NLACHANNEL_SKIP); glDisable(GL_BLEND); + break; } - break; } } @@ -684,8 +683,8 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw manually still */ do_draw = TRUE; + break; } - break; case ANIMTYPE_NLAACTION: /* NLA Action-Line */ { bAction *act = (bAction *)ale->data; @@ -698,9 +697,8 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw manually still */ do_draw = TRUE; + break; } - break; - default: /* handled by standard channel-drawing API */ // draw backdrops only... ANIM_channel_draw(ac, ale, yminc, ymaxc); @@ -725,17 +723,15 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* same as for textures */ offset = 0.7f * U.widget_unit; indent = 1; + break; } - break; - case NTREE_TEXTURE: { /* even more */ offset = U.widget_unit; indent = 1; + break; } - break; - default: /* normal will do */ offset = 0.7f * U.widget_unit; diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index e54c1e8323a..4d4f27cf1ad 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -427,6 +427,7 @@ static void nla_main_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARe default: if (wmn->data == ND_KEYS) ED_region_tag_redraw(ar); + break; } } @@ -457,10 +458,10 @@ static void nla_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), if (wmn->action == NA_RENAME) ED_region_tag_redraw(ar); break; - default: if (wmn->data == ND_KEYS) ED_region_tag_redraw(ar); + break; } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 82104d2c837..cf3c0454e6b 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -790,6 +790,12 @@ static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA node_buts_image_user(layout, C, &iuserptr, &imaptr, &iuserptr); } +static void node_shader_buts_tex_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); +} + static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) { PointerRNA imaptr = RNA_pointer_get(ptr, "image"); @@ -993,6 +999,7 @@ static void node_shader_set_butfunc(bNodeType *ntype) break; case SH_NODE_TEX_IMAGE: ntype->uifunc = node_shader_buts_tex_image; + ntype->uifuncbut = node_shader_buts_tex_image_details; break; case SH_NODE_TEX_ENVIRONMENT: ntype->uifunc = node_shader_buts_tex_environment; @@ -1062,19 +1069,10 @@ static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA * static void node_composit_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; - PointerRNA imaptr; - - node_composit_buts_image(layout, C, ptr); - - uiItemR(layout, ptr, "use_straight_alpha_output", 0, NULL, 0); + PointerRNA iuserptr; - if (!node->id) - return; - - imaptr = RNA_pointer_get(ptr, "image"); - - uiTemplateColorspaceSettings(layout, &imaptr, "colorspace_settings"); - uiItemR(layout, &imaptr, "alpha_mode", 0, NULL, 0); + RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); } static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -1389,6 +1387,7 @@ static void node_composit_buts_zcombine(uiLayout *layout, bContext *UNUSED(C), P col = uiLayoutColumn(layout, TRUE); uiItemR(col, ptr, "use_alpha", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_antialias_z", 0, NULL, ICON_NONE); } @@ -2548,6 +2547,15 @@ static void node_texture_buts_image(uiLayout *layout, bContext *C, PointerRNA *p uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); } +static void node_texture_buts_image_details(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node = ptr->data; + PointerRNA iuserptr; + + RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); + uiTemplateImage(layout, C, ptr, "image", &iuserptr, 0); +} + static void node_texture_buts_output(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "filepath", 0, "", ICON_NONE); @@ -2592,6 +2600,7 @@ static void node_texture_set_butfunc(bNodeType *ntype) case TEX_NODE_IMAGE: ntype->uifunc = node_texture_buts_image; + ntype->uifuncbut = node_texture_buts_image_details; break; case TEX_NODE_OUTPUT: @@ -2777,7 +2786,8 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, case SOCK_VECTOR: uiTemplateComponentMenu(layout, ptr, "default_value", text); break; - case SOCK_RGBA: { + case SOCK_RGBA: + { uiLayout *row = uiLayoutRow(layout, false); uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT); /* draw the socket name right of the actual button */ @@ -2785,14 +2795,14 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, uiItemL(row, text, 0); break; } - case SOCK_STRING: { + case SOCK_STRING: + { uiLayout *row = uiLayoutRow(layout, true); /* draw the socket name right of the actual button */ uiItemR(row, ptr, "default_value", 0, "", 0); uiItemL(row, text, 0); break; } - default: node_socket_button_label(C, layout, ptr, node_ptr, text); break; @@ -2806,7 +2816,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout /*int subtype = sock->typeinfo->subtype;*/ switch (type) { - case SOCK_FLOAT: { + case SOCK_FLOAT: + { uiLayout *row; uiItemR(layout, ptr, "default_value", 0, NULL, 0); row = uiLayoutRow(layout, true); @@ -2814,7 +2825,8 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout uiItemR(row, ptr, "max_value", 0, "Max", 0); break; } - case SOCK_INT: { + case SOCK_INT: + { uiLayout *row; uiItemR(layout, ptr, "default_value", 0, NULL, 0); row = uiLayoutRow(layout, true); @@ -2822,11 +2834,13 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout uiItemR(row, ptr, "max_value", 0, "Max", 0); break; } - case SOCK_BOOLEAN: { + case SOCK_BOOLEAN: + { uiItemR(layout, ptr, "default_value", 0, NULL, 0); break; } - case SOCK_VECTOR: { + case SOCK_VECTOR: + { uiLayout *row; uiItemR(layout, ptr, "default_value", UI_ITEM_R_EXPAND, NULL, 0); row = uiLayoutRow(layout, true); @@ -2834,11 +2848,13 @@ static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout uiItemR(row, ptr, "max_value", 0, "Max", 0); break; } - case SOCK_RGBA: { + case SOCK_RGBA: + { uiItemR(layout, ptr, "default_value", 0, NULL, 0); break; } - case SOCK_STRING: { + case SOCK_STRING: + { uiItemR(layout, ptr, "default_value", 0, NULL, 0); break; } diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index d5224a37358..4c40b6c412b 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -339,8 +339,6 @@ static int node_add_file_exec(bContext *C, wmOperator *op) } } - node_deselect_all(snode); - switch (snode->nodetree->type) { case NTREE_SHADER: type = SH_NODE_TEX_IMAGE; @@ -410,6 +408,69 @@ void NODE_OT_add_file(wmOperatorType *ot) RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); } +/* ****************** Add Mask Node Operator ******************* */ + +static int node_add_mask_poll(bContext *C) +{ + SpaceNode *snode = CTX_wm_space_node(C); + + return ED_operator_node_editable(C) && snode->nodetree->type == NTREE_COMPOSIT; +} + +static int node_add_mask_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + SpaceNode *snode = CTX_wm_space_node(C); + bNode *node; + ID *mask = NULL; + + /* check input variables */ + char name[MAX_ID_NAME - 2]; + RNA_string_get(op->ptr, "name", name); + mask = BKE_libblock_find_name(ID_MSK, name); + if (!mask) { + BKE_reportf(op->reports, RPT_ERROR, "Mask '%s' not found", name); + return OPERATOR_CANCELLED; + } + + ED_preview_kill_jobs(C); + + /* convert mouse coordinates to v2d space */ + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], + &snode->cursor[0], &snode->cursor[1]); + node = node_add_node(C, NULL, CMP_NODE_MASK, snode->cursor[0], snode->cursor[1]); + + if (!node) { + BKE_report(op->reports, RPT_WARNING, "Could not add a mask node"); + return OPERATOR_CANCELLED; + } + + node->id = mask; + id_us_plus(mask); + + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; +} + +void NODE_OT_add_mask(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Mask Node"; + ot->description = "Add a mask node to the current node editor"; + ot->idname = "NODE_OT_add_mask"; + + /* callbacks */ + ot->invoke = node_add_mask_invoke; + ot->poll = node_add_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_string(ot->srna, "name", "Mask", MAX_ID_NAME - 2, "Name", "Datablock name to assign"); +} + /********************** New node tree operator *********************/ static int new_node_tree_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 7068973b2bf..f95e895bef2 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -206,7 +206,7 @@ void node_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int node_properties(bContext *C, wmOperator *UNUSED(op)) +static int node_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = node_has_buttons_region(sa); @@ -230,7 +230,7 @@ void NODE_OT_properties(wmOperatorType *ot) ot->description = "Toggles the properties panel display"; ot->idname = "NODE_OT_properties"; - ot->exec = node_properties; + ot->exec = node_properties_toggle_exec; ot->poll = node_properties_poll; /* flags */ diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 7da06bcf3a6..dce04bb8c42 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -91,18 +91,18 @@ static bNodeTree *node_tree_from_ID(ID *id) short idtype = GS(id->name); switch (idtype) { - case ID_NT: - return (bNodeTree *)id; - case ID_MA: - return ((Material *)id)->nodetree; - case ID_LA: - return ((Lamp *)id)->nodetree; - case ID_WO: - return ((World *)id)->nodetree; - case ID_SCE: - return ((Scene *)id)->nodetree; - case ID_TE: - return ((Tex *)id)->nodetree; + case ID_NT: + return (bNodeTree *)id; + case ID_MA: + return ((Material *)id)->nodetree; + case ID_LA: + return ((Lamp *)id)->nodetree; + case ID_WO: + return ((World *)id)->nodetree; + case ID_SCE: + return ((Scene *)id)->nodetree; + case ID_TE: + return ((Tex *)id)->nodetree; } } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index e10cba43d71..9b48774588d 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -577,9 +577,10 @@ void snode_set_context(const bContext *C) if (!treetype || (treetype->poll && !treetype->poll(C, treetype))) { - /* invalid tree type, disable */ - snode->tree_idname[0] = '\0'; - ED_node_tree_start(snode, NULL, NULL, NULL); + /* invalid tree type, skip + * NB: not resetting the node path here, invalid bNodeTreeType + * may still be registered at a later point. + */ return; } @@ -2261,24 +2262,26 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; switch (direction) { - case 1: { /* up */ - bNodeSocket *before = iosock->prev; - BLI_remlink(lb, iosock); - if (before) - BLI_insertlinkbefore(lb, before, iosock); - else - BLI_addhead(lb, iosock); - break; - } - case 2: { /* down */ - bNodeSocket *after = iosock->next; - BLI_remlink(lb, iosock); - if (after) - BLI_insertlinkafter(lb, after, iosock); - else - BLI_addtail(lb, iosock); - break; - } + case 1: + { /* up */ + bNodeSocket *before = iosock->prev; + BLI_remlink(lb, iosock); + if (before) + BLI_insertlinkbefore(lb, before, iosock); + else + BLI_addhead(lb, iosock); + break; + } + case 2: + { /* down */ + bNodeSocket *after = iosock->next; + BLI_remlink(lb, iosock); + if (after) + BLI_insertlinkafter(lb, after, iosock); + else + BLI_addtail(lb, iosock); + break; + } } ntreeUpdateTree(CTX_data_main(C), ntree); diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index a9a17b182a4..1a2e90e5522 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -143,6 +143,7 @@ void draw_nodespace_back_pix(const struct bContext *C, struct ARegion *ar, struc bNode *node_add_node(const struct bContext *C, const char *idname, int type, float locx, float locy); void NODE_OT_add_reroute(struct wmOperatorType *ot); void NODE_OT_add_file(struct wmOperatorType *ot); +void NODE_OT_add_mask(struct wmOperatorType *ot); void NODE_OT_new_node_tree(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 2476a9b8b99..566bb1600cc 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -101,6 +101,7 @@ void node_operatortypes(void) WM_operatortype_append(NODE_OT_backimage_sample); WM_operatortype_append(NODE_OT_add_file); + WM_operatortype_append(NODE_OT_add_mask); WM_operatortype_append(NODE_OT_new_node_tree); diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c index beea4dc3183..244b222811e 100644 --- a/source/blender/editors/space_node/node_relationships.c +++ b/source/blender/editors/space_node/node_relationships.c @@ -356,7 +356,7 @@ static int node_link_viewer(const bContext *C, bNode *tonode) } -static int node_active_link_viewer(bContext *C, wmOperator *UNUSED(op)) +static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op)) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; @@ -385,7 +385,7 @@ void NODE_OT_link_viewer(wmOperatorType *ot) ot->idname = "NODE_OT_link_viewer"; /* api callbacks */ - ot->exec = node_active_link_viewer; + ot->exec = node_active_link_viewer_exec; ot->poll = composite_node_editable; /* flags */ diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index ea745c47690..e17699309ef 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -429,6 +429,7 @@ void NODE_OT_select(wmOperatorType *ot) /* api callbacks */ ot->invoke = node_select_invoke; + ot->exec = node_select_exec; ot->poll = ED_operator_node_active; /* flags */ @@ -925,7 +926,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *ar, void *arg_op) uiEndBlock(C, block); // uiButActiveOnly(C, ar, block, but); XXX using this here makes Blender hang - investigate - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index b74d1bf2ef8..83c11e69d84 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -675,23 +675,23 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, /* input not linked, show value */ if (!(input->flag & SOCK_HIDE_VALUE)) { switch (input->type) { - case SOCK_FLOAT: - case SOCK_INT: - case SOCK_BOOLEAN: - case SOCK_RGBA: - case SOCK_STRING: - row = uiLayoutRow(split, TRUE); - uiItemR(row, &inputptr, "default_value", 0, "", ICON_NONE); - break; - case SOCK_VECTOR: - row = uiLayoutRow(split, FALSE); - col = uiLayoutColumn(row, FALSE); - uiItemR(col, &inputptr, "default_value", 0, "", ICON_NONE); - break; - - default: - row = uiLayoutRow(split, FALSE); - break; + case SOCK_FLOAT: + case SOCK_INT: + case SOCK_BOOLEAN: + case SOCK_RGBA: + case SOCK_STRING: + row = uiLayoutRow(split, TRUE); + uiItemR(row, &inputptr, "default_value", 0, "", ICON_NONE); + break; + case SOCK_VECTOR: + row = uiLayoutRow(split, FALSE); + col = uiLayoutColumn(row, FALSE); + uiItemR(col, &inputptr, "default_value", 0, "", ICON_NONE); + break; + + default: + row = uiLayoutRow(split, FALSE); + break; } } else diff --git a/source/blender/editors/space_node/node_toolbar.c b/source/blender/editors/space_node/node_toolbar.c index 86da4009b17..dd5bad3f8ad 100644 --- a/source/blender/editors/space_node/node_toolbar.c +++ b/source/blender/editors/space_node/node_toolbar.c @@ -60,7 +60,7 @@ void node_toolbar_register(ARegionType *UNUSED(art)) /* ********** operator to open/close toolshelf region */ -static int node_toolbar(bContext *C, wmOperator *UNUSED(op)) +static int node_toolbar_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = node_has_tools_region(sa); @@ -84,7 +84,7 @@ void NODE_OT_toolbar(wmOperatorType *ot) ot->description = "Toggles tool shelf display"; ot->idname = "NODE_OT_toolbar"; - ot->exec = node_toolbar; + ot->exec = node_toolbar_toggle_exec; ot->poll = node_toolbar_poll; /* flags */ diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index eed8a10a1db..9e6e1e628f6 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -295,7 +295,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; } -static int backimage_zoom(bContext *C, wmOperator *op) +static int backimage_zoom_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); @@ -317,7 +317,7 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot) ot->description = "Zoom in/out the background image"; /* api callbacks */ - ot->exec = backimage_zoom; + ot->exec = backimage_zoom_exec; ot->poll = composite_node_active; /* flags */ diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 07fa6997e99..922912fa540 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -41,6 +41,7 @@ #include "BLI_math.h" #include "BKE_context.h" +#include "BKE_library.h" #include "BKE_screen.h" #include "BKE_node.h" @@ -83,6 +84,8 @@ void ED_node_tree_start(SpaceNode *snode, bNodeTree *ntree, ID *id, ID *from) BLI_strncpy(path->node_name, id->name + 2, sizeof(path->node_name)); BLI_addtail(&snode->treepath, path); + + id_us_ensure_real(&ntree->id); } /* update current tree */ @@ -116,6 +119,8 @@ void ED_node_tree_push(SpaceNode *snode, bNodeTree *ntree, bNode *gnode) BLI_addtail(&snode->treepath, path); + id_us_ensure_real(&ntree->id); + /* update current tree */ snode->edittree = ntree; @@ -387,7 +392,8 @@ static void node_area_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn switch (wmn->category) { case NC_SCENE: switch (wmn->data) { - case ND_NODES: { + case ND_NODES: + { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); bNodeTreePath *path = snode->treepath.last; /* shift view to node tree center */ @@ -629,7 +635,7 @@ static void node_main_area_draw(const bContext *C, ARegion *ar) /* ************* dropboxes ************* */ -static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +static int node_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) { if (drag->type == WM_DRAG_ID) { ID *id = (ID *)drag->poin; @@ -643,6 +649,23 @@ static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUS return 0; } +static int node_mask_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event)) +{ + if (drag->type == WM_DRAG_ID) { + ID *id = (ID *)drag->poin; + if (GS(id->name) == ID_MSK) + return 1; + } + return 0; +} + +static void node_id_drop_copy(wmDrag *drag, wmDropBox *drop) +{ + ID *id = (ID *)drag->poin; + + RNA_string_set(drop->ptr, "name", id->name + 2); +} + static void node_id_path_drop_copy(wmDrag *drag, wmDropBox *drop) { ID *id = (ID *)drag->poin; @@ -660,7 +683,8 @@ static void node_dropboxes(void) { ListBase *lb = WM_dropboxmap_find("Node Editor", SPACE_NODE, RGN_TYPE_WINDOW); - WM_dropbox_add(lb, "NODE_OT_add_file", node_drop_poll, node_id_path_drop_copy); + WM_dropbox_add(lb, "NODE_OT_add_file", node_ima_drop_poll, node_id_path_drop_copy); + WM_dropbox_add(lb, "NODE_OT_add_mask", node_mask_drop_poll, node_id_drop_copy); } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 3b769761dfb..b308bd09026 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -263,7 +263,7 @@ static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poi { bArmature *arm = (bArmature *)poin; Bone *bone = (Bone *)poin2; - if (bone && (bone->flag & BONE_HIDDEN_P)) + if (bone->flag & BONE_HIDDEN_P) bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (CTX_wm_window(C)->eventstate->ctrl) { @@ -277,7 +277,7 @@ static void restrictbutton_bone_select_cb(bContext *C, void *poin, void *poin2) { bArmature *arm = (bArmature *)poin; Bone *bone = (Bone *)poin2; - if (bone && (bone->flag & BONE_UNSELECTABLE)) + if (bone->flag & BONE_UNSELECTABLE) bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); if (CTX_wm_window(C)->eventstate->ctrl) { @@ -464,8 +464,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) ED_armature_bone_rename(obedit->data, oldname, newname); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, OBACT); } + break; } - break; case TSE_BONE: { @@ -482,8 +482,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) BLI_strncpy(bone->name, oldname, sizeof(bone->name)); ED_armature_bone_rename(ob->data, oldname, newname); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); + break; } - break; case TSE_POSE_CHANNEL: { bPoseChannel *pchan = te->directdata; @@ -499,8 +499,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) BLI_strncpy(pchan->name, oldname, sizeof(pchan->name)); ED_armature_bone_rename(ob->data, oldname, newname); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); + break; } - break; case TSE_POSEGRP: { Object *ob = (Object *)tselem->id; // id = object @@ -509,8 +509,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname) BLI_uniquename(&ob->pose->agroups, grp, CTX_DATA_(BLF_I18NCONTEXT_ID_ACTION, "Group"), '.', offsetof(bActionGroup, name), sizeof(grp->name)); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); + break; } - break; case TSE_R_LAYER: break; } @@ -539,21 +539,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide", -1, 0, 0, -1, -1, TIP_("Restrict viewport visibility (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide_select", -1, 0, 0, -1, -1, TIP_("Restrict viewport selection (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &ptr, "hide_render", -1, 0, 0, -1, -1, TIP_("Restrict rendering (Ctrl - Recursive)")); uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); @@ -570,21 +570,21 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER); bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -596,7 +596,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -611,7 +611,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -621,7 +621,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) { bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined")); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -635,14 +635,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability")); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); @@ -656,14 +656,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone); @@ -676,14 +676,14 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View")); uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone); uiButSetFlag(bt, UI_BUT_DRAG_LOCK); bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, + (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), te->ys, UI_UNIT_X, UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View")); uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone); @@ -735,7 +735,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa prop = te->directdata; if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops)))) { - uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, + uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1); } } @@ -743,7 +743,7 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa ptr = &te->rnaptr; prop = te->directdata; - uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, + uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1); } } @@ -811,7 +811,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -929,6 +929,7 @@ static void keymap_type_cb(bContext *C, void *kmi_v, void *UNUSED(arg_v)) case OL_KM_SPECIALS: kmi->type = AKEY; kmi->val = KM_PRESS; + break; } ED_region_tag_redraw(CTX_wm_region(C)); } @@ -959,7 +960,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo /* pass */ } else { - uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, + uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, te->ys + 1, butw1, UI_UNIT_Y - 1, TIP_("Assign new Operator")); } xstart += butw1 + 10; @@ -968,7 +969,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo kmi->maptype = keymap_menu_type(kmi->type); str = keymap_type_menu(); - but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, + but = uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, 0, 0, 0, 0, TIP_("Event type")); uiButSetFunc(but, keymap_type_cb, kmi, NULL); xstart += butw2 + 5; @@ -976,48 +977,48 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo /* edit actual event */ switch (kmi->maptype) { case OL_KM_KEYBOARD: - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, TIP_("Key code")); xstart += butw2 + 5; break; case OL_KM_MOUSE: str = keymap_mouse_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, TIP_("Mouse button")); xstart += butw2 + 5; break; case OL_KM_TWEAK: str = keymap_tweak_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, TIP_("Tweak gesture")); xstart += butw2 + 5; str = keymap_tweak_dir_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, + uiDefButS(block, MENU, 0, str, xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, 0, 0, 0, 0, TIP_("Tweak gesture direction")); xstart += butw2 + 5; break; } /* modifiers */ - uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, + uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, &kmi->shift, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3 + 5; - uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, + uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, + uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3; - uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, + uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, TIP_("Modifier")); xstart += butw3 + 5; - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, + uiDefKeyevtButS(block, 0, "", xstart, te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, TIP_("Key Modifier code")); xstart += butw3 + 5; /* rna property */ if (kmi->ptr && kmi->ptr->data) { - uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, + uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2; } @@ -1063,7 +1064,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa spx = te->xs + 1.8f * UI_UNIT_X; if (spx + dx + 0.5f * UI_UNIT_X > ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax - spx - 0.5f * UI_UNIT_X; - bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name, + bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, te->ys, dx + UI_UNIT_X, UI_UNIT_Y - 1, (void *)te->name, 1.0, (float)len, 0, 0, ""); uiButSetRenameFunc(bt, namebutton_cb, tselem); @@ -1252,8 +1253,6 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto } break; } - case TSE_SCRIPT_BASE: - UI_icon_draw(x, y, ICON_TEXT); break; case TSE_POSE_BASE: UI_icon_draw(x, y, ICON_ARMATURE_DATA); break; case TSE_POSE_CHANNEL: @@ -1441,8 +1440,8 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa } tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); - te->xs = (float)*offsx; - te->ys = (float)ys; + te->xs = *offsx; + te->ys = ys; te->xend = (short)*offsx + UI_UNIT_X; te->flag |= TE_ICONROW; // for click @@ -1457,13 +1456,13 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa } /* closed tree element */ -static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int *starty) +static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, int startx, int starty) { TreeElement *ten; /* store coord and continue, we need coordinates for elements outside view too */ - te->xs = (float)startx; - te->ys = (float)(*starty); + te->xs = startx; + te->ys = starty; for (ten = te->subtree.first; ten; ten = ten->next) { outliner_set_coord_tree_element(soops, ten, startx + UI_UNIT_X, starty); @@ -1657,8 +1656,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } } /* store coord and continue, we need coordinates for elements outside view too */ - te->xs = (float)startx; - te->ys = (float)*starty; + te->xs = startx; + te->ys = *starty; te->xend = startx + offsx; if (TSELEM_OPEN(tselem, soops)) { @@ -1669,7 +1668,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } else { for (ten = te->subtree.first; ten; ten = ten->next) - outliner_set_coord_tree_element(soops, te, startx, starty); + outliner_set_coord_tree_element(soops, ten, startx, *starty); *starty -= UI_UNIT_Y; } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 0a1d3a63f2c..cef5fe53407 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -219,7 +219,7 @@ static void do_item_rename(ARegion *ar, TreeElement *te, TreeStoreElem *tselem, /* do nothing */; } else if (ELEM10(tselem->type, TSE_ANIM_DATA, TSE_NLA, TSE_DEFGROUP_BASE, TSE_CONSTRAINT_BASE, TSE_MODIFIER_BASE, - TSE_SCRIPT_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) + TSE_DRIVER_BASE, TSE_POSE_BASE, TSE_POSEGRP_BASE, TSE_R_LAYER_BASE, TSE_R_PASS)) { BKE_report(reports, RPT_WARNING, "Cannot edit builtin name"); } @@ -618,7 +618,7 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op)) te = outliner_find_id(so, &so->tree, (ID *)OBACT); if (te) { /* make te->ys center of view */ - ytop = (int)(te->ys + BLI_rcti_size_y(&v2d->mask) / 2); + ytop = te->ys + BLI_rcti_size_y(&v2d->mask) / 2; if (ytop > 0) ytop = 0; v2d->cur.ymax = (float)ytop; @@ -1181,14 +1181,14 @@ static void do_outliner_drivers_editop(SpaceOops *soops, ListBase *tree, ReportL { /* add a new driver with the information obtained (only if valid) */ ANIM_add_driver(reports, id, path, array_index, dflags, DRIVER_TYPE_PYTHON); + break; } - break; case DRIVERS_EDITMODE_REMOVE: { /* remove driver matching the information obtained (only if valid) */ ANIM_remove_driver(reports, id, path, array_index, dflags); + break; } - break; } } diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 3ab412f0ddc..2310ca9b4b5 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -48,7 +48,7 @@ struct Object; typedef struct TreeElement { struct TreeElement *next, *prev, *parent; ListBase subtree; - float xs, ys; // do selection + int xs, ys; // do selection int store_index; // offset in tree store short flag; // flag for non-saved stuff short index; // index for data arrays @@ -77,7 +77,7 @@ typedef struct TreeElement { #define TSE_MODIFIER_BASE 9 #define TSE_MODIFIER 10 #define TSE_LINKED_OB 11 -#define TSE_SCRIPT_BASE 12 +// #define TSE_SCRIPT_BASE 12 // UNUSED #define TSE_POSE_BASE 13 #define TSE_POSE_CHANNEL 14 #define TSE_ANIM_DATA 15 diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 3f06db22f59..9720d981e85 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -704,7 +704,7 @@ static int tree_element_active_sequence_dup(Scene *scene, TreeElement *te, TreeS // XXX select_single_seq(seq, 1); p = ed->seqbasep->first; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) { p = p->next; continue; } diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index 9b9e7bef42c..fb56c5c6dfe 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -854,17 +854,15 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Not yet implemented"); break; } + break; } - break; - case OUTLINER_IDOP_LOCAL: { /* make local */ outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); ED_undo_push(C, "Localized Data"); + break; } - break; - case OUTLINER_IDOP_SINGLE: { /* make single user */ @@ -887,9 +885,8 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_WARNING, "Not yet implemented"); break; } + break; } - break; - case OUTLINER_IDOP_FAKE_ADD: { /* set fake user */ @@ -897,9 +894,8 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Add Fake User"); + break; } - break; - case OUTLINER_IDOP_FAKE_CLEAR: { /* clear fake user */ @@ -907,8 +903,8 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Clear Fake User"); + break; } - break; case OUTLINER_IDOP_RENAME: { /* rename */ @@ -916,9 +912,8 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ID | NA_EDITED, NULL); ED_undo_push(C, "Rename"); + break; } - break; - case OUTLINER_IDOP_SELECT_LINKED: outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_select_linked_cb); ED_undo_push(C, "Select"); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index b5c74eea30e..17734f00997 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -616,18 +616,18 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor case ID_LI: { te->name = ((Library *)id)->name; + break; } - break; case ID_SCE: { outliner_add_scene_contents(soops, &te->subtree, (Scene *)id, te); + break; } - break; case ID_OB: { outliner_add_object_contents(soops, te, tselem, (Object *)id); + break; } - break; case ID_ME: { Mesh *me = (Mesh *)id; @@ -641,8 +641,8 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor outliner_add_element(soops, &te->subtree, me->mat[a], te, 0, a); /* could do tfaces with image links, but the images are not grouped nicely. * would require going over all tfaces, sort images in use. etc... */ + break; } - break; case ID_CU: { Curve *cu = (Curve *)id; @@ -653,8 +653,8 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor for (a = 0; a < cu->totcol; a++) outliner_add_element(soops, &te->subtree, cu->mat[a], te, 0, a); + break; } - break; case ID_MB: { MetaBall *mb = (MetaBall *)id; @@ -665,8 +665,8 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor for (a = 0; a < mb->totcol; a++) outliner_add_element(soops, &te->subtree, mb->mat[a], te, 0, a); + break; } - break; case ID_MA: { Material *ma = (Material *)id; @@ -678,8 +678,8 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor for (a = 0; a < MAX_MTEX; a++) { if (ma->mtex[a]) outliner_add_element(soops, &te->subtree, ma->mtex[a]->tex, te, 0, a); } + break; } - break; case ID_TE: { Tex *tex = (Tex *)id; @@ -688,16 +688,16 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor outliner_add_element(soops, &te->subtree, tex, te, TSE_ANIM_DATA, 0); outliner_add_element(soops, &te->subtree, tex->ima, te, 0, 0); + break; } - break; case ID_CA: { Camera *ca = (Camera *)id; if (outliner_animdata_test(ca->adt)) outliner_add_element(soops, &te->subtree, ca, te, TSE_ANIM_DATA, 0); + break; } - break; case ID_LA: { Lamp *la = (Lamp *)id; @@ -709,16 +709,16 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor for (a = 0; a < MAX_MTEX; a++) { if (la->mtex[a]) outliner_add_element(soops, &te->subtree, la->mtex[a]->tex, te, 0, a); } + break; } - break; case ID_SPK: { Speaker *spk = (Speaker *)id; if (outliner_animdata_test(spk->adt)) outliner_add_element(soops, &te->subtree, spk, te, TSE_ANIM_DATA, 0); + break; } - break; case ID_WO: { World *wrld = (World *)id; @@ -730,22 +730,22 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor for (a = 0; a < MAX_MTEX; a++) { if (wrld->mtex[a]) outliner_add_element(soops, &te->subtree, wrld->mtex[a]->tex, te, 0, a); } + break; } - break; case ID_KE: { Key *key = (Key *)id; if (outliner_animdata_test(key->adt)) outliner_add_element(soops, &te->subtree, key, te, TSE_ANIM_DATA, 0); + break; } - break; case ID_AC: { // XXX do we want to be exposing the F-Curves here? //bAction *act = (bAction *)id; + break; } - break; case ID_AR: { bArmature *arm = (bArmature *)id; @@ -791,8 +791,8 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor } } } + break; } - break; } } @@ -804,7 +804,6 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i TreeElement *te; TreeStoreElem *tselem; ID *id = idv; - int a = 0; if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { id = ((PointerRNA *)idv)->id.data; @@ -957,7 +956,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i else if (type == TSE_SEQ_STRIP) { Strip *strip = (Strip *)idv; - if (strip->dir) + if (strip->dir[0] != '\0') te->name = strip->dir; else te->name = IFACE_("Strip None"); @@ -1084,7 +1083,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->name = km->idname; if (TSELEM_OPEN(tselem, soops)) { - a = 0; + int a = 0; for (kmi = km->items.first; kmi; kmi = kmi->next, a++) { const char *key = WM_key_event_string(kmi->type); @@ -1131,7 +1130,7 @@ static int need_add_seq_dup(Sequence *seq) { Sequence *p; - if ((!seq->strip) || (!seq->strip->stripdata) || (!seq->strip->stripdata->name)) + if ((!seq->strip) || (!seq->strip->stripdata)) return(1); /* @@ -1140,7 +1139,7 @@ static int need_add_seq_dup(Sequence *seq) */ p = seq->prev; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata)) { p = p->prev; continue; } @@ -1152,7 +1151,7 @@ static int need_add_seq_dup(Sequence *seq) p = seq->next; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata)) { p = p->next; continue; } @@ -1171,7 +1170,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t p = seq; while (p) { - if ((!p->strip) || (!p->strip->stripdata) || (!p->strip->stripdata->name)) { + if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) { p = p->next; continue; } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 65199ee9c3d..93dfc347b1f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -118,7 +118,7 @@ static void sequencer_generic_invoke_path__internal(bContext *C, wmOperator *op, Scene *scene = CTX_data_scene(C); Sequence *last_seq = BKE_sequencer_active_get(scene); if (last_seq && last_seq->strip && SEQ_HAS_PATH(last_seq)) { - char path[sizeof(last_seq->strip->dir)]; + char path[FILE_MAX]; BLI_strncpy(path, last_seq->strip->dir, sizeof(path)); BLI_path_abs(path, G.main->name); RNA_string_set(op->ptr, identifier, path); @@ -761,7 +761,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) BKE_sequencer_sort(scene); /* last active name */ - strncpy(ed->act_imagedir, strip->dir, FILE_MAXDIR - 1); + BLI_strncpy(ed->act_imagedir, strip->dir, sizeof(ed->act_imagedir)); if (RNA_boolean_get(op->ptr, "overlap") == FALSE) { if (BKE_sequence_test_overlap(ed->seqbasep, seq)) diff --git a/source/blender/editors/space_sequencer/sequencer_buttons.c b/source/blender/editors/space_sequencer/sequencer_buttons.c index 197cc64dea4..36589984c78 100644 --- a/source/blender/editors/space_sequencer/sequencer_buttons.c +++ b/source/blender/editors/space_sequencer/sequencer_buttons.c @@ -76,7 +76,7 @@ void sequencer_buttons_register(ARegionType *art) /* **************** operator to open/close properties view ************* */ -static int sequencer_properties(bContext *C, wmOperator *UNUSED(op)) +static int sequencer_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = sequencer_has_buttons_region(sa); @@ -93,7 +93,7 @@ void SEQUENCER_OT_properties(wmOperatorType *ot) ot->idname = "SEQUENCER_OT_properties"; ot->description = "Open sequencer properties panel"; - ot->exec = sequencer_properties; + ot->exec = sequencer_properties_toggle_exec; ot->poll = ED_operator_sequencer_active; /* flags */ diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index af4b4055156..68fd09f5fb7 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -162,12 +162,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ break; case SEQ_TYPE_COLOR: - if (colvars->col) { - rgb_float_to_uchar(col, colvars->col); - } - else { - col[0] = col[1] = col[2] = 128; - } + rgb_float_to_uchar(col, colvars->col); break; case SEQ_TYPE_SOUND_RAM: @@ -178,6 +173,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ default: col[0] = 10; col[1] = 255; col[2] = 40; + break; } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 135fddfd348..955a9c78c56 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -551,12 +551,14 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen } if (seq1 == NULL) seq1 = seq2; if (seq3 == NULL) seq3 = seq2; + /* fall-through */ case 2: if (seq1 == NULL || seq2 == NULL) { *error_str = N_("2 selected sequence strips are needed"); return 0; } if (seq3 == NULL) seq3 = seq2; + break; } if (seq1 == NULL && seq2 == NULL && seq3 == NULL) { @@ -866,7 +868,7 @@ static int cut_seq_list(Scene *scene, ListBase *slist, int cutframe, return (seq_first_new != NULL); } -static bool insert_gap(Scene *scene, int gap, int cfra) +static bool sequence_offset_after_frame(Scene *scene, const int delta, const int cfra) { Sequence *seq; Editing *ed = BKE_sequencer_editing_get(scene, FALSE); @@ -876,15 +878,13 @@ static bool insert_gap(Scene *scene, int gap, int cfra) if (ed == NULL) return 0; - SEQP_BEGIN (ed, seq) - { + for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->startdisp >= cfra) { - seq->start += gap; + BKE_sequence_translate(scene, seq, delta); BKE_sequence_calc(scene, seq); done = true; } } - SEQ_END return done; } @@ -1017,7 +1017,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) else if (BKE_sequencer_evaluate_frame(scene, cfra) == 0) { done = true; while (BKE_sequencer_evaluate_frame(scene, cfra) == 0) { - done = insert_gap(scene, -1, cfra); + done = sequence_offset_after_frame(scene, -1, cfra); if (done == false) break; } if (done == false || do_all == false) break; @@ -1054,7 +1054,7 @@ static int sequencer_gap_insert_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); int frames = RNA_int_get(op->ptr, "frames"); - insert_gap(scene, frames, CFRA); + sequence_offset_after_frame(scene, frames, CFRA); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); @@ -2721,7 +2721,6 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq) } } -/* TODO, validate scenes */ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -2766,6 +2765,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) for (seq = seqbase_clipboard.first; seq; seq = seq->next) { seq_copy_del_sound(scene, seq); } + + /* duplicate pointers */ + for (seq = seqbase_clipboard.first; seq; seq = seq->next) { + BKE_sequence_clipboard_pointers_store(seq); + } } return OPERATOR_FINISHED; @@ -2790,11 +2794,12 @@ void SEQUENCER_OT_copy(wmOperatorType *ot) static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, TRUE); /* create if needed */ ListBase nseqbase = {NULL, NULL}; int ofs; - Sequence *iseq; + Sequence *iseq, *iseq_first; ED_sequencer_deselect_all(scene); ofs = scene->r.cfra - seqbase_clipboard_frame; @@ -2805,19 +2810,33 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op)) if (ofs) { for (iseq = nseqbase.first; iseq; iseq = iseq->next) { BKE_sequence_translate(scene, iseq, ofs); - BKE_sequence_sound_init(scene, iseq); } } - iseq = nseqbase.first; + for (iseq = nseqbase.first; iseq; iseq = iseq->next) { + BKE_sequence_clipboard_pointers_restore(iseq, bmain); + } + + for (iseq = nseqbase.first; iseq; iseq = iseq->next) { + BKE_sequence_sound_init(scene, iseq); + } + + iseq_first = nseqbase.first; BLI_movelisttolist(ed->seqbasep, &nseqbase); /* make sure the pasted strips have unique names between them */ - for (; iseq; iseq = iseq->next) { + for (iseq = iseq_first; iseq; iseq = iseq->next) { BKE_sequencer_recursive_apply(iseq, apply_unique_name_cb, scene); } + /* ensure pasted strips don't overlap */ + for (iseq = iseq_first; iseq; iseq = iseq->next) { + if (BKE_sequence_test_overlap(ed->seqbasep, iseq)) { + BKE_sequence_base_shuffle(ed->seqbasep, iseq, scene); + } + } + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index e7fa4c05b9d..b04d2b16e8d 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -149,7 +149,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) } ED_area_tag_redraw(sa); - /* no break -- fall down to tag redraw */ + /* fall-through */ /* fall down to tag redraw */ case NA_ADDED: case NA_REMOVED: ED_area_tag_redraw(sa); diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index 26e0be264a4..ba61399f6d5 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -433,6 +433,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e break; case PAGEDOWNKEY: scroll = SUGG_LIST_SIZE - 1; + /* fall-through */ case WHEELDOWNMOUSE: case DOWNARROWKEY: if (event->val == KM_PRESS) { @@ -460,6 +461,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e break; case PAGEUPKEY: scroll = SUGG_LIST_SIZE - 1; + /* fall-through */ case WHEELUPMOUSE: case UPARROWKEY: if (event->val == KM_PRESS) { diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c index 8258d717889..f7116c01a72 100644 --- a/source/blender/editors/space_time/space_time.c +++ b/source/blender/editors/space_time/space_time.c @@ -201,9 +201,10 @@ static void time_draw_cache(SpaceTime *stime, Object *ob, Scene *scene) col[3] = 0.1; break; default: - BLI_assert(0); col[0] = 1.0; col[1] = 0.0; col[2] = 1.0; col[3] = 0.1; + BLI_assert(0); + break; } glColor4fv(col); @@ -403,6 +404,7 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) /* mainly for updating cache display */ switch (wmn->category) { case NC_OBJECT: + { switch (wmn->data) { case ND_BONE_ACTIVE: case ND_POINTCACHE: @@ -414,7 +416,9 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) break; } break; + } case NC_SCENE: + { switch (wmn->data) { case ND_OB_ACTIVE: case ND_FRAME: @@ -432,21 +436,29 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) break; } } + break; } - break; } + break; + } case NC_SPACE: + { switch (wmn->data) { case ND_SPACE_CHANGED: ED_area_tag_refresh(sa); break; } + break; + } case NC_WM: + { switch (wmn->data) { case ND_FILEREAD: ED_area_tag_refresh(sa); break; } + break; + } } } @@ -568,11 +580,13 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), /* context changes */ switch (wmn->category) { case NC_SCREEN: + { if (wmn->data == ND_ANIMPLAY) ED_region_tag_redraw(ar); break; - + } case NC_SCENE: + { switch (wmn->data) { case ND_OB_SELECT: case ND_FRAME: @@ -582,11 +596,14 @@ static void time_header_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ED_region_tag_redraw(ar); break; } - + break; + } case NC_SPACE: + { if (wmn->data == ND_SPACE_TIME) ED_region_tag_redraw(ar); break; + } } } diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index f3528ef61b6..68f656bbf57 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -186,8 +186,6 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) return true; } - break; - case PCHAN_COLOR_SOLID: { if (bcolor) { @@ -198,8 +196,6 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) return true; } - break; - case PCHAN_COLOR_CONSTS: { if ((bcolor == NULL) || (bcolor->flag & TH_WIRECOLOR_CONSTCOLS)) { @@ -210,11 +206,8 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) return true; } - else - return 0; + return false; } - break; - case PCHAN_COLOR_SPHEREBONE_BASE: { if (bcolor) { @@ -240,7 +233,6 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) return true; } - break; case PCHAN_COLOR_SPHEREBONE_END: { if (bcolor) { @@ -266,9 +258,8 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) else if (boneflag & BONE_SELECTED) UI_ThemeColorShade(TH_BONE_POSE, -30); else UI_ThemeColorShade(TH_BONE_SOLID, -30); } + break; } - break; - case PCHAN_COLOR_LINEBONE: { /* inner part in background color or constraint */ @@ -290,7 +281,6 @@ static bool set_pchan_glColor(short colCode, int boneflag, short constflag) return true; } - break; } return false; @@ -1426,8 +1416,8 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) glEnd(); setlinestyle(0); + break; } - break; case CONSTRAINT_TYPE_SPLINEIK: { bSplineIKConstraint *data = (bSplineIKConstraint *)con->data; @@ -1451,8 +1441,8 @@ static void pchan_draw_IK_root_lines(bPoseChannel *pchan, short only_temp) glEnd(); setlinestyle(0); + break; } - break; } } } @@ -2070,20 +2060,10 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* in editmode, we don't store the bone matrix... */ -static void get_matrix_editbone(EditBone *eBone, float bmat[4][4]) +static void get_matrix_editbone(EditBone *ebone, float bmat[4][4]) { - float delta[3]; - float mat[3][3]; - - /* Compose the parent transforms (i.e. their translations) */ - sub_v3_v3v3(delta, eBone->tail, eBone->head); - - eBone->length = (float)sqrt(delta[0] * delta[0] + delta[1] * delta[1] + delta[2] * delta[2]); - - vec_roll_to_mat3(delta, eBone->roll, mat); - copy_m4_m3(bmat, mat); - - add_v3_v3(bmat[3], eBone->head); + ebone->length = len_v3v3(ebone->tail, ebone->head); + ED_armature_ebone_to_mat4(ebone, bmat); } static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 7525b799067..16423c60cac 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -77,7 +77,7 @@ /* user data structures for derived mesh callbacks */ typedef struct drawMeshFaceSelect_userData { Mesh *me; - BLI_bitmap edge_flags; /* pairs of edge options (visible, select) */ + BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */ } drawMeshFaceSelect_userData; typedef struct drawEMTFMapped_userData { @@ -100,9 +100,9 @@ typedef struct drawTFace_userData { BLI_INLINE int edge_vis_index(const int index) { return index * 2; } BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } -static BLI_bitmap get_tface_mesh_marked_edge_info(Mesh *me) +static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me) { - BLI_bitmap bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); + BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__); MPoly *mp; MLoop *ml; int i, j; @@ -566,7 +566,12 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) { drawEMTFMapped_userData *data = userData; BMEditMesh *em = data->em; - BMFace *efa = EDBM_face_at_index(em, index); + BMFace *efa; + + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; @@ -907,7 +912,7 @@ static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs) } } -static int tex_mat_set_face_mesh_cb(void *userData, int index) +static bool tex_mat_set_face_mesh_cb(void *userData, int index) { /* faceselect mode face hiding */ TexMatCallback *data = (TexMatCallback *)userData; @@ -917,12 +922,18 @@ static int tex_mat_set_face_mesh_cb(void *userData, int index) return !(mp->flag & ME_HIDE); } -static int tex_mat_set_face_editmesh_cb(void *userData, int index) +static bool tex_mat_set_face_editmesh_cb(void *userData, int index) { /* editmode face hiding */ TexMatCallback *data = (TexMatCallback *)userData; Mesh *me = (Mesh *)data->me; - BMFace *efa = EDBM_face_at_index(me->edit_btmesh, index); + BMEditMesh *em = me->edit_btmesh; + BMFace *efa; + + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN); } @@ -949,7 +960,7 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, { Mesh *me = ob->data; TexMatCallback data = {scene, ob, me, dm}; - int (*set_face_cb)(void *, int); + bool (*set_face_cb)(void *, int); int glsl, picking = (G.f & G_PICKSEL); /* face hiding callback depending on mode */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 9ab6336ab0e..6383440893d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2002,7 +2002,7 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) data.col[2] = act_col; glBegin(GL_POINTS); - dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data); + dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, &data, DM_FOREACH_NOP); glEnd(); } @@ -2068,7 +2068,7 @@ static void draw_dm_face_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv calcDrawDMNormalScale(ob, &data); glBegin(GL_LINES); - dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data); + dm->foreachMappedFaceCenter(dm, draw_dm_face_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); glEnd(); } @@ -2088,7 +2088,7 @@ static void draw_dm_face_centers(BMEditMesh *em, DerivedMesh *dm, char sel) void *ptrs[2] = {em, &sel}; bglBegin(GL_POINTS); - dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs); + dm->foreachMappedFaceCenter(dm, draw_dm_face_centers__mapFunc, ptrs, DM_FOREACH_NOP); bglEnd(); } @@ -2133,7 +2133,7 @@ static void draw_dm_vert_normals(BMEditMesh *em, Scene *scene, Object *ob, Deriv calcDrawDMNormalScale(ob, &data); glBegin(GL_LINES); - dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_vert_normals__mapFunc, &data, DM_FOREACH_USE_NORMAL); glEnd(); } @@ -2204,7 +2204,7 @@ static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, const char sel, BMVer invert_m4(data.imat); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_verts__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); } @@ -2534,7 +2534,7 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) if (data.cd_layer_offset != -1) { glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data); + dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); } } @@ -2699,7 +2699,8 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; const bool do_moving = (G.moving & G_TRANSFORM_EDIT) != 0; float clip_planes[4][4]; - + /* allow for displaying shape keys and deform mods */ + DerivedMesh *dm = EDBM_mesh_deform_dm_get(em); BMIter iter; int i; @@ -2725,23 +2726,33 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter)) { + if (dm) { + BM_mesh_elem_index_ensure(em->bm, BM_VERT); + } + + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { /* draw selected edges, or edges next to selected verts while draging */ if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))) { + float v1_clip[3], v2_clip[3]; - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); + if (dm) { + dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); + dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); + } + else { + copy_v3_v3(v1, eed->v1->co); + copy_v3_v3(v2, eed->v2->co); + } - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) { + copy_v3_v3(v1_clip, v1); + copy_v3_v3(v2_clip, v2); - mid_v3_v3v3(vmid, v1, v2); + if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); + mid_v3_v3v3(vmid, v1_clip, v2_clip); if (do_global) { mul_mat3_m4_v3(ob->obmat, v1); @@ -2768,10 +2779,13 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col); + if (dm) { + BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); + } + // invert_m4_m4(ob->imat, ob->obmat); // this is already called - eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter)) { + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { BMLoop *l_a, *l_b; if (BM_edge_loop_pair(eed, &l_a, &l_b)) { /* draw selected edges, or edges next to selected verts while draging */ @@ -2786,30 +2800,44 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT) ))) { - copy_v3_v3(v1, eed->v1->co); - copy_v3_v3(v2, eed->v2->co); - - if (clip_segment_v3_plane_n(v1, v2, clip_planes, 4)) { - float angle; - - mid_v3_v3v3(vmid, v1, v2); + float v1_clip[3], v2_clip[3]; + if (dm) { + dm->getVertCo(dm, BM_elem_index_get(eed->v1), v1); + dm->getVertCo(dm, BM_elem_index_get(eed->v2), v2); + } + else { copy_v3_v3(v1, eed->v1->co); copy_v3_v3(v2, eed->v2->co); + } - if (do_global) { - float no_a[3]; - float no_b[3]; + copy_v3_v3(v1_clip, v1); + copy_v3_v3(v2_clip, v2); + + if (clip_segment_v3_plane_n(v1_clip, v2_clip, clip_planes, 4)) { + float no_a[3], no_b[3]; + float angle; + + mid_v3_v3v3(vmid, v1_clip, v2_clip); + + if (dm) { + dm->getPolyNo(dm, BM_elem_index_get(l_a->f), no_a); + dm->getPolyNo(dm, BM_elem_index_get(l_b->f), no_b); + } + else { copy_v3_v3(no_a, l_a->f->no); copy_v3_v3(no_b, l_b->f->no); + } + + if (do_global) { mul_mat3_m4_v3(ob->imat, no_a); mul_mat3_m4_v3(ob->imat, no_b); - angle = angle_v3v3(no_a, no_b); - } - else { - angle = angle_normalized_v3v3(l_a->f->no, l_b->f->no); + normalize_v3(no_a); + normalize_v3(no_b); } + angle = angle_normalized_v3v3(no_a, no_b); + BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); @@ -2844,6 +2872,10 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEAREA, col); + if (dm) { + BM_mesh_elem_index_ensure(em->bm, BM_VERT); + } + f = NULL; area = 0.0; zero_v3(vmid); @@ -2858,9 +2890,18 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe } f = l[0]->f; - copy_v3_v3(v1, l[0]->v->co); - copy_v3_v3(v2, l[1]->v->co); - copy_v3_v3(v3, l[2]->v->co); + + if (dm) { + dm->getVertCo(dm, BM_elem_index_get(l[0]->v), v1); + dm->getVertCo(dm, BM_elem_index_get(l[1]->v), v2); + dm->getVertCo(dm, BM_elem_index_get(l[2]->v), v3); + } + else { + copy_v3_v3(v1, l[0]->v->co); + copy_v3_v3(v2, l[1]->v->co); + copy_v3_v3(v3, l[2]->v->co); + } + add_v3_v3(vmid, v1); add_v3_v3(vmid, v2); add_v3_v3(vmid, v3); @@ -2885,6 +2926,9 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); + if (dm) { + BM_mesh_elem_index_ensure(em->bm, BM_VERT); + } BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { const int is_face_sel = BM_elem_flag_test(efa, BM_ELEM_SELECT); @@ -2897,35 +2941,50 @@ static void draw_em_measure_stats(ARegion *ar, View3D *v3d, Object *ob, BMEditMe BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { if (is_face_sel || (do_moving && BM_elem_flag_test(loop->v, BM_ELEM_SELECT))) { float angle; + float v2_local[3]; /* lazy init center calc */ if (is_first) { - BM_face_calc_center_bounds(efa, vmid); - /* Avoid triple matrix multiply every vertex for 'global' */ - if (do_global) { - copy_v3_v3(v1, loop->prev->v->co); - copy_v3_v3(v2, loop->v->co); - mul_mat3_m4_v3(ob->obmat, v1); - mul_mat3_m4_v3(ob->obmat, v2); + if (dm) { + BMLoop *l_iter, *l_first; + float tvec[3]; + zero_v3(vmid); + l_iter = l_first = BM_FACE_FIRST_LOOP(efa); + do { + dm->getVertCo(dm, BM_elem_index_get(l_iter->v), tvec); + add_v3_v3(vmid, tvec); + } while ((l_iter = l_iter->next) != l_first); + mul_v3_fl(vmid, 1.0f / (float)efa->len); + } + else { + BM_face_calc_center_bounds(efa, vmid); } is_first = false; } - if (do_global) { + if (dm) { + dm->getVertCo(dm, BM_elem_index_get(loop->prev->v), v1); + dm->getVertCo(dm, BM_elem_index_get(loop->v), v2); + dm->getVertCo(dm, BM_elem_index_get(loop->next->v), v3); + } + else { + copy_v3_v3(v1, loop->prev->v->co); + copy_v3_v3(v2, loop->v->co); copy_v3_v3(v3, loop->next->v->co); + } - mul_mat3_m4_v3(ob->obmat, v3); + copy_v3_v3(v2_local, v2); - angle = angle_v3v3v3(v1, v2, v3); - copy_v3_v3(v1, v2); - copy_v3_v3(v2, v3); - } - else { - angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co); + if (do_global) { + mul_mat3_m4_v3(ob->obmat, v1); + mul_mat3_m4_v3(ob->obmat, v2); + mul_mat3_m4_v3(ob->obmat, v3); } + angle = angle_v3v3v3(v1, v2, v3); + BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); - interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f); + interp_v3_v3v3(fvec, vmid, v2_local, 0.8f); view3d_cached_text_draw_add(fvec, numstr, 0, txt_flag, col); } } @@ -2990,24 +3049,38 @@ static void draw_em_indices(BMEditMesh *em) static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) { - BMFace *efa = EDBM_face_at_index(userData, index); + BMEditMesh *em = userData; + BMFace *efa; + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; } - else + else { return DM_DRAW_OPTION_SKIP; + } } static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) { - BMFace *efa = EDBM_face_at_index(userData, index); + BMEditMesh *em = userData; + BMFace *efa; - if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) - return DM_DRAW_OPTION_SKIP; - else + if (UNLIKELY(index >= em->bm->totface)) + return DM_DRAW_OPTION_NORMAL; + + efa = EDBM_face_at_index(em, index); + + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_NORMAL; + } + else { + return DM_DRAW_OPTION_SKIP; + } } static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, @@ -3019,8 +3092,9 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, BMFace *efa_act = BM_mesh_active_face_get(em->bm, false, true); /* annoying but active faces is stored differently */ BMEdge *eed_act = NULL; BMVert *eve_act = NULL; + bool use_occlude_wire = (v3d->flag2 & V3D_OCCLUDE_WIRE) && (dt > OB_WIRE); - if (cageDM) BLI_assert(!(cageDM->dirty & DM_DIRTY_NORMALS)); + // if (cageDM) BLI_assert(!(cageDM->dirty & DM_DIRTY_NORMALS)); if (finalDM) BLI_assert(!(finalDM->dirty & DM_DIRTY_NORMALS)); if (em->bm->selected.last) { @@ -3057,7 +3131,14 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, } } else if (dt > OB_WIRE) { - if (check_object_draw_texture(scene, v3d, dt)) { + if (use_occlude_wire) { + /* use the cageDM since it always overlaps the editmesh faces */ + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + cageDM->drawMappedFaces(cageDM, draw_em_fancy__setFaceOpts, + GPU_enable_material, NULL, me->edit_btmesh, 0); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + else if (check_object_draw_texture(scene, v3d, dt)) { if (draw_glsl_material(scene, ob, v3d, dt)) { glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); @@ -3098,8 +3179,8 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, finalDM->drawEdges(finalDM, 1, 0); } } - - if (me->drawflag & ME_DRAWFACES) { /* transp faces */ + + if ((me->drawflag & ME_DRAWFACES) && (use_occlude_wire == false)) { /* transp faces */ unsigned char col1[4], col2[4], col3[4]; #ifdef WITH_FREESTYLE unsigned char col4[4]; @@ -3238,6 +3319,11 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, bglPolygonOffset(rv3d->dist, 0.0); GPU_disable_material(); } +#if 0 /* currently not needed */ + else if (use_occlude_wire) { + bglPolygonOffset(rv3d->dist, 0.0); + } +#endif } /* Mesh drawing routines */ @@ -3273,7 +3359,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D Object *ob = base->object; Mesh *me = ob->data; Material *ma = give_current_material(ob, 1); - const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO)); + const short hasHaloMat = (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene)); eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; int /* totvert,*/ totedge, totface; DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); @@ -3766,8 +3852,8 @@ static void drawDispListsolid(ListBase *lb, Object *ob, const short dflag, glEnd(); glEnable(GL_LIGHTING); - break; } + break; case DL_SURF: if (dl->index) { @@ -4345,7 +4431,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv copy_m4_m4(imat, rv3d->viewinv); normalize_v3(imat[0]); normalize_v3(imat[1]); - /* no break! */ + /* fall-through */ case PART_DRAW_CROSS: case PART_DRAW_AXIS: /* lets calculate the scale: */ @@ -4519,6 +4605,8 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv break; default: intensity = 1.0f; /* should never happen */ + BLI_assert(0); + break; } CLAMP(intensity, 0.f, 1.f); weight_to_rgb(ma_col, intensity); @@ -6780,8 +6868,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ { drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); - break; } + break; case OB_SPEAKER: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) drawspeaker(scene, v3d, rv3d, ob, dflag); @@ -6820,6 +6908,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { drawaxes(1.0, OB_ARROWS); } + break; } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -7270,7 +7359,7 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) data.offset = (void *)(intptr_t) offset; glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data); + dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data, DM_FOREACH_NOP); bglEnd(); glPointSize(1.0); } @@ -7293,7 +7382,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs); + dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs, DM_FOREACH_NOP); bglEnd(); glPointSize(1.0); } @@ -7359,7 +7448,7 @@ static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d, glPointSize(UI_GetThemeValuef(TH_FACEDOT_SIZE)); bglBegin(GL_POINTS); - dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs); + dm->foreachMappedFaceCenter(dm, bbs_mesh_solid__drawCenter, ptrs, DM_FOREACH_NOP); bglEnd(); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 92bf8214336..dfbc973ee85 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1141,17 +1141,17 @@ const char *view3d_context_dir[] = { static int view3d_context(const bContext *C, const char *member, bContextDataResult *result) { - View3D *v3d = CTX_wm_view3d(C); - Scene *scene = CTX_data_scene(C); - Base *base; /* fallback to the scene layer, allows duplicate and other object operators to run outside the 3d view */ - unsigned int lay = v3d ? v3d->lay : scene->lay; if (CTX_data_dir(member)) { CTX_data_dir_set(result, view3d_context_dir); } else if (CTX_data_equals(member, "selected_objects") || CTX_data_equals(member, "selected_bases")) { - int selected_objects = CTX_data_equals(member, "selected_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selected_objects = CTX_data_equals(member, "selected_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { @@ -1167,7 +1167,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "selected_editable_objects") || CTX_data_equals(member, "selected_editable_bases")) { - int selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selected_editable_objects = CTX_data_equals(member, "selected_editable_objects"); for (base = scene->base.first; base; base = base->next) { if ((base->flag & SELECT) && (base->lay & lay)) { @@ -1185,7 +1189,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "visible_objects") || CTX_data_equals(member, "visible_bases")) { - int visible_objects = CTX_data_equals(member, "visible_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool visible_objects = CTX_data_equals(member, "visible_objects"); for (base = scene->base.first; base; base = base->next) { if (base->lay & lay) { @@ -1201,7 +1209,11 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "selectable_objects") || CTX_data_equals(member, "selectable_bases")) { - int selectable_objects = CTX_data_equals(member, "selectable_objects"); + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; + Base *base; + const bool selectable_objects = CTX_data_equals(member, "selectable_objects"); for (base = scene->base.first; base; base = base->next) { if (base->lay & lay) { @@ -1217,6 +1229,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "active_base")) { + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; if (scene->basact && (scene->basact->lay & lay)) { Object *ob = scene->basact->object; /* if hidden but in edit mode, we still display, can happen with animation */ @@ -1227,6 +1242,9 @@ static int view3d_context(const bContext *C, const char *member, bContextDataRes return 1; } else if (CTX_data_equals(member, "active_object")) { + View3D *v3d = CTX_wm_view3d(C); + Scene *scene = CTX_data_scene(C); + const unsigned int lay = v3d ? v3d->lay : scene->lay; if (scene->basact && (scene->basact->lay & lay)) { Object *ob = scene->basact->object; if ((ob->restrictflag & OB_RESTRICT_VIEW) == 0 || (ob->mode & OB_MODE_EDIT)) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 4a823290f99..75e7605df6b 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -95,8 +95,6 @@ typedef struct { float ob_dims[3]; short link_scale; float ve_median[NBR_TRANSFORM_PROPERTIES]; - int curdef; - float *defweightp; } TransformProperties; /* Helper function to compute a median changed value, @@ -154,17 +152,14 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float #define L_WEIGHT 4 uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; - MDeformVert *dvert = NULL; TransformProperties *tfp; float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; bool has_meshdata = false; - char defstr[320]; PointerRNA data_ptr; fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; - defstr[0] = '\0'; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -175,7 +170,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMVert *eve, *evedef = NULL; + BMVert *eve; BMEdge *eed; BMIter iter; @@ -187,7 +182,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (bm->totvertsel) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - evedef = eve; tot++; add_v3_v3(&median[LOC_X], eve->co); @@ -226,33 +220,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float totedgedata = bm->totedgesel; } - /* check for defgroups */ - if (evedef) - dvert = CustomData_bmesh_get(&bm->vdata, evedef->head.data, CD_MDEFORMVERT); - if (tot == 1 && dvert && dvert->totweight) { - bDeformGroup *dg; - int i, max = 1, init = 1; - char str[320]; - - for (i = 0; i < dvert->totweight; i++) { - dg = BLI_findlink(&ob->defbase, dvert->dw[i].def_nr); - if (dg) { - max += BLI_snprintf(str, sizeof(str), "%s %%x%d|", dg->name, dvert->dw[i].def_nr); - if (max < sizeof(str)) strcat(defstr, str); - } - - if (tfp->curdef == dvert->dw[i].def_nr) { - init = 0; - tfp->defweightp = &dvert->dw[i].weight; - } - } - - if (init) { /* needs new initialized */ - tfp->curdef = dvert->dw[0].def_nr; - tfp->defweightp = &dvert->dw[0].weight; - } - } - has_meshdata = (totedgedata || totskinradius); } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { @@ -915,7 +882,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) ot = WM_operatortype_find("OBJECT_OT_vertex_weight_normalize_active_vertex", 1); but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Normalize", 0, yco, UI_UNIT_X * 5, UI_UNIT_Y, - TIP_("Normalize weights of active vertex (if affected groups are unlocked")); + TIP_("Normalize weights of active vertex (if affected groups are unlocked)")); if (lock_count) { uiButSetFlag(but, UI_BUT_DISABLED); } @@ -923,7 +890,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) ot = WM_operatortype_find("OBJECT_OT_vertex_weight_copy", 1); but = uiDefButO_ptr(block, BUT, ot, WM_OP_EXEC_DEFAULT, "Copy", UI_UNIT_X * 5, yco, UI_UNIT_X * 5, UI_UNIT_Y, - TIP_("Copy active vertex to other selected verts (if affected groups are unlocked)")); + TIP_("Copy active vertex to other selected vertices (if affected groups are unlocked)")); if (lock_count) { uiButSetFlag(but, UI_BUT_DISABLED); } @@ -1204,7 +1171,7 @@ void view3d_buttons_register(ARegionType *art) BLI_addtail(&art->paneltypes, pt); } -static int view3d_properties(bContext *C, wmOperator *UNUSED(op)) +static int view3d_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = view3d_has_buttons_region(sa); @@ -1221,7 +1188,7 @@ void VIEW3D_OT_properties(wmOperatorType *ot) ot->description = "Toggles the properties panel display"; ot->idname = "VIEW3D_OT_properties"; - ot->exec = view3d_properties; + ot->exec = view3d_properties_toggle_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0a2358aa137..61532e75ee9 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -3033,7 +3033,7 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A { float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f}; - if (!rv3d->render_engine || !rv3d->render_engine->text) + if (!rv3d->render_engine || !rv3d->render_engine->text[0]) return; if (render_border) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e4aa44d7d78..7b8c197f3e6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -1009,6 +1009,14 @@ static int view3d_camera_user_poll(bContext *C) return 0; } +static int view3d_lock_poll(bContext *C) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + + return ED_view3d_offset_lock_check(v3d, rv3d); +} + static int viewrotate_cancel(bContext *C, wmOperator *op) { viewops_data_free(C, op); @@ -1537,7 +1545,11 @@ void viewmove_modal_keymap(wmKeyConfig *keyconf) static void viewmove_apply(ViewOpsData *vod, int x, int y) { - if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { + if (ED_view3d_offset_lock_check(vod->v3d, vod->rv3d)) { + vod->rv3d->ofs_lock[0] -= ((vod->oldx - x) * 2.0f) / (float)vod->ar->winx; + vod->rv3d->ofs_lock[1] -= ((vod->oldy - y) * 2.0f) / (float)vod->ar->winy; + } + else if ((vod->rv3d->persp == RV3D_CAMOB) && !ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { const float zoomfac = BKE_screen_view3d_zoom_to_fac((float)vod->rv3d->camzoom) * 2.0f; vod->rv3d->camdx += (vod->oldx - x) / (vod->ar->winx * zoomfac); vod->rv3d->camdy += (vod->oldy - y) / (vod->ar->winy * zoomfac); @@ -1614,8 +1626,6 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ViewOpsData *vod; - VIEW3D_OP_OFS_LOCK_TEST(C, op); - /* makes op->customdata */ viewops_data_create(C, op, event); vod = op->customdata; @@ -2141,7 +2151,7 @@ static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event) static int viewdolly_exec(bContext *C, wmOperator *op) { - /* View3D *v3d; */ + View3D *v3d; RegionView3D *rv3d; ScrArea *sa; ARegion *ar; @@ -2163,7 +2173,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op) normalize_v3(mousevec); } - /* v3d = sa->spacedata.first; */ /* UNUSED */ + v3d = sa->spacedata.first; rv3d = ar->regiondata; /* overwrite the mouse vector with the view direction (zoom into the center) */ @@ -2172,16 +2182,19 @@ static int viewdolly_exec(bContext *C, wmOperator *op) } if (delta < 0) { - view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 1.2f); + view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 0.2f); } else { - view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 0.83333f); + view_dolly_mouseloc(ar, rv3d->ofs, mousevec, 1.8f); } if (rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_sync(sa, ar); ED_view3d_depth_tag_update(rv3d); + + ED_view3d_camera_lock_sync(v3d, rv3d); + ED_region_tag_redraw(ar); viewops_data_free(C, op); @@ -2792,6 +2805,32 @@ void VIEW3D_OT_view_center_camera(wmOperatorType *ot) ot->flag = 0; } +static int view3d_center_lock_exec(bContext *C, wmOperator *UNUSED(op)) /* was view3d_home() in 2.4x */ +{ + RegionView3D *rv3d = CTX_wm_region_view3d(C); + + zero_v2(rv3d->ofs_lock); + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_view_center_lock(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View Lock Center"; + ot->description = "Center the view lock offset"; + ot->idname = "VIEW3D_OT_view_center_lock"; + + /* api callbacks */ + ot->exec = view3d_center_lock_exec; + ot->poll = view3d_lock_poll; + + /* flags */ + ot->flag = 0; +} + /* ********************* Set render border operator ****************** */ static int render_border_exec(bContext *C, wmOperator *op) @@ -3202,16 +3241,11 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar, align_active = false; } else { - const float z_flip_quat[4] = {0.0f, 0.0f, 0.0f, 1.0f}; float obact_quat[4]; float twmat[3][3]; - /* flip the input, the end result being that an object - * with no rotation behaves as if 'align_active' is off */ - mul_qt_qtqt(new_quat, new_quat, z_flip_quat); - /* same as transform manipulator when normal is set */ - ED_getTransformOrientationMatrix(C, twmat, false); + ED_getTransformOrientationMatrix(C, twmat, true); mat3_to_quat(obact_quat, twmat); invert_qt(obact_quat); @@ -4166,28 +4200,27 @@ float ED_view3d_offset_distance(float mat[4][4], const float ofs[3], const float */ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist) { + float nmat[3][3]; + + /* dist depends on offset */ + BLI_assert(dist == NULL || ofs != NULL); + + copy_m3_m4(nmat, mat); + normalize_m3(nmat); + /* Offset */ if (ofs) negate_v3_v3(ofs, mat[3]); /* Quat */ if (quat) { - float imat[4][4]; - normalize_m4_m4(imat, mat); - invert_m4(imat); - mat4_to_quat(quat, imat); + float imat[3][3]; + invert_m3_m3(imat, nmat); + mat3_to_quat(quat, imat); } - if (dist) { - float nmat[3][3]; - float vec[3]; - - vec[0] = 0.0f; - vec[1] = 0.0f; - vec[2] = -(*dist); - - copy_m3_m4(nmat, mat); - normalize_m3(nmat); + if (ofs && dist) { + float vec[3] = {0.0f, 0.0f, -(*dist)}; mul_m3_v3(nmat, vec); sub_v3_v3(ofs, vec); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 659c9a6c2e6..a1a13130b27 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -518,7 +518,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event) #ifdef NDOF_FLY_DEBUG puts("start keeping track of 3D mouse position"); #endif - /* fall through... */ + /* fall-through */ case P_IN_PROGRESS: /* update 3D mouse position */ #ifdef NDOF_FLY_DEBUG diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 44c85799896..085af4e5c18 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -89,6 +89,7 @@ void VIEW3D_OT_view_lock_to_active(struct wmOperatorType *ot); void VIEW3D_OT_view_center_cursor(struct wmOperatorType *ot); void VIEW3D_OT_view_center_pick(struct wmOperatorType *ot); void VIEW3D_OT_view_center_camera(struct wmOperatorType *ot); +void VIEW3D_OT_view_center_lock(struct wmOperatorType *ot); void VIEW3D_OT_view_pan(struct wmOperatorType *ot); void VIEW3D_OT_view_persportho(struct wmOperatorType *ot); void VIEW3D_OT_background_image_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 0490d8763d8..d13ab15d837 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -124,7 +124,7 @@ void meshobject_foreachScreenVert( ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ } - dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data); + dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } @@ -166,7 +166,7 @@ void mesh_foreachScreenVert( } EDBM_index_arrays_ensure(vc->em, BM_VERT); - dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } @@ -262,7 +262,7 @@ void mesh_foreachScreenFace( data.clip_flag = clip_flag; EDBM_index_arrays_ensure(vc->em, BM_FACE); - dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data, DM_FOREACH_NOP); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index c46ae36a3a5..6780b71c906 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -148,6 +148,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_view_center_cursor); WM_operatortype_append(VIEW3D_OT_view_center_pick); WM_operatortype_append(VIEW3D_OT_view_center_camera); + WM_operatortype_append(VIEW3D_OT_view_center_lock); WM_operatortype_append(VIEW3D_OT_select); WM_operatortype_append(VIEW3D_OT_select_border); WM_operatortype_append(VIEW3D_OT_clip_border); @@ -232,7 +233,6 @@ void view3d_keymap(wmKeyConfig *keyconf) /*numpad +/-*/ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADPLUSKEY, KM_PRESS, 0, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", PADMINUS, KM_PRESS, 0, 0)->ptr, "delta", -1); - /*ctrl +/-*/ RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", EQUALKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", MINUSKEY, KM_PRESS, KM_CTRL, 0)->ptr, "delta", -1); @@ -241,9 +241,18 @@ void view3d_keymap(wmKeyConfig *keyconf) RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELINMOUSE, KM_PRESS, 0, 0)->ptr, "delta", 1); RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_zoom", WHEELOUTMOUSE, KM_PRESS, 0, 0)->ptr, "delta", -1); + /* ... and for dolly */ + /*numpad +/-*/ + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_dolly", PADPLUSKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", 1); + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_dolly", PADMINUS, KM_PRESS, KM_SHIFT, 0)->ptr, "delta", -1); + /*ctrl +/-*/ + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_dolly", EQUALKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "delta", 1); + RNA_int_set(WM_keymap_add_item(keymap, "VIEW3D_OT_dolly", MINUSKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "delta", -1); + WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_camera_1_to_1", PADENTER, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_camera", HOMEKEY, KM_PRESS, 0, 0); /* only with camera view */ + WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_lock", HOMEKEY, KM_PRESS, 0, 0); /* only with lock view */ WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_cursor", HOMEKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_view_center_pick", FKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 576badf601e..b2f2d5849a4 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -967,6 +967,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event) WM_clipboard_text_set((void *) numstr, false); } } + break; } case RIGHTCTRLKEY: case LEFTCTRLKEY: diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index c119fe24210..16282b0d49c 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -609,7 +609,7 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo LassoSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; - if (EBONE_SELECTABLE(arm, ebone)) { + if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) { bool is_point_done = false; int points_proj_tot = 0; @@ -856,6 +856,7 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, break; default: assert(!"lasso select on incorrect object type"); + break; } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data); @@ -1907,7 +1908,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool int index = buffer[(4 * a) + 3]; if (index != -1) { ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (index & BONESEL_TIP) { ebone->flag |= BONE_DONE; if (select) ebone->flag |= BONE_TIPSEL; @@ -1937,7 +1938,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool if (index != -1) { ebone = BLI_findlink(arm->edbo, index & ~(BONESEL_ANY)); if (index & BONESEL_BONE) { - if ((ebone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((ebone->flag & BONE_UNSELECTABLE) == 0)) { if (!(ebone->flag & BONE_DONE)) { if (select) ebone->flag |= (BONE_ROOTSEL | BONE_TIPSEL | BONE_SELECTED); @@ -1974,7 +1975,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b if (bone_only) { CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) { - if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) { + if ((select == false) || ((pchan->bone->flag & BONE_UNSELECTABLE) == 0)) { pchan->bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); } } @@ -2110,6 +2111,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) break; default: assert(!"border select on incorrect object type"); + break; } } else { /* no editmode, unified for bones and objects */ @@ -2622,7 +2624,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB CircleSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; - if (EBONE_SELECTABLE(arm, ebone)) { + if (data->select ? EBONE_SELECTABLE(arm, ebone) : EBONE_VISIBLE(arm, ebone)) { bool is_point_done = false; int points_proj_tot = 0; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 1678487d8bf..0f2f07a1053 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -64,7 +64,8 @@ #include "WM_api.h" #include "WM_types.h" - +#include "RNA_access.h" +#include "RNA_define.h" #include "ED_armature.h" #include "ED_mesh.h" @@ -74,13 +75,13 @@ #include "view3d_intern.h" -extern float originmat[3][3]; /* XXX object.c */ - /* ************************************************** */ /* ********************* old transform stuff ******** */ /* *********** will get replaced with new transform * */ /* ************************************************** */ +static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]); + typedef struct TransVert { float *loc; float oldloc[3], maploc[3]; @@ -342,7 +343,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod if (transvmain && em->derivedCage) { EDBM_index_arrays_ensure(em, BM_VERT); - em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata); + em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata, DM_FOREACH_NOP); } } else if (obedit->type == OB_ARMATURE) { @@ -531,7 +532,7 @@ static void make_trans_verts(Object *obedit, float min[3], float max[3], int mod /* *********************** operators ******************** */ -static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) +static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); @@ -628,7 +629,8 @@ static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op)) vec[2] = -ob->obmat[3][2] + gridf * floorf(0.5f + ob->obmat[3][2] / gridf); if (ob->parent) { - BKE_object_where_is_calc(scene, ob); + float originmat[3][3]; + BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); invert_m3_m3(imat, originmat); mul_m3_v3(imat, vec); @@ -658,11 +660,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Selection to Grid"; - ot->description = "Snap selected item(s) to nearest grid node"; + ot->description = "Snap selected item(s) to nearest grid division"; ot->idname = "VIEW3D_OT_snap_selected_to_grid"; /* api callbacks */ - ot->exec = snap_sel_to_grid; + ot->exec = snap_sel_to_grid_exec; ot->poll = ED_operator_region_view3d_active; /* flags */ @@ -671,18 +673,30 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot) /* *************************************************** */ -static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) +static int snap_sel_to_curs_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); TransVert *tv; - float *curs, imat[3][3], bmat[3][3], vec[3]; + float imat[3][3], bmat[3][3]; + const float *cursor_global; + float center_global[3]; + float offset_global[3]; int a; - curs = give_cursor(scene, v3d); + const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); + + cursor_global = give_cursor(scene, v3d); + + if (use_offset) { + snap_curs_to_sel_ex(C, center_global); + sub_v3_v3v3(offset_global, cursor_global, center_global); + } if (obedit) { + float cursor_local[3]; + tottrans = 0; if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)) @@ -692,11 +706,25 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) copy_m3_m4(bmat, obedit->obmat); invert_m3_m3(imat, bmat); - tv = transvmain; - for (a = 0; a < tottrans; a++, tv++) { - sub_v3_v3v3(vec, curs, obedit->obmat[3]); - mul_m3_v3(imat, vec); - copy_v3_v3(tv->loc, vec); + /* get the cursor in object space */ + sub_v3_v3v3(cursor_local, cursor_global, obedit->obmat[3]); + mul_m3_v3(imat, cursor_local); + + if (use_offset) { + float offset_local[3]; + + mul_v3_m3v3(offset_local, imat, offset_global); + + tv = transvmain; + for (a = 0; a < tottrans; a++, tv++) { + add_v3_v3(tv->loc, offset_local); + } + } + else { + tv = transvmain; + for (a = 0; a < tottrans; a++, tv++) { + copy_v3_v3(tv->loc, cursor_local); + } } special_transvert_update(obedit); @@ -712,25 +740,36 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) if (ob->mode & OB_MODE_POSE) { bPoseChannel *pchan; bArmature *arm = ob->data; + float cursor_local[3]; invert_m4_m4(ob->imat, ob->obmat); - copy_v3_v3(vec, curs); - mul_m4_v3(ob->imat, vec); - + mul_v3_m4v3(cursor_local, ob->imat, cursor_global); + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->bone->flag & BONE_SELECTED) { - if (pchan->bone->layer & arm->layer) { + if (PBONE_VISIBLE(arm, pchan->bone)) { if ((pchan->bone->flag & BONE_CONNECTED) == 0) { /* Get position in pchan (pose) space. */ - BKE_armature_loc_pose_to_bone(pchan, vec, vec); + float cursor_pose[3]; + + if (use_offset) { + mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]); + add_v3_v3(cursor_pose, offset_global); + + mul_m4_v3(ob->imat, cursor_pose); + BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose); + } + else { + BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose); + } /* copy new position */ if ((pchan->protectflag & OB_LOCK_LOCX) == 0) - pchan->loc[0] = vec[0]; + pchan->loc[0] = cursor_pose[0]; if ((pchan->protectflag & OB_LOCK_LOCY) == 0) - pchan->loc[1] = vec[1]; + pchan->loc[1] = cursor_pose[1]; if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) - pchan->loc[2] = vec[2]; + pchan->loc[2] = cursor_pose[2]; /* auto-keyframing */ ED_autokeyframe_pchan(C, scene, ob, pchan, ks); @@ -746,22 +785,30 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op)) DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { - vec[0] = -ob->obmat[3][0] + curs[0]; - vec[1] = -ob->obmat[3][1] + curs[1]; - vec[2] = -ob->obmat[3][2] + curs[2]; + float cursor_parent[3]; /* parent-relative */ + + if (use_offset) { + add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global); + } + else { + copy_v3_v3(cursor_parent, cursor_global); + } + + sub_v3_v3(cursor_parent, ob->obmat[3]); if (ob->parent) { - BKE_object_where_is_calc(scene, ob); + float originmat[3][3]; + BKE_object_where_is_calc_ex(scene, NULL, ob, originmat); invert_m3_m3(imat, originmat); - mul_m3_v3(imat, vec); + mul_m3_v3(imat, cursor_parent); } if ((ob->protectflag & OB_LOCK_LOCX) == 0) - ob->loc[0] += vec[0]; + ob->loc[0] += cursor_parent[0]; if ((ob->protectflag & OB_LOCK_LOCY) == 0) - ob->loc[1] += vec[1]; + ob->loc[1] += cursor_parent[1]; if ((ob->protectflag & OB_LOCK_LOCZ) == 0) - ob->loc[2] += vec[2]; + ob->loc[2] += cursor_parent[2]; /* auto-keyframing */ ED_autokeyframe_object(C, scene, ob, ks); @@ -785,16 +832,19 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_selected_to_cursor"; /* api callbacks */ - ot->exec = snap_sel_to_curs; + ot->exec = snap_sel_to_curs_exec; ot->poll = ED_operator_view3d_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* rna */ + RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", ""); } /* *************************************************** */ -static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); RegionView3D *rv3d = CTX_wm_region_data(C); @@ -817,11 +867,11 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) { /* identifiers */ ot->name = "Snap Cursor to Grid"; - ot->description = "Snap cursor to nearest grid node"; + ot->description = "Snap cursor to nearest grid division"; ot->idname = "VIEW3D_OT_snap_cursor_to_grid"; /* api callbacks */ - ot->exec = snap_curs_to_grid; + ot->exec = snap_curs_to_grid_exec; ot->poll = ED_operator_region_view3d_active; /* flags */ @@ -882,28 +932,29 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) } } -static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) +static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); TransVert *tv; - float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3]; + float bmat[3][3], vec[3], min[3], max[3], centroid[3]; int count, a; - curs = give_cursor(scene, v3d); - count = 0; INIT_MINMAX(min, max); zero_v3(centroid); if (obedit) { tottrans = 0; - + if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL)) make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS | TM_SKIP_HANDLES); - if (tottrans == 0) return OPERATOR_CANCELLED; - + + if (tottrans == 0) { + return false; + } + copy_m3_m4(bmat, obedit->obmat); tv = transvmain; @@ -917,10 +968,10 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) if (v3d->around == V3D_CENTROID) { mul_v3_fl(centroid, 1.0f / (float)tottrans); - copy_v3_v3(curs, centroid); + copy_v3_v3(cursor, centroid); } else { - mid_v3_v3v3(curs, min, max); + mid_v3_v3v3(cursor, min, max); } MEM_freeN(transvmain); transvmain = NULL; @@ -962,19 +1013,38 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) } CTX_DATA_END; } - if (count) { - if (v3d->around == V3D_CENTROID) { - mul_v3_fl(centroid, 1.0f / (float)count); - copy_v3_v3(curs, centroid); - } - else { - mid_v3_v3v3(curs, min, max); - } + + if (count == 0) { + return false; + } + + if (v3d->around == V3D_CENTROID) { + mul_v3_fl(centroid, 1.0f / (float)count); + copy_v3_v3(cursor, centroid); + } + else { + mid_v3_v3v3(cursor, min, max); } } - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); - - return OPERATOR_FINISHED; + return true; +} + +static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + float *curs; + + curs = give_cursor(scene, v3d); + + if (snap_curs_to_sel_ex(C, curs)) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) @@ -985,7 +1055,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_selected"; /* api callbacks */ - ot->exec = snap_curs_to_sel; + ot->exec = snap_curs_to_sel_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -994,7 +1064,7 @@ void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot) /* ********************************************** */ -static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_active_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); @@ -1043,7 +1113,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_active"; /* api callbacks */ - ot->exec = snap_curs_to_active; + ot->exec = snap_curs_to_active_exec; ot->poll = ED_operator_view3d_active; /* flags */ @@ -1052,7 +1122,7 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) /* **************************************************** */ /*New Code - Snap Cursor to Center -*/ -static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op)) +static int snap_curs_to_center_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -1074,7 +1144,7 @@ void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot) ot->idname = "VIEW3D_OT_snap_cursor_to_center"; /* api callbacks */ - ot->exec = snap_curs_to_center; + ot->exec = snap_curs_to_center_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c index ebb9a7b8c81..bdb203ab003 100644 --- a/source/blender/editors/space_view3d/view3d_toolbar.c +++ b/source/blender/editors/space_view3d/view3d_toolbar.c @@ -195,7 +195,7 @@ static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase) uiBlockSetDirection(block, UI_DOWN); uiEndBlock(C, block); - event = *(win->eventstate); /* XXX huh huh? make api call */ + wm_event_init_from_window(win, &event); event.type = EVT_BUT_OPEN; event.val = KM_PRESS; event.customdata = but; @@ -258,7 +258,7 @@ void view3d_tool_props_register(ARegionType *art) /* ********** operator to open/close toolshelf region */ -static int view3d_toolshelf(bContext *C, wmOperator *UNUSED(op)) +static int view3d_toolshelf_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = view3d_has_tools_region(sa); @@ -275,7 +275,7 @@ void VIEW3D_OT_toolshelf(wmOperatorType *ot) ot->description = "Toggles tool shelf display"; ot->idname = "VIEW3D_OT_toolshelf"; - ot->exec = view3d_toolshelf; + ot->exec = view3d_toolshelf_toggle_exec; ot->poll = ED_operator_view3d_active; /* flags */ diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index a3421295464..4a14aa79e41 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -202,7 +202,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera } /* skip smooth viewing for render engine draw */ - if (C && U.smooth_viewtx && v3d->drawtype != OB_RENDER) { + if (U.smooth_viewtx && v3d->drawtype != OB_RENDER) { bool changed = false; /* zero means no difference */ if (oldcamera != camera) @@ -753,7 +753,7 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect) glGetFloatv(GL_PROJECTION_MATRIX, (float *)rv3d->winmat); } -static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short smooth) +static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob) { float bmat[4][4]; float tmat[3][3]; @@ -766,36 +766,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short /* view quat calculation, needed for add object */ copy_m3_m4(tmat, rv3d->viewmat); - if (smooth) { - float new_quat[4]; - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { - /* were from a camera view */ - - float orig_ofs[3]; - float orig_dist = rv3d->dist; - float orig_lens = v3d->lens; - copy_v3_v3(orig_ofs, rv3d->ofs); - - /* Switch from camera view */ - mat3_to_quat(new_quat, tmat); - - rv3d->persp = RV3D_PERSP; - rv3d->dist = 0.0; - - ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */ - - rv3d->persp = RV3D_CAMOB; /* just to be polite, not needed */ - - } - else { - mat3_to_quat(new_quat, tmat); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */ - } - } - else { - mat3_to_quat(rv3d->viewquat, tmat); - } + mat3_to_quat(rv3d->viewquat, tmat); } #define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0 @@ -839,7 +810,7 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */ if (v3d->camera) { BKE_object_where_is_calc(scene, v3d->camera); - obmat_to_viewmat(v3d, rv3d, v3d->camera, 0); + obmat_to_viewmat(rv3d, v3d->camera); } else { quat_to_mat4(rv3d->viewmat, rv3d->viewquat); @@ -847,6 +818,9 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) } } else { + bool use_lock_ofs = false; + + /* should be moved to better initialize later on XXX */ if (rv3d->viewlock) ED_view3d_lock(rv3d); @@ -866,15 +840,34 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d) } } translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); + use_lock_ofs = true; } else if (v3d->ob_centre_cursor) { float vec[3]; copy_v3_v3(vec, give_cursor(scene, v3d)); translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]); + use_lock_ofs = true; } else { translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]); } + + /* lock offset */ + if (use_lock_ofs) { + float persmat[4][4], persinv[4][4]; + float vec[3]; + + /* we could calculate the real persmat/persinv here + * but it would be unreliable so better to later */ + mul_m4_m4m4(persmat, rv3d->winmat, rv3d->viewmat); + invert_m4_m4(persinv, persmat); + + mul_v2_v2fl(vec, rv3d->ofs_lock, rv3d->is_persp ? rv3d->dist : 1.0f); + vec[2] = 0.0f; + mul_mat3_m4_v3(persinv, vec); + translate_m4(rv3d->viewmat, vec[0], vec[1], vec[2]); + } + /* end lock offset */ } } @@ -1540,40 +1533,6 @@ void VIEW3D_OT_game_start(wmOperatorType *ot) /* ************************************** */ -static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView3D *rv3d, int axisidx, float vec[3]) -{ - float alignaxis[3] = {0.0, 0.0, 0.0}; - float norm[3], axis[3], angle, new_quat[4]; - - if (axisidx > 0) alignaxis[axisidx - 1] = 1.0; - else alignaxis[-axisidx - 1] = -1.0; - - normalize_v3_v3(norm, vec); - - angle = (float)acos(dot_v3v3(alignaxis, norm)); - cross_v3_v3v3(axis, alignaxis, norm); - axis_angle_to_quat(new_quat, axis, -angle); - - rv3d->view = RV3D_VIEW_USER; - - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { - /* switch out of camera view */ - float orig_ofs[3]; - float orig_dist = rv3d->dist; - float orig_lens = v3d->lens; - - copy_v3_v3(orig_ofs, rv3d->ofs); - rv3d->persp = RV3D_PERSP; - rv3d->dist = 0.0; - ED_view3d_from_object(v3d->camera, rv3d->ofs, NULL, NULL, &v3d->lens); - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, orig_ofs, new_quat, &orig_dist, &orig_lens); /* XXX */ - } - else { - if (rv3d->persp == RV3D_CAMOB) rv3d->persp = RV3D_PERSP; /* switch out of camera mode */ - view3d_smooth_view(NULL, NULL, NULL, NULL, NULL, NULL, new_quat, NULL, NULL); /* XXX */ - } -} - float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3]) { return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5ad5636bb21..6c854ef6795 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -59,10 +59,8 @@ #include "BLI_string.h" #include "BLI_ghash.h" #include "BLI_linklist.h" -#include "BLI_smallhash.h" #include "BKE_nla.h" -#include "BKE_bmesh.h" #include "BKE_editmesh_bvh.h" #include "BKE_context.h" #include "BKE_constraint.h" @@ -112,9 +110,7 @@ static bool transdata_check_local_center(TransInfo *t) { return ((t->around == V3D_LOCAL) && ( (t->flag & (T_OBJECT | T_POSE)) || - (t->obedit && t->obedit->type == OB_MESH && (t->settings->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_FACE))) || - (t->obedit && t->obedit->type == OB_MBALL) || - (t->obedit && t->obedit->type == OB_ARMATURE) || + (t->obedit && ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE)) || (t->spacetype == SPACE_IPO)) ); } @@ -1433,6 +1429,7 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size) offset = -offset; length = -length; size = -size; + /* fall-through */ case RIGHT: glBegin(GL_LINES); glVertex2s(offset, 0); @@ -1443,10 +1440,12 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size) glVertex2s(offset + length - size, size); glEnd(); break; + case DOWN: offset = -offset; length = -length; size = -size; + /* fall-through */ case UP: glBegin(GL_LINES); glVertex2s(0, offset); @@ -1465,6 +1464,7 @@ static void drawArrowHead(ArrowDirection d, short size) switch (d) { case LEFT: size = -size; + /* fall-through */ case RIGHT: glBegin(GL_LINES); glVertex2s(0, 0); @@ -1473,8 +1473,10 @@ static void drawArrowHead(ArrowDirection d, short size) glVertex2s(-size, size); glEnd(); break; + case DOWN: size = -size; + /* fall-through */ case UP: glBegin(GL_LINES); glVertex2s(0, 0); @@ -1676,9 +1678,9 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) */ UI_ThemeColorShade(TH_TEXT_HI, -50); #ifdef WITH_INTERNATIONAL - BLF_draw_default(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); + BLF_draw_default(xco, ar->winy - 17, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); #else - BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, BLF_DRAW_STR_DUMMY_MAX); #endif /* autokey recording icon... */ @@ -1748,6 +1750,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) break; default: proportional = PROP_EDIT_OFF; + break; } // If modal, save settings back in scene if not set as operator argument @@ -2003,8 +2006,8 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even initBoneEnvelope(t); else initBoneSize(t); + break; } - break; case TFM_BONE_ENVELOPE: initBoneEnvelope(t); break; @@ -2935,6 +2938,7 @@ static void headerResize(TransInfo *t, float vec[3], char *str) case 2: ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext); + break; } } else { @@ -3901,6 +3905,7 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str) ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, autoik); + break; } } else { @@ -4995,8 +5000,7 @@ static bool createEdgeSlideVerts(TransInfo *t) TransDataEdgeSlideVert *sv_array; int sv_tot; BMBVHTree *btree; - /* BMVert -> sv_array index */ - SmallHash table; + int *sv_table; /* BMVert -> sv_array index */ EdgeSlideData *sld = MEM_callocN(sizeof(*sld), "sld"); View3D *v3d = NULL; RegionView3D *rv3d = NULL; @@ -5014,6 +5018,17 @@ static bool createEdgeSlideVerts(TransInfo *t) rv3d = t->ar ? t->ar->regiondata : NULL; } + if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) && + /* don't do this at all for non-basis shape keys, too easy to + * accidentally break uv maps or vertex colors then */ + (bm->shapenr <= 1)) + { + sld->use_origfaces = true; + } + else { + sld->use_origfaces = false; + } + sld->is_proportional = true; sld->curr_sv_index = 0; sld->flipped_vtx = FALSE; @@ -5025,11 +5040,7 @@ static bool createEdgeSlideVerts(TransInfo *t) else { ED_view3d_ob_project_mat_get(rv3d, t->obedit, projectMat); } - - BLI_smallhash_init(&sld->vhash); - BLI_smallhash_init(&sld->origfaces); - BLI_smallhash_init(&table); - + /*ensure valid selection*/ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { @@ -5063,20 +5074,26 @@ static bool createEdgeSlideVerts(TransInfo *t) } } + sv_table = MEM_mallocN(sizeof(*sv_table) * bm->totvert, __func__); + j = 0; - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { BM_elem_flag_enable(v, BM_ELEM_TAG); - BLI_smallhash_insert(&table, (uintptr_t)v, SET_INT_IN_POINTER(j)); + sv_table[i] = j; j += 1; } else { BM_elem_flag_disable(v, BM_ELEM_TAG); + sv_table[i] = -1; } + BM_elem_index_set(v, i); /* set_inline */ } + bm->elem_index_dirty &= ~BM_VERT; if (!j) { MEM_freeN(sld); + MEM_freeN(sv_table); return false; } @@ -5173,9 +5190,9 @@ static bool createEdgeSlideVerts(TransInfo *t) BMEdge *e_prev; /* XXX, 'sv' will initialize multiple times, this is suspicious. see [#34024] */ - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); BLI_assert(v != NULL); - sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + sv = &sv_array[sv_table[BM_elem_index_get(v)]]; sv->v = v; copy_v3_v3(sv->v_co_orig, v->co); sv->loop_nr = loop_nr; @@ -5199,9 +5216,9 @@ static bool createEdgeSlideVerts(TransInfo *t) e = get_other_edge(v, e); if (!e) { - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); BLI_assert(v != NULL); - sv = sv_array + GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + sv = &sv_array[sv_table[BM_elem_index_get(v)]]; sv->v = v; copy_v3_v3(sv->v_co_orig, v->co); sv->loop_nr = loop_nr; @@ -5268,7 +5285,6 @@ static bool createEdgeSlideVerts(TransInfo *t) loop_nr++; } - /* use for visibility checks */ use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); @@ -5316,8 +5332,8 @@ static bool createEdgeSlideVerts(TransInfo *t) continue; } - BLI_assert(BLI_smallhash_haskey(&table, (uintptr_t)v) != false); - j = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&table, (uintptr_t)v)); + BLI_assert(sv_table[BM_elem_index_get(v)] != -1); + j = sv_table[BM_elem_index_get(v)]; if (sv_array[j].v_b) { ED_view3d_project_float_v3_m4(ar, sv_array[j].v_b->co, sco_b, projectMat); @@ -5364,33 +5380,29 @@ static bool createEdgeSlideVerts(TransInfo *t) bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); + if (sld->use_origfaces) { + sld->origfaces = BLI_ghash_ptr_new(__func__); + sld->bm_origfaces = BM_mesh_create(&bm_mesh_allocsize_default); + /* we need to have matching customdata */ + BM_mesh_copy_init_customdata(sld->bm_origfaces, bm, NULL); + } + /*create copies of faces for customdata projection*/ sv_array = sld->sv; for (i = 0; i < sld->totsv; i++, sv_array++) { - BMIter fiter, liter; + BMIter fiter; BMFace *f; - BMLoop *l; - BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) { - - if (!BLI_smallhash_haskey(&sld->origfaces, (uintptr_t)f)) { - BMFace *copyf = BM_face_copy(bm, f, true, true); - - BM_face_select_set(bm, copyf, false); - BM_elem_flag_enable(copyf, BM_ELEM_HIDDEN); - BM_ITER_ELEM (l, &liter, copyf, BM_LOOPS_OF_FACE) { - BM_vert_select_set(bm, l->v, false); - BM_elem_flag_enable(l->v, BM_ELEM_HIDDEN); - BM_edge_select_set(bm, l->e, false); - BM_elem_flag_enable(l->e, BM_ELEM_HIDDEN); - } - BLI_smallhash_insert(&sld->origfaces, (uintptr_t)f, copyf); + if (sld->use_origfaces) { + BM_ITER_ELEM (f, &fiter, sv_array->v, BM_FACES_OF_VERT) { + if (!BLI_ghash_haskey(sld->origfaces, f)) { + BMFace *f_copy = BM_face_copy(sld->bm_origfaces, bm, f, true, true); + BLI_ghash_insert(sld->origfaces, f, f_copy); + } } } - BLI_smallhash_insert(&sld->vhash, (uintptr_t)sv_array->v, sv_array); - /* switch a/b if loop direction is different from global direction */ l_nr = sv_array->loop_nr; if (dot_v3v3(loop_dir[l_nr], mval_dir) < 0.0f) { @@ -5402,9 +5414,8 @@ static bool createEdgeSlideVerts(TransInfo *t) if (rv3d) calcNonProportionalEdgeSlide(t, sld, mval); - sld->origfaces_init = true; sld->em = em; - + /*zero out start*/ zero_v2(mval_start); @@ -5422,16 +5433,13 @@ static bool createEdgeSlideVerts(TransInfo *t) t->customData = sld; - BLI_smallhash_release(&table); + MEM_freeN(sv_table); if (btree) { BKE_bmbvh_free(btree); } MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); - /* arrays are dirty from copying faces: EDBM_index_arrays_free */ - EDBM_update_generic(em, false, true); - return true; } @@ -5442,17 +5450,10 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) BMEditMesh *em = sld->em; int i; - if (!em) - return; - - if (!(t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT)) + if (sld->use_origfaces == false) { return; + } - /* don't do this at all for non-basis shape keys, too easy to - * accidentally break uv maps or vertex colors then */ - if (em->bm->shapenr > 1) - return; - for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { BMIter fiter; BMLoop *l; @@ -5460,15 +5461,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { BMFace *f_copy; /* the copy of 'f' */ BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ - bool is_sel, is_hide; - /* the face attributes of the copied face will get - * copied over, so its necessary to save the selection - * and hidden state*/ - is_sel = BM_elem_flag_test(l->f, BM_ELEM_SELECT) != 0; - is_hide = BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) != 0; - - f_copy = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l->f); + f_copy = BLI_ghash_lookup(sld->origfaces, l->f); /* project onto copied projection face */ f_copy_flip = f_copy; @@ -5482,12 +5476,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) if (sld->perc < 0.0f) { if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_b)) { - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); } } else if (sld->perc > 0.0f) { if (BM_vert_in_face(l_ed_sel->radial_next->f, sv->v_a)) { - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_ed_sel->radial_next->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_ed_sel->radial_next->f); } } @@ -5573,7 +5567,7 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) l_adj = l; } - f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)l_adj->f); + f_copy_flip = BLI_ghash_lookup(sld->origfaces, l_adj->f); } } } @@ -5590,36 +5584,23 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) } /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(em->bm, em->bm, f_copy, l->f); - - /* restore selection and hidden flags */ - BM_face_select_set(em->bm, l->f, is_sel); - if (!is_hide) { - /* this check is a workaround for bug, see note - [#30735], - * without this edge can be hidden and selected */ - BM_elem_hide_set(em->bm, l->f, is_hide); - } + BM_elem_attrs_copy(sld->bm_origfaces, em->bm, f_copy, l->f); } } } void freeEdgeSlideTempFaces(EdgeSlideData *sld) { - if (sld->origfaces_init) { - SmallHashIter hiter; - BMFace *copyf; - - copyf = BLI_smallhash_iternew(&sld->origfaces, &hiter, NULL); - for (; copyf; copyf = BLI_smallhash_iternext(&hiter, NULL)) { - BM_face_verts_kill(sld->em->bm, copyf); + if (sld->use_origfaces) { + if (sld->bm_origfaces) { + BM_mesh_free(sld->bm_origfaces); + sld->bm_origfaces = NULL; } - BLI_smallhash_release(&sld->origfaces); - - sld->origfaces_init = false; - - /* arrays are dirty from removing faces: EDBM_index_arrays_free */ - EDBM_update_generic(sld->em, FALSE, TRUE); + if (sld->origfaces) { + BLI_ghash_free(sld->origfaces, NULL, NULL); + sld->origfaces = NULL; + } } } @@ -5628,30 +5609,12 @@ void freeEdgeSlideVerts(TransInfo *t) { EdgeSlideData *sld = t->customData; -#if 0 /*BMESH_TODO*/ - if (me->drawflag & ME_DRAWEXTRA_EDGELEN) { - TransDataEdgeSlideVert *sv; - LinkNode *look = sld->vertlist; - GHash *vertgh = sld->vhash; - while (look) { - sv = BLI_ghash_lookup(vertgh, (EditVert *)look->link); - if (sv != NULL) { - sv->v_a->f &= !SELECT; - sv->v_b->f &= !SELECT; - } - look = look->next; - } - } -#endif - if (!sld) return; freeEdgeSlideTempFaces(sld); bmesh_edit_end(sld->em->bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); - - BLI_smallhash_release(&sld->vhash); MEM_freeN(sld->sv); MEM_freeN(sld); @@ -5733,6 +5696,7 @@ int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) break; } } + break; } default: break; @@ -6265,6 +6229,7 @@ int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) calcVertSlideMouseActiveEdges(t, event->mval); } calcVertSlideCustomPoints(t); + break; } default: break; @@ -7390,7 +7355,7 @@ bool checkUseAxisMatrix(TransInfo *t) { /* currenly only checks for editmode */ if (t->flag & T_EDIT) { - if ((t->around == V3D_LOCAL) && (ELEM3(t->obedit->type, OB_MESH, OB_MBALL, OB_ARMATURE))) { + if ((t->around == V3D_LOCAL) && (ELEM4(t->obedit->type, OB_MESH, OB_CURVE, OB_MBALL, OB_ARMATURE))) { /* not all editmode supports axis-matrix */ return true; } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index d160e1562b0..4a1c4203a43 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -201,14 +201,14 @@ typedef struct EdgeSlideData { TransDataEdgeSlideVert *sv; int totsv; - struct SmallHash vhash; - struct SmallHash origfaces; + struct GHash *origfaces; int mval_start[2], mval_end[2]; struct BMEditMesh *em; /* flag that is set when origfaces is initialized */ - bool origfaces_init; + bool use_origfaces; + struct BMesh *bm_origfaces; float perc; @@ -725,7 +725,7 @@ void initTransformOrientation(struct bContext *C, TransInfo *t); /* Those two fill in mat and return non-zero on success */ bool createSpaceNormal(float mat[3][3], const float normal[3]); -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]); struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite); void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 27b25a50eff..fd8fba91fc9 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -621,8 +621,8 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte float mtx[3][3] = MAT3_UNITY; BLI_snprintf(text, sizeof(text), ftext, IFACE_("global")); setConstraint(t, mtx, mode, text); + break; } - break; case V3D_MANIP_LOCAL: BLI_snprintf(text, sizeof(text), ftext, IFACE_("local")); setLocalConstraint(t, mode, text); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a089f0d4159..b154acc7456 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -59,14 +59,12 @@ #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_array.h" #include "BLI_utildefines.h" #include "BLI_smallhash.h" #include "BKE_DerivedMesh.h" #include "BKE_action.h" #include "BKE_armature.h" -#include "BKE_bmesh.h" #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -124,6 +122,11 @@ #include "BLI_sys_types.h" // for intptr_t support +/* when transforming islands */ +struct TransIslandData { + float co[3]; + float axismtx[3][3]; +}; /* local function prototype - for Object/Bone Constraints */ static bool constraints_list_needinv(TransInfo *t, ListBase *list); @@ -1043,7 +1046,7 @@ static void createTransArmatureVerts(TransInfo *t) bArmature *arm = t->obedit->data; ListBase *edbo = arm->edbo; TransData *td; - float mtx[3][3], smtx[3][3], delta[3], bonemat[3][3]; + float mtx[3][3], smtx[3][3], bonemat[3][3]; /* special hack for envelope drawmode and scaling: * to allow scaling the size of the envelope around single points, @@ -1135,8 +1138,7 @@ static void createTransArmatureVerts(TransInfo *t) td->flag = TD_SELECTED; /* use local bone matrix */ - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, bonemat); + ED_armature_ebone_to_mat3(ebo, bonemat); mul_m3_m3m3(td->mtx, mtx, bonemat); invert_m3_m3(td->smtx, td->mtx); @@ -1176,8 +1178,7 @@ static void createTransArmatureVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, td->axismtx); + ED_armature_ebone_to_mat3(ebo, td->axismtx); if ((ebo->flag & BONE_ROOTSEL) == 0) { td->extra = ebo; @@ -1200,8 +1201,7 @@ static void createTransArmatureVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); - sub_v3_v3v3(delta, ebo->tail, ebo->head); - vec_roll_to_mat3(delta, ebo->roll, td->axismtx); + ED_armature_ebone_to_mat3(ebo, td->axismtx); td->extra = ebo; /* to fix roll */ @@ -1413,6 +1413,23 @@ static void createTransCurveVerts(TransInfo *t) for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { if (bezt->hide == 0) { TransDataCurveHandleFlags *hdata = NULL; + float axismtx[3][3]; + + if (t->around == V3D_LOCAL) { + float normal[3], plane[3]; + + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + + if (createSpaceNormalTangent(axismtx, normal, plane)) { + /* pass */ + } + else { + normalize_v3(normal); + axis_dominant_v3_to_m3(axismtx, normal); + invert_m3(axismtx); + } + } if (propmode || ((bezt->f2 & SELECT) && hide_handles) || @@ -1436,6 +1453,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; @@ -1465,6 +1485,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0) /* If the middle is selected but the sides arnt, this is needed */ @@ -1500,6 +1523,9 @@ static void createTransCurveVerts(TransInfo *t) copy_m3_m3(td->smtx, smtx); copy_m3_m3(td->mtx, mtx); + if (t->around == V3D_LOCAL) { + copy_m3_m3(td->axismtx, axismtx); + } td++; count++; @@ -1914,75 +1940,147 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float MEM_freeN(dists_prev); } -static BMElem *bm_vert_single_select_face(BMVert *eve) +static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r_island_tot, int **r_island_vert_map) { - BMElem *ele; - BMIter iter; + BMesh *bm = em->bm; + struct TransIslandData *trans_islands; + char htype; + char itype; + int i; + + /* group vars */ + int *groups_array; + int (*group_index)[2]; + int group_tot; + void **ele_array; + + int *vert_map; + + if (em->selectmode & (SCE_SELECT_VERTEX | SCE_SELECT_EDGE)) { + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totedgesel, __func__); + group_tot = BM_mesh_calc_edge_groups(bm, groups_array, &group_index, + NULL, NULL, + BM_ELEM_SELECT); + + htype = BM_EDGE; + itype = BM_VERTS_OF_EDGE; - BM_ITER_ELEM (ele, &iter, eve, BM_FACES_OF_VERT) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - return ele; - } } - return NULL; -} -static BMElem *bm_vert_single_select_edge(BMVert *eve) -{ - BMElem *ele; - BMIter iter; + else { /* (bm->selectmode & SCE_SELECT_FACE) */ + groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__); + group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index, + NULL, NULL, + BM_ELEM_SELECT, BM_VERT); + + htype = BM_FACE; + itype = BM_VERTS_OF_FACE; + } + + + trans_islands = MEM_mallocN(sizeof(*trans_islands) * group_tot, __func__); + + vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__); + /* we shouldn't need this, but with incorrect selection flushing + * its possible we have a selected vertex thats not in a face, for now best not crash in that case. */ + fill_vn_i(vert_map, bm->totvert, -1); - BM_ITER_ELEM (ele, &iter, eve, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) { - return ele; + EDBM_index_arrays_ensure(em, htype); + ele_array = (htype == BM_FACE) ? (void **)em->face_index : (void **)em->edge_index; + + BM_mesh_elem_index_ensure(bm, BM_VERT); + + /* may be an edge OR a face array */ + for (i = 0; i < group_tot; i++) { + BMEditSelection ese = {0}; + + const int fg_sta = group_index[i][0]; + const int fg_len = group_index[i][1]; + float co[3], no[3], tangent[3]; + int j; + + zero_v3(co); + zero_v3(no); + zero_v3(tangent); + + ese.htype = htype; + + /* loop on each face in this group: + * - assign r_vert_map + * - calculate (co, no) + */ + for (j = 0; j < fg_len; j++) { + float tmp_co[3], tmp_no[3], tmp_tangent[3]; + + ese.ele = ele_array[groups_array[fg_sta + j]]; + + BM_editselection_center(&ese, tmp_co); + BM_editselection_normal(&ese, tmp_no); + BM_editselection_plane(&ese, tmp_tangent); + + add_v3_v3(co, tmp_co); + add_v3_v3(no, tmp_no); + add_v3_v3(tangent, tmp_tangent); + + { + /* setup vertex map */ + BMIter iter; + BMVert *v; + + /* connected edge-verts */ + BM_ITER_ELEM (v, &iter, ese.ele, itype) { + vert_map[BM_elem_index_get(v)] = i; + } + } + } + + mul_v3_v3fl(trans_islands[i].co, co, 1.0f / (float)fg_len); + + if (createSpaceNormalTangent(trans_islands[i].axismtx, no, tangent)) { + /* pass */ + } + else { + normalize_v3(no); + axis_dominant_v3_to_m3(trans_islands[i].axismtx, no); + invert_m3(trans_islands[i].axismtx); } } - return NULL; + + MEM_freeN(groups_array); + MEM_freeN(group_index); + + *r_island_tot = group_tot; + *r_island_vert_map = vert_map; + + return trans_islands; } /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, - BMEditMesh *em, BMVert *eve, float *bweight) + BMEditMesh *em, BMVert *eve, float *bweight, + struct TransIslandData *v_island) { + BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); + td->flag = 0; //if (key) // td->loc = key->co; //else td->loc = eve->co; copy_v3_v3(td->iloc, td->loc); - copy_v3_v3(td->center, td->loc); - - if (t->around == V3D_LOCAL) { - BMElem *ele; - bool is_axismat_set = false; - - if (em->selectmode & (SCE_SELECT_FACE | SCE_SELECT_EDGE) && - (ele = ((em->selectmode & SCE_SELECT_FACE) ? - bm_vert_single_select_face(eve) : - bm_vert_single_select_edge(eve)))) - { - float normal[3], tangent[3]; - - BMEditSelection ese; - ese.next = ese.prev = NULL; - ese.ele = ele; - ese.htype = ele->head.htype; - BM_editselection_center(&ese, td->center); - BM_editselection_normal(&ese, normal); - BM_editselection_plane(&ese, tangent); - - if (createSpaceNormalTangent(td->axismtx, normal, tangent)) { - is_axismat_set = true; - } - } + if (v_island) { + copy_v3_v3(td->center, v_island->co); + copy_m3_m3(td->axismtx, v_island->axismtx); + } + else if (t->around == V3D_LOCAL) { + copy_v3_v3(td->center, td->loc); - /* for verts or fallback when createSpaceNormalTangent fails */ - if (is_axismat_set == false) { - axis_dominant_v3_to_m3(td->axismtx, eve->no); - invert_m3(td->axismtx); - } + axis_dominant_v3_to_m3(td->axismtx, eve->no); + invert_m3(td->axismtx); } else { + copy_v3_v3(td->center, td->loc); + /* Setting normals */ copy_v3_v3(td->axismtx[2], eve->no); td->axismtx[0][0] = @@ -2019,7 +2117,6 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx static void createTransEditVerts(TransInfo *t) { - ToolSettings *ts = t->scene->toolsettings; TransData *tob = NULL; TransDataExtension *tx = NULL; BMEditMesh *em = BKE_editmesh_from_object(t->obedit); @@ -2031,85 +2128,42 @@ static void createTransEditVerts(TransInfo *t) float *mappedcos = NULL, *quats = NULL; float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; float *dists = NULL; - int count = 0, countsel = 0, a, totleft; + int a; int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0; int mirror = 0; - char *selstate = NULL; - short selectmode = ts->selectmode; int cd_vert_bweight_offset = -1; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; + struct TransIslandData *island_info = NULL; + int island_info_tot; + int *island_vert_map = NULL; + if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology); mirror = 1; } - /* edge slide forces edge select */ - if (t->mode == TFM_EDGE_SLIDE) { - selectmode = SCE_SELECT_EDGE; - } - - /* BMESH_TODO, writing into the index values is BAD!, means we cant - * use the values for vertex mirror - campbell */ - - // transform now requires awareness for select mode, so we tag the f1 flags in verts - if (selectmode & SCE_SELECT_VERTEX) { - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - BM_elem_flag_set(eve, BM_ELEM_TAG, BM_elem_flag_test(eve, BM_ELEM_SELECT)); + /* quick check if we can transform */ + /* note: in prop mode we need at least 1 selected */ + if (em->selectmode & SCE_SELECT_VERTEX) { + if (bm->totvertsel == 0) { + goto cleanup; } } - else if (selectmode & SCE_SELECT_EDGE) { - BMEdge *eed; - - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (; eve; eve = BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); - - eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL); - for (; eed; eed = BM_iter_step(&iter)) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - BM_elem_flag_enable(eed->v1, BM_ELEM_TAG); - BM_elem_flag_enable(eed->v2, BM_ELEM_TAG); - } + else if (em->selectmode & SCE_SELECT_EDGE) { + if (bm->totvertsel == 0 || bm->totedgesel == 0) { + goto cleanup; } } - else { - BMFace *efa; - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (; eve; eve = BM_iter_step(&iter)) BM_elem_flag_disable(eve, BM_ELEM_TAG); - - efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); - for (; efa; efa = BM_iter_step(&iter)) { - if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - BMIter liter; - BMLoop *l; - - l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, efa); - for (; l; l = BM_iter_step(&liter)) { - BM_elem_flag_enable(l->v, BM_ELEM_TAG); - } - } + else if (em->selectmode & SCE_SELECT_FACE) { + if (bm->totvertsel == 0 || bm->totfacesel == 0) { + goto cleanup; } } - - /* now we can count. we store selection state in selstate, since - * get_crazy_mapped_editverts messes up the index state of the - * verts*/ - selstate = MEM_callocN(sizeof(*selstate) * bm->totvert, __func__); - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a = 0; eve; eve = BM_iter_step(&iter), a++) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - if (BM_elem_flag_test(eve, BM_ELEM_TAG)) { - selstate[a] = 1; - countsel++; - } - if (propmode) count++; - } + else { + BLI_assert(0); } - /* note: in prop mode we need at least 1 selected */ - if (countsel == 0) { - goto cleanup; - } /* check active */ eve_act = BM_mesh_active_vert_get(bm); @@ -2120,6 +2174,13 @@ static void createTransEditVerts(TransInfo *t) } if (propmode) { + unsigned int count = 0; + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + count++; + } + } + t->total = count; /* allocating scratch arrays */ @@ -2127,7 +2188,7 @@ static void createTransEditVerts(TransInfo *t) dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears"); } else { - t->total = countsel; + t->total = bm->totvertsel; } tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)"); @@ -2149,9 +2210,17 @@ static void createTransEditVerts(TransInfo *t) editmesh_set_connectivity_distance(em->bm, mtx, dists); } + if (t->around == V3D_LOCAL) { + island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map); + } + + /* BMESH_TODO, crazy-space writing into the index values is BAD!, means we cant + * use the values for vertex mirror - campbell */ + /* detect CrazySpace [tm] */ if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) >= 0) { if (modifiers_isCorrectableDeformed(t->obedit)) { + int totleft; /* check if we can use deform matrices for modifier from the * start up to stack, they are more accurate than quats */ totleft = editbmesh_get_first_deform_matrices(t->scene, t->obedit, em, &defmats, &defcos); @@ -2174,9 +2243,8 @@ static void createTransEditVerts(TransInfo *t) /* find out which half we do */ if (mirror) { - eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); - for (a = 0; eve; eve = BM_iter_step(&iter), a++) { - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && selstate[a] && eve->co[0] != 0.0f) { + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) { if (eve->co[0] < 0.0f) { t->mirror = -1; mirror = -1; @@ -2188,15 +2256,18 @@ static void createTransEditVerts(TransInfo *t) BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - if (propmode || selstate[a]) { + if (propmode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ? + &island_info[island_vert_map[a]] : NULL; float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL; - - VertsToTransData(t, tob, tx, em, eve, bweight); + + VertsToTransData(t, tob, tx, em, eve, bweight, v_island); if (tx) tx++; /* selected */ - if (selstate[a]) tob->flag |= TD_SELECTED; + if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) + tob->flag |= TD_SELECTED; /* active */ if (eve == eve_act) tob->flag |= TD_ACTIVE; @@ -2250,6 +2321,11 @@ static void createTransEditVerts(TransInfo *t) } } + if (island_info) { + MEM_freeN(island_info); + MEM_freeN(island_vert_map); + } + if (mirror != 0) { tob = t->data; for (a = 0; a < t->total; a++, tob++) { @@ -2267,12 +2343,9 @@ cleanup: MEM_freeN(defmats); if (dists) MEM_freeN(dists); - - MEM_freeN(selstate); if (t->flag & T_MIRROR) { EDBM_verts_mirror_cache_end(em); - mirror = 1; } } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 666612880e5..cb0a0530036 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1667,7 +1667,7 @@ void calculateCenter(TransInfo *t) projectIntView(t, t->center, t->center2d); } } - + break; } } @@ -1803,6 +1803,7 @@ void calculatePropRatio(TransInfo *t) break; default: td->factor = 1; + break; } } } @@ -1830,6 +1831,7 @@ void calculatePropRatio(TransInfo *t) break; default: t->proptext[0] = '\0'; + break; } } else { diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 5059e3bcc40..6fecf0d6642 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -602,7 +602,7 @@ int calc_manipulator_stats(const bContext *C) break; } /* if not gimbal, fall through to normal */ - /* pass through */ + /* fall-through */ } case V3D_MANIP_NORMAL: { @@ -613,7 +613,7 @@ int calc_manipulator_stats(const bContext *C) break; } /* no break we define 'normal' as 'local' in Object mode */ - /* pass through */ + /* fall-through */ } case V3D_MANIP_LOCAL: { @@ -840,7 +840,8 @@ static void manipulator_setcolor(View3D *v3d, char axis, int colcode, unsigned c UI_GetThemeColor3ubv(TH_AXIS_Z, col); break; default: - BLI_assert(!"invalid axis arg"); + BLI_assert(0); + break; } } @@ -1641,6 +1642,11 @@ void BIF_draw_manipulator(const bContext *C) mul_mat3_m4_fl(rv3d->twmat, ED_view3d_pixel_size(rv3d, rv3d->twmat[3]) * U.tw_size * 5.0f); } + /* when looking through a selected camera, the manipulator can be at the + * exact same position as the view, skip so we don't break selection */ + if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f) + return; + test_manipulator_axis(C); drawflags = rv3d->twdrawflag; /* set in calc_manipulator_stats */ @@ -1677,7 +1683,12 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl rctf rect; GLuint buffer[64]; // max 4 items per select, so large enuf short hits; - extern void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); // XXX check a bit later on this... (ton) + extern void setwinmatrixview3d(ARegion *, View3D *, rctf *); // XXX check a bit later on this... (ton) + + /* when looking through a selected camera, the manipulator can be at the + * exact same position as the view, skip so we don't break selection */ + if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f) + return 0; G.f |= G_PICKSEL; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 70e01ef3718..55d80d63234 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -115,7 +115,7 @@ static TransformOrientation *createViewSpace(bContext *C, ReportList *UNUSED(rep View3D *v3d = CTX_wm_view3d(C); if (rv3d->persp == RV3D_CAMOB && v3d->camera) { /* If an object is used as camera, then this space is the same as object space! */ - strncpy(name, v3d->camera->id.name + 2, MAX_NAME); + BLI_strncpy(name, v3d->camera->id.name + 2, MAX_NAME); } else { strcpy(name, "Custom View"); @@ -141,7 +141,7 @@ static TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(r /* use object name if no name is given */ if (name[0] == 0) { - strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); + BLI_strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); } return addMatrixSpace(C, mat, name, overwrite); @@ -166,6 +166,26 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, c return addMatrixSpace(C, mat, name, overwrite); } +static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, char *name, int overwrite) +{ + float mat[3][3]; + float normal[3], plane[3]; + + getTransformOrientation(C, normal, plane, 0); + + if (createSpaceNormalTangent(mat, normal, plane) == 0) { + BKE_reports_prepend(reports, "Cannot use zero-length curve"); + return NULL; + } + + if (name[0] == 0) { + strcpy(name, "Curve"); + } + + return addMatrixSpace(C, mat, name, overwrite); +} + + static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; @@ -236,26 +256,34 @@ bool createSpaceNormal(float mat[3][3], const float normal[3]) return true; } -bool createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) +/** + * \note To recreate an orientation from the matrix: + * - (plane == mat[1]) + * - (normal == mat[2]) + */ +bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const float tangent[3]) { - copy_v3_v3(mat[2], normal); - if (normalize_v3(mat[2]) == 0.0f) { + if (normalize_v3_v3(mat[2], normal) == 0.0f) { return false; /* error return */ } - + + /* negate so we can use values from the matrix as input */ + negate_v3_v3(mat[1], tangent); /* preempt zero length tangent from causing trouble */ - if (tangent[0] == 0 && tangent[1] == 0 && tangent[2] == 0) { - tangent[2] = 1; + if (is_zero_v3(mat[1])) { + mat[1][2] = 1.0f; } - cross_v3_v3v3(mat[0], mat[2], tangent); + cross_v3_v3v3(mat[0], mat[2], mat[1]); if (normalize_v3(mat[0]) == 0.0f) { return false; /* error return */ } cross_v3_v3v3(mat[1], mat[2], mat[0]); + normalize_v3(mat[1]); - normalize_m3(mat); + /* final matrix must be normalized, do inline */ + // normalize_m3(mat); return true; } @@ -276,6 +304,8 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name ts = createMeshSpace(C, reports, name, overwrite); else if (obedit->type == OB_ARMATURE) ts = createBoneSpace(C, reports, name, overwrite); + else if (obedit->type == OB_CURVE) + ts = createCurveSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { ts = createBoneSpace(C, reports, name, overwrite); @@ -306,7 +336,7 @@ TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], if (ts == NULL) { ts = MEM_callocN(sizeof(TransformOrientation), "UserTransSpace from matrix"); BLI_addtail(transform_spaces, ts); - strncpy(ts->name, name, sizeof(ts->name)); + BLI_strncpy(ts->name, name, sizeof(ts->name)); } /* copy matrix into transform space */ @@ -466,14 +496,14 @@ void initTransformOrientation(bContext *C, TransInfo *t) strcpy(t->spacename, IFACE_("gimbal")); break; } - /* no gimbal fallthrough to normal */ + /* fall-through */ /* no gimbal fallthrough to normal */ case V3D_MANIP_NORMAL: if (obedit || (ob && ob->mode & OB_MODE_POSE)) { strcpy(t->spacename, IFACE_("normal")); ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE)); break; } - /* no break we define 'normal' as 'local' in Object mode */ + /* fall-through */ /* we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: strcpy(t->spacename, IFACE_("local")); @@ -667,6 +697,10 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], result = ORIENTATION_VERT; } } + + /* not needed but this matches 2.68 and older behavior */ + negate_v3(plane); + } /* end editmesh */ else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu = obedit->data; @@ -675,34 +709,67 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - for (nu = nurbs->first; nu; nu = nu->next) { - /* only bezier has a normal */ - if (nu->type == CU_BEZIER) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - /* exception */ - if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); + if (activeOnly && cu->lastsel) { + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + if (ARRAY_HAS_ITEM((BezTriple *)cu->lastsel, nu->bezt, nu->pntsu)) { + bezt = cu->lastsel; + BKE_nurb_bezt_calc_normal(nu, bezt, normal); + BKE_nurb_bezt_calc_plane(nu, bezt, plane); + break; } - else { - if (bezt->f1) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[1]); - } - if (bezt->f2) { - sub_v3_v3v3(normal, bezt->vec[0], bezt->vec[2]); - } - if (bezt->f3) { - sub_v3_v3v3(normal, bezt->vec[1], bezt->vec[2]); + } + else { + if (ARRAY_HAS_ITEM((BPoint *)cu->lastsel, nu->bp, nu->pntsu)) { + /* do nothing */ + break; + } + } + } + } + else { + for (nu = nurbs->first; nu; nu = nu->next) { + /* only bezier has a normal */ + if (nu->type == CU_BEZIER) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + /* exception */ + if ((bezt->f1 | bezt->f2 | bezt->f3) & SELECT) { + float tvec[3]; + if ((bezt->f1 & SELECT) + (bezt->f2 & SELECT) + (bezt->f3 & SELECT) > SELECT) { + BKE_nurb_bezt_calc_normal(nu, bezt, tvec); + add_v3_v3(normal, tvec); + } + else { + if (bezt->f1 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[1]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f2 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[0], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + if (bezt->f3 & SELECT) { + sub_v3_v3v3(tvec, bezt->vec[1], bezt->vec[2]); + normalize_v3(tvec); + add_v3_v3(normal, tvec); + } + } + + BKE_nurb_bezt_calc_plane(nu, bezt, tvec); + add_v3_v3(plane, tvec); } + bezt++; } - bezt++; } } } if (!is_zero_v3(normal)) { - result = ORIENTATION_NORMAL; + result = ORIENTATION_FACE; } } else if (obedit->type == OB_MBALL) { @@ -716,7 +783,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], copy_v3_v3(normal, qmat[2]); - negate_v3_v3(plane, qmat[1]); + copy_v3_v3(plane, qmat[1]); result = ORIENTATION_FACE; } @@ -724,45 +791,33 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebone; - int ok = FALSE; - - /* grr. but better then duplicate code */ -#define EBONE_CALC_NORMAL_PLANE { \ - float tmat[3][3]; \ - float vec[3]; \ - sub_v3_v3v3(vec, ebone->tail, ebone->head); \ - normalize_v3(vec); \ - add_v3_v3(normal, vec); \ - \ - vec_roll_to_mat3(vec, ebone->roll, tmat); \ - add_v3_v3(plane, tmat[2]); \ - } (void)0 - + bool ok = false; + float tmat[3][3]; if (activeOnly && (ebone = arm->act_edbone)) { - EBONE_CALC_NORMAL_PLANE; - ok = TRUE; + ED_armature_ebone_to_mat3(ebone, tmat); + add_v3_v3(normal, tmat[2]); + add_v3_v3(plane, tmat[1]); + ok = true; } else { for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { if (arm->layer & ebone->layer) { if (ebone->flag & BONE_SELECTED) { - EBONE_CALC_NORMAL_PLANE; - ok = TRUE; + ED_armature_ebone_to_mat3(ebone, tmat); + add_v3_v3(normal, tmat[2]); + add_v3_v3(plane, tmat[1]); + ok = true; } } } } if (ok) { - normalize_v3(normal); - normalize_v3(plane); - if (!is_zero_v3(plane)) { result = ORIENTATION_EDGE; } } -#undef EBONE_CALC_NORMAL_PLANE } /* Vectors from edges don't need the special transpose inverse multiplication */ @@ -804,8 +859,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* use for both active & all */ if (ok) { - negate_v3(plane); - /* we need the transpose of the inverse for a normal... */ copy_m3_m4(imat, ob->obmat); @@ -823,11 +876,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else { /* we need the one selected object, if its not active */ ob = OBACT; - if (ob && !(ob->flag & SELECT)) ob = NULL; - - for (base = scene->base.first; base; base = base->next) { - if (TESTBASELIB(v3d, base)) { - if (ob == NULL) { + if (ob && (ob->flag & SELECT)) { + /* pass */ + } + else { + /* first selected */ + ob = NULL; + for (base = scene->base.first; base; base = base->next) { + if (TESTBASELIB(v3d, base)) { ob = base->object; break; } diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index ea5e806647f..e72385b311d 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -47,6 +47,7 @@ set(SRC ../include/BIF_glutil.h ../include/ED_anim_api.h ../include/ED_armature.h + ../include/ED_buttons.h ../include/ED_clip.h ../include/ED_curve.h ../include/ED_datafiles.h diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index ea3687ad715..bed8aaaddf2 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -40,6 +40,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_bitmap.h" #include "BKE_DerivedMesh.h" #include "BKE_modifier.h" @@ -51,7 +52,7 @@ typedef struct { float *vertexcos; - short *flags; + BLI_bitmap *vertex_visit; } MappedUserData; #define TAN_MAKE_VEC(a, b, c) a[0] = b[0] + 0.2f * (b[0] - c[0]); a[1] = b[1] + 0.2f * (b[1] - c[1]); a[2] = b[2] + 0.2f * (b[2] - c[2]) @@ -79,11 +80,11 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3] float *vec = mappedData->vertexcos; vec += 3 * index; - if (!mappedData->flags[index]) { + if (BLI_BITMAP_GET(mappedData->vertex_visit, index) == 0) { /* we need coord from prototype vertex, not it clones or images, * suppose they stored in the beginning of vertex array stored in DM */ copy_v3_v3(vec, co); - mappedData->flags[index] = 1; + BLI_BITMAP_SET(mappedData->vertex_visit, index); } } @@ -109,7 +110,7 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) DerivedMesh *dm; float *vertexcos; int nverts = me->edit_btmesh->bm->totvert; - short *flags; + BLI_bitmap *vertex_visit; MappedUserData userData; /* disable subsurf temporal, get mapped cos, and enable it */ @@ -122,18 +123,18 @@ float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit) dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH); vertexcos = MEM_callocN(3 * sizeof(float) * nverts, "vertexcos map"); - flags = MEM_callocN(sizeof(short) * nverts, "vertexcos flags"); + vertex_visit = BLI_BITMAP_NEW(nverts, "vertexcos flags"); userData.vertexcos = vertexcos; - userData.flags = flags; - dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData); + userData.vertex_visit = vertex_visit; + dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData, DM_FOREACH_NOP); dm->release(dm); /* set back the flag, no new cage needs to be built, transform does it */ modifiers_disable_subsurf_temporary(obedit); - MEM_freeN(flags); + MEM_freeN(vertex_visit); return vertexcos; } @@ -278,7 +279,7 @@ int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em if (!defmats) { dm = getEditDerivedBMesh(em, ob, NULL); deformedVerts = editbmesh_get_vertex_cos(em, &numVerts); - defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats"); + defmats = MEM_mallocN(sizeof(*defmats) * numVerts, "defmats"); for (a = 0; a < numVerts; a++) unit_m3(defmats[a]); diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index bfe3b80eff4..3e5f879aa3c 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -109,6 +109,7 @@ void outputNumInput(NumInput *n, char *str) break; default: BLI_snprintf(&str[j * ln], ln, "%s%.4e%c", inv, n->val[i], cur); + break; } } } @@ -201,8 +202,7 @@ char handleNumInput(NumInput *n, const wmEvent *event) n->inv[idx] = 0; } break; - case PERIODKEY: - case PADPERIOD: + case PERIODKEY: case PADPERIOD: if (n->flag & NUM_NO_FRACTION) return 0; @@ -213,11 +213,13 @@ char handleNumInput(NumInput *n, const wmEvent *event) break; case -1: n->ctrl[idx] = -10; + break; } break; case PADMINUS: if (event->alt) break; + /* fall-through */ case MINUSKEY: if (n->flag & NUM_NO_NEGATIVE) return 0; @@ -229,8 +231,7 @@ char handleNumInput(NumInput *n, const wmEvent *event) else n->ctrl[idx] = -1; break; - case PADSLASHKEY: - case SLASHKEY: + case PADSLASHKEY: case SLASHKEY: if (n->flag & NUM_NO_FRACTION) return 0; @@ -245,35 +246,34 @@ char handleNumInput(NumInput *n, const wmEvent *event) idx = 0; n->idx = idx; break; - case PAD9: - case NINEKEY: + case PAD9: case NINEKEY: Val += 1.0f; - case PAD8: - case EIGHTKEY: + /* fall-through */ + case PAD8: case EIGHTKEY: Val += 1.0f; - case PAD7: - case SEVENKEY: + /* fall-through */ + case PAD7: case SEVENKEY: Val += 1.0f; - case PAD6: - case SIXKEY: + /* fall-through */ + case PAD6: case SIXKEY: Val += 1.0f; - case PAD5: - case FIVEKEY: + /* fall-through */ + case PAD5: case FIVEKEY: Val += 1.0f; - case PAD4: - case FOURKEY: + /* fall-through */ + case PAD4: case FOURKEY: Val += 1.0f; - case PAD3: - case THREEKEY: + /* fall-through */ + case PAD3: case THREEKEY: Val += 1.0f; - case PAD2: - case TWOKEY: + /* fall-through */ + case PAD2: case TWOKEY: Val += 1.0f; - case PAD1: - case ONEKEY: + /* fall-through */ + case PAD1: case ONEKEY: Val += 1.0f; - case PAD0: - case ZEROKEY: + /* fall-through */ + case PAD0: case ZEROKEY: if (!n->ctrl[idx]) n->ctrl[idx] = 1; diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 7f2e5b4b81c..e285fd8bea4 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -59,6 +59,7 @@ #include "ED_mball.h" #include "ED_mesh.h" #include "ED_object.h" +#include "ED_render.h" #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_util.h" @@ -140,9 +141,12 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) SpaceImage *sima = (SpaceImage *)sa->spacedata.first; if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { - if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) - if (U.uiflag & USER_GLOBALUNDO) + if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) { + if (U.uiflag & USER_GLOBALUNDO) { + ED_viewport_render_kill_jobs(C, true); BKE_undo_name(C, undoname); + } + } WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; @@ -192,6 +196,8 @@ static int ed_undo_step(bContext *C, int step, const char *undoname) /* for example, texface stores image pointers */ undo_editmode_clear(); + ED_viewport_render_kill_jobs(C, true); + if (undoname) BKE_undo_name(C, undoname); else @@ -363,6 +369,8 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int retval; + ED_viewport_render_kill_jobs(C, true); + if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); ED_undo_pop_op(C, op); @@ -529,6 +537,7 @@ static int undo_history_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); } else { + ED_viewport_render_kill_jobs(C, true); BKE_undo_number(C, item); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, CTX_data_scene(C)); } diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 438f6bbdb9c..a873702b5b8 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -49,7 +49,6 @@ #include "BKE_mesh.h" #include "BKE_editmesh.h" -#include "BLI_array.h" #include "BLI_buffer.h" #include "BIF_gl.h" @@ -66,6 +65,10 @@ #include "uvedit_intern.h" +/* use editmesh tessface */ +#define USE_EDBM_LOOPTRIS + + void draw_image_cursor(SpaceImage *sima, ARegion *ar) { float zoom[2], x_fac, y_fac; @@ -257,6 +260,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe weight_to_rgb(col, areadiff); glColor3fv(col); + /* TODO: USE_EDBM_LOOPTRIS */ glBegin(GL_POLYGON); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -321,6 +325,7 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]); } + /* TODO: USE_EDBM_LOOPTRIS */ glBegin(GL_POLYGON); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -421,6 +426,23 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) } } +#ifdef USE_EDBM_LOOPTRIS +static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset) +{ + unsigned int i = *r_loop_index; + BMFace *f = em->looptris[i][0]->f; + do { + unsigned int j; + for (j = 0; j < 3; j++) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset); + glVertex2fv(luv->uv); + } + i++; + } while (i != em->tottri && (f == em->looptris[i][0]->f)); + *r_loop_index = i - 1; +} +#endif + /* draws uv's in the image space */ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) { @@ -428,7 +450,10 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) Mesh *me = obedit->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMFace *efa, *efa_act, *activef; + BMFace *efa, *efa_act; +#ifndef USE_EDBM_LOOPTRIS + BMFace *activef; +#endif BMLoop *l; BMIter iter, liter; MTexPoly *tf, *activetf = NULL; @@ -443,7 +468,9 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */ +#ifndef USE_EDBM_LOOPTRIS activef = BM_mesh_active_face_get(bm, FALSE, FALSE); +#endif ts = scene->toolsettings; drawfaces = draw_uvs_face_check(scene); @@ -490,9 +517,42 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); +#ifdef USE_EDBM_LOOPTRIS + { + unsigned int i; + for (i = 0; i < em->tottri; i++) { + efa = em->looptris[i][0]->f; + tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); + if (uvedit_face_visible_test(scene, ima, efa, tf)) { + const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset); + BM_elem_flag_enable(efa, BM_ELEM_TAG); + + if (tf == activetf) { + /* only once */ + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(stipple_quarttone); + UI_ThemeColor4(TH_EDITMESH_ACTIVE); + } + else { + glColor4ubv((GLubyte *)(is_select ? col2 : col1)); + } + + glBegin(GL_TRIANGLES); + draw_uvs_looptri(em, &i, cd_loop_uv_offset); + glEnd(); + + if (tf == activetf) { + glDisable(GL_POLYGON_STIPPLE); + } + } + else { + BM_elem_flag_disable(efa, BM_ELEM_TAG); + } + } + } +#else BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); if (tf == activetf) continue; /* important the temp boolean is set above */ @@ -515,6 +575,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) BM_elem_flag_disable(efa, BM_ELEM_TAG); } } +#endif glDisable(GL_BLEND); } else { @@ -536,7 +597,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) } /* 3. draw active face stippled */ - +#ifndef USE_EDBM_LOOPTRIS if (activef) { tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset); if (uvedit_face_visible_test(scene, ima, activef, tf)) { @@ -558,6 +619,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) glDisable(GL_BLEND); } } +#endif /* 4. draw edges */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 1ed00c3aa20..0b514e3f6fd 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -46,11 +46,12 @@ #include "DNA_space_types.h" #include "DNA_scene_types.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_lasso.h" #include "BLI_blenlib.h" #include "BLI_array.h" -#include "BLI_utildefines.h" #include "BKE_context.h" #include "BKE_customdata.h" @@ -3226,7 +3227,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot) /* ******************** snap selection operator **************** */ -static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceImage *sima) +static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, const float cursor[2]) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; @@ -3247,7 +3248,37 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, Spac BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(luv->uv, sima->cursor); + copy_v2_v2 (luv->uv, cursor); + change = true; + } + } + } + + return change; +} + +static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const float offset[2]) +{ + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMFace *efa; + BMLoop *l; + BMIter iter, liter; + MTexPoly *tface; + MLoopUV *luv; + bool change = false; + + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + tface = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); + if (!uvedit_face_visible_test(scene, ima, efa, tface)) + continue; + + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + add_v2_v2(luv->uv, offset); change = true; } } @@ -3365,9 +3396,19 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op) change = uv_snap_uvs_to_pixels(sima, scene, obedit); break; case 1: - change = uv_snap_uvs_to_cursor(scene, ima, obedit, sima); + change = uv_snap_uvs_to_cursor(scene, ima, obedit, sima->cursor); break; case 2: + { + float center[2]; + if (uvedit_center(scene, ima, obedit, center, sima->around)) { + float offset[2]; + sub_v2_v2v2(offset, sima->cursor, center); + change = uv_snap_uvs_offset(scene, ima, obedit, offset); + } + break; + } + case 3: change = uv_snap_uvs_to_adjacent_unselected(scene, ima, obedit); break; } @@ -3387,7 +3428,8 @@ static void UV_OT_snap_selected(wmOperatorType *ot) static EnumPropertyItem target_items[] = { {0, "PIXELS", 0, "Pixels", ""}, {1, "CURSOR", 0, "Cursor", ""}, - {2, "ADJACENT_UNSELECTED", 0, "Adjacent Unselected", ""}, + {2, "CURSOR_OFFSET", 0, "Cursor (Offset)", ""}, + {3, "ADJACENT_UNSELECTED", 0, "Adjacent Unselected", ""}, {0, NULL, 0, NULL, NULL}}; /* identifiers */ diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 6f92c1873d6..7851eebe269 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -26,15 +26,13 @@ #include "MEM_guardedalloc.h" -#include "BLI_array.h" +#include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_memarena.h" #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_heap.h" #include "BLI_boxpack2d.h" -#include "BLI_utildefines.h" - - #include "ONL_opennl.h" @@ -3682,8 +3680,8 @@ static SmoothNode *p_node_new(MemArena *arena, SmoothTriangle **tri, int ntri, f if (ntri <= 10 || depth >= 15) return node; - t1 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1"); - t2 = MEM_mallocN(sizeof(SmoothTriangle) * ntri, "PNodeTri1"); + t1 = MEM_mallocN(sizeof(*t1) * ntri, "PNodeTri1"); + t2 = MEM_mallocN(sizeof(*t2) * ntri, "PNodeTri1"); axis = (bmax[0] - bmin[0] > bmax[1] - bmin[1]) ? 0 : 1; split = 0.5f * (bmin[axis] + bmax[axis]); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index a100757980c..af6689e3f6d 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -44,6 +44,7 @@ #include "DNA_modifier_types.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_uvproject.h" @@ -65,7 +66,6 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_scanfill.h" -#include "BLI_array.h" #include "BLI_uvproject.h" #include "PIL_time.h" |