diff options
Diffstat (limited to 'source/blender/editors')
164 files changed, 5008 insertions, 2299 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 1d9022e463b..75363f4f567 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -342,7 +342,7 @@ static void acf_generic_idblock_name(bAnimListElem *ale, char *name) } /* name property for ID block entries */ -static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_generic_idblock_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { RNA_id_pointer_create(ale->id, ptr); *prop = RNA_struct_name_property(ptr->type); @@ -352,7 +352,7 @@ static short acf_generic_idblock_nameprop(bAnimListElem *ale, PointerRNA *ptr, P /* name property for ID block entries which are just subheading "fillers" */ -static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */ RNA_id_pointer_create(ale->data, ptr); @@ -365,19 +365,19 @@ static short acf_generic_idfill_nameprop(bAnimListElem *ale, PointerRNA *ptr, Pr #if 0 /* channel type has no settings */ -static short acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { - return 0; + return false; } #endif /* check if some setting exists for this object-based data-expander (datablock only) */ -static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* expand is always supported */ case ACHANNEL_SETTING_EXPAND: - return 1; + return true; /* mute is only supported for NLA */ case ACHANNEL_SETTING_MUTE: @@ -385,11 +385,11 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle /* select is ok for most "ds*" channels (e.g. dsmat) */ case ACHANNEL_SETTING_SELECT: - return 1; + return true; /* other flags are never supported */ default: - return 0; + return false; } } @@ -438,23 +438,23 @@ static int acf_summary_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { /* only expanded is supported, as it is used for hiding all stuff which the summary covers */ return (setting == ACHANNEL_SETTING_EXPAND); } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { if (setting == ACHANNEL_SETTING_EXPAND) { /* expanded */ - *neg = 1; + *neg = true; return ADS_FLAG_SUMMARY_COLLAPSED; } else { /* unsupported */ - *neg = 0; + *neg = false; return 0; } } @@ -509,7 +509,7 @@ static int acf_scene_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* muted only in NLA */ @@ -523,32 +523,32 @@ static short acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale /* only select and expand supported otherwise */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return SCE_DS_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return SCE_DS_COLLAPSED; case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */ return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; default: /* unsupported */ @@ -593,7 +593,7 @@ static bAnimChannelType ACF_SCENE = NULL, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_scene_icon, /* icon */ acf_scene_setting_valid, /* has setting */ @@ -649,7 +649,7 @@ static void acf_object_name(bAnimListElem *ale, char *name) } /* check if some setting exists for this channel */ -static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { Base *base = (Base *)ale->data; Object *ob = base->object; @@ -666,18 +666,18 @@ static short acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, int /* only select and expand supported otherwise */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -691,7 +691,7 @@ static int acf_object_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; default: /* unsupported */ @@ -737,7 +737,7 @@ static bAnimChannelType ACF_OBJECT = NULL, /* offset */ acf_object_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_object_icon, /* icon */ acf_object_setting_valid, /* has setting */ @@ -803,7 +803,7 @@ static void acf_group_name(bAnimListElem *ale, char *name) } /* name property for group entries */ -static short acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr); *prop = RNA_struct_name_property(ptr->type); @@ -812,28 +812,28 @@ static short acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRN } /* check if some setting exists for this channel */ -static short acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) +static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), int setting) { /* for now, all settings are supported, though some are only conditionally */ switch (setting) { /* unsupported */ case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */ - return 0; + return false; /* conditionally supported */ case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */ return (ac->spacetype == SPACE_IPO); default: /* always supported */ - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg) +static int acf_group_setting_flag(bAnimContext *ac, int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -854,7 +854,6 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg) return AGRP_MUTED; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to edtiability return AGRP_PROTECTED; case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ @@ -903,7 +902,7 @@ static void acf_fcurve_name(bAnimListElem *ale, char *name) } /* "name" property for fcurve entries */ -static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { FCurve *fcu = (FCurve *)ale->data; @@ -924,7 +923,7 @@ static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyR } /* check if some setting exists for this channel */ -static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) +static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting) { FCurve *fcu = (FCurve *)ale->data; @@ -932,29 +931,29 @@ static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int /* unsupported */ case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */ case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */ - return 0; + return false; /* conditionally available */ case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */ if (fcu->bezt) - return 1; + return true; else - return 0; // NOTE: in this special case, we need to draw ICON_ZOOMOUT + return false; // NOTE: in this special case, we need to draw ICON_ZOOMOUT case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */ return (ac->spacetype == SPACE_IPO); /* always available */ default: - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -964,7 +963,6 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short return FCURVE_MUTED; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to edtiability return FCURVE_PROTECTED; case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ @@ -1012,31 +1010,31 @@ static int acf_fillactd_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* only select and expand supported */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return ADT_UI_SELECTED; case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return ACT_COLLAPSED; default: /* unsupported */ @@ -1079,7 +1077,7 @@ static bAnimChannelType ACF_FILLACTD = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_fillactd_icon, /* icon */ acf_fillactd_setting_valid, /* has setting */ @@ -1102,27 +1100,27 @@ static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name) /* check if some setting exists for this channel */ // TODO: this could be made more generic -static short acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* only expand supported */ case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ - *neg = 1; + *neg = true; return ADT_DRIVERS_COLLAPSED; default: /* unsupported */ @@ -1176,10 +1174,10 @@ static int acf_dsmat_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1189,7 +1187,7 @@ static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1235,7 +1233,7 @@ static bAnimChannelType ACF_DSMAT = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmat_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1252,10 +1250,10 @@ static int acf_dslam_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1265,7 +1263,7 @@ static int acf_dslam_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1311,7 +1309,7 @@ static bAnimChannelType ACF_DSLAM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslam_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1335,10 +1333,10 @@ static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(al } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1348,7 +1346,7 @@ static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1394,7 +1392,7 @@ static bAnimChannelType ACF_DSTEX = acf_dstex_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dstex_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1411,10 +1409,10 @@ static int acf_dscam_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1424,7 +1422,7 @@ static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1470,7 +1468,7 @@ static bAnimChannelType ACF_DSCAM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dscam_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1497,10 +1495,10 @@ static int acf_dscur_icon(bAnimListElem *ale) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1510,7 +1508,7 @@ static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1556,7 +1554,7 @@ static bAnimChannelType ACF_DSCUR = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dscur_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1573,10 +1571,10 @@ static int acf_dsskey_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1586,7 +1584,7 @@ static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1632,7 +1630,7 @@ static bAnimChannelType ACF_DSSKEY = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsskey_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1649,10 +1647,10 @@ static int acf_dswor_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1662,7 +1660,7 @@ static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1708,7 +1706,7 @@ static bAnimChannelType ACF_DSWOR = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_dswor_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1725,10 +1723,10 @@ static int acf_dspart_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1738,7 +1736,7 @@ static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1784,7 +1782,7 @@ static bAnimChannelType ACF_DSPART = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dspart_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1801,10 +1799,10 @@ static int acf_dsmball_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1814,7 +1812,7 @@ static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1860,7 +1858,7 @@ static bAnimChannelType ACF_DSMBALL = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmball_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1877,10 +1875,10 @@ static int acf_dsarm_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1890,7 +1888,7 @@ static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -1936,7 +1934,7 @@ static bAnimChannelType ACF_DSARM = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsarm_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -1964,10 +1962,10 @@ static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -1977,7 +1975,7 @@ static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2023,7 +2021,7 @@ static bAnimChannelType ACF_DSNTREE = acf_dsntree_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsntree_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2040,10 +2038,10 @@ static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2053,7 +2051,7 @@ static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), int setting, s return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2099,7 +2097,7 @@ static bAnimChannelType ACF_DSLINESTYLE = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslinestyle_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2116,10 +2114,10 @@ static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2129,7 +2127,7 @@ static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), int setting, short return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2175,7 +2173,7 @@ static bAnimChannelType ACF_DSMESH = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsmesh_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2192,10 +2190,10 @@ static int acf_dslat_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2205,7 +2203,7 @@ static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2251,7 +2249,7 @@ static bAnimChannelType ACF_DSLAT = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dslat_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2268,10 +2266,10 @@ static int acf_dsspk_icon(bAnimListElem *UNUSED(ale)) } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_EXPAND: /* expanded */ @@ -2281,7 +2279,7 @@ static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), int setting, short * return ADT_NLA_EVAL_OFF; case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */ - *neg = 1; + *neg = true; return ADT_CURVES_NOT_VISIBLE; case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2327,7 +2325,7 @@ static bAnimChannelType ACF_DSSPK = acf_generic_basic_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idblock_nameprop, /* name prop */ + acf_generic_idblock_name_prop, /* name prop */ acf_dsspk_icon, /* icon */ acf_generic_dataexpand_setting_valid, /* has setting */ @@ -2353,7 +2351,7 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name) } /* name property for ShapeKey entries */ -static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { KeyBlock *kb = (KeyBlock *)ale->data; @@ -2365,29 +2363,29 @@ static short acf_shapekey_nameprop(bAnimListElem *ale, PointerRNA *ptr, Property return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ case ACHANNEL_SETTING_MUTE: /* muted */ case ACHANNEL_SETTING_PROTECT: /* protected */ - return 1; + return true; /* nothing else is supported */ default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_MUTE: /* mute */ @@ -2434,7 +2432,7 @@ static bAnimChannelType ACF_SHAPEKEY = acf_generic_basic_offset, /* offset */ acf_shapekey_name, /* name */ - acf_shapekey_nameprop, /* name prop */ + acf_shapekey_name_prop, /* name prop */ NULL, /* icon */ acf_shapekey_setting_valid, /* has setting */ @@ -2458,24 +2456,24 @@ static int acf_gpd_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* only select and expand supported */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2509,7 +2507,7 @@ static bAnimChannelType ACF_GPD = acf_generic_group_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_gpd_icon, /* icon */ acf_gpd_setting_valid, /* has setting */ @@ -2529,7 +2527,7 @@ static void acf_gpl_name(bAnimListElem *ale, char *name) } /* name property for grease pencil layer entries */ -static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { if (ale->data) { RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr); @@ -2538,30 +2536,30 @@ static short acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* unsupported */ case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ case ACHANNEL_SETTING_SOLO: /* nla editor only */ - return 0; + return false; /* always available */ default: - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2571,7 +2569,6 @@ static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), int setting, short *ne return GP_LAYER_HIDE; case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to editability return GP_LAYER_LOCKED; default: /* unsupported */ @@ -2624,24 +2621,24 @@ static int acf_mask_icon(bAnimListElem *UNUSED(ale)) } /* check if some setting exists for this channel */ -static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* only select and expand supported */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: - return 1; + return true; default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -2675,7 +2672,7 @@ static bAnimChannelType ACF_MASKDATA = acf_generic_group_offset, /* offset */ acf_generic_idblock_name, /* name */ - acf_generic_idfill_nameprop, /* name prop */ + acf_generic_idfill_name_prop, /* name prop */ acf_mask_icon, /* icon */ acf_mask_setting_valid, /* has setting */ @@ -2695,7 +2692,7 @@ static void acf_masklay_name(bAnimListElem *ale, char *name) } /* name property for grease pencil layer entries */ -static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { if (ale->data) { RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr); @@ -2704,40 +2701,36 @@ static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) +static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), int setting) { switch (setting) { /* unsupported */ case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ case ACHANNEL_SETTING_SOLO: /* nla editor only */ - return 0; + return false; /* always available */ default: - return 1; + return true; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return MASK_LAYERFLAG_SELECT; -// case ACHANNEL_SETTING_MUTE: /* muted */ -// return GP_LAYER_HIDE; - case ACHANNEL_SETTING_PROTECT: /* protected */ - // *neg = 1; - if we change this to editability return MASK_LAYERFLAG_LOCKED; default: /* unsupported */ @@ -2804,7 +2797,7 @@ static void acf_nlatrack_name(bAnimListElem *ale, char *name) } /* name property for nla track entries */ -static short acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) { if (ale->data) { RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr); @@ -2813,11 +2806,11 @@ static short acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, Propert return (*prop != NULL); } - return 0; + return false; } /* check if some setting exists for this channel */ -static short acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, int setting) +static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, int setting) { NlaTrack *nlt = (NlaTrack *)ale->data; AnimData *adt = ale->adt; @@ -2827,7 +2820,7 @@ static short acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem /* always supported */ case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_SOLO: - return 1; + return true; /* conditionally supported... */ case ACHANNEL_SETTING_PROTECT: @@ -2838,34 +2831,34 @@ static short acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) { if (nlt->flag & NLATRACK_SOLO) { /* ok - we've got a solo track, and this is it */ - return 1; + return true; } else { /* not ok - we've got a solo track, but this isn't it, so make it more obvious */ - return 0; + return false; } } /* ok - no tracks are solo'd, and this isn't being tweaked */ - return 1; + return true; } else { /* unsupported - this track is being tweaked */ - return 0; + return false; } /* unsupported */ default: - return 0; + return false; } } /* get the appropriate flag(s) for the setting when it is valid */ -static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), int setting, short *neg) +static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), int setting, bool *neg) { /* clear extra return data first */ - *neg = 0; + *neg = false; switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ @@ -3037,7 +3030,8 @@ short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, int setting /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { /* 2) get pointer to check for flag in, and the flag to check for */ - short negflag, ptrsize; + short ptrsize; + bool negflag; int flag; void *ptr; @@ -3112,7 +3106,8 @@ void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, int setting, /* 1) check that the setting exists for the current context */ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) { /* 2) get pointer to check for flag in, and the flag to check for */ - short negflag, ptrsize; + short ptrsize; + bool negflag; int flag; void *ptr; @@ -3494,7 +3489,8 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting) { - short negflag, ptrsize /* , enabled */ /* UNUSED */, butType; + short ptrsize, butType; + bool negflag; int flag, icon; void *ptr; const char *tooltip; diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index 33ca10420ec..861998c15f3 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2152,7 +2152,8 @@ static int animchannels_borderselect_exec(bContext *C, wmOperator *op) bAnimContext ac; rcti rect; short selectmode = 0; - int gesture_mode, extend; + int gesture_mode; + bool extend; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index cab072675b2..9818c312e8e 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -125,11 +125,11 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f { TimeMarker *marker; float cfra = (float)CFRA; - int changed = 0; + int changed_tot = 0; /* sanity check */ if (markers == NULL) - return changed; + return changed_tot; /* affect selected markers - it's unlikely that we will want to affect all in this way? */ for (marker = markers->first; marker; marker = marker->next) { @@ -144,7 +144,7 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f (side == 'R' && marker->frame >= cfra)) { marker->frame += (int)floorf(value + 0.5f); - changed++; + changed_tot++; } break; } @@ -152,14 +152,14 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f { /* rescale the distance between the marker and the current frame */ marker->frame = cfra + (int)floorf(((float)(marker->frame - cfra) * value) + 0.5f); - changed++; + changed_tot++; break; } } } } - return changed; + return changed_tot; } /* --------------------------------- */ @@ -173,7 +173,7 @@ TimeMarker *ED_markers_find_nearest_marker(ListBase *markers, float x) if (markers) { for (marker = markers->first; marker; marker = marker->next) { - dist = ABS((float)marker->frame - x); + dist = fabsf((float)marker->frame - x); if (dist < min_dist) { min_dist = dist; @@ -1083,7 +1083,7 @@ static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool static int ed_marker_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); bool camera = false; #ifdef DURIAN_CAMERA_SWITCH camera = RNA_boolean_get(op->ptr, "camera"); @@ -1148,7 +1148,7 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op) TimeMarker *marker; float xminf, xmaxf, yminf, ymaxf; int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); - int extend = RNA_boolean_get(op->ptr, "extend"); + bool extend = RNA_boolean_get(op->ptr, "extend"); rcti rect; WM_operator_properties_border_to_rcti(op, &rect); @@ -1270,7 +1270,7 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op)) { ListBase *markers = ED_context_get_markers(C); TimeMarker *marker, *nmarker; - short changed = 0; + bool changed = false; if (markers == NULL) return OPERATOR_CANCELLED; @@ -1279,7 +1279,7 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op)) nmarker = marker->next; if (marker->flag & SELECT) { BLI_freelinkN(markers, marker); - changed = 1; + changed = true; } } diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index cfa5f9f032c..481012bf411 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -104,12 +104,13 @@ void delete_fcurve_key(FCurve *fcu, int index, short do_recalc) } /* Delete selected keyframes in given F-Curve */ -void delete_fcurve_keys(FCurve *fcu) +bool delete_fcurve_keys(FCurve *fcu) { int i; + bool changed = false; if (fcu->bezt == NULL) /* ignore baked curves */ - return; + return false; /* Delete selected BezTriples */ for (i = 0; i < fcu->totvert; i++) { @@ -117,12 +118,15 @@ void delete_fcurve_keys(FCurve *fcu) memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1)); fcu->totvert--; i--; + changed = true; } } /* Free the array of BezTriples if there are not keyframes */ if (fcu->totvert == 0) clear_fcurve_keys(fcu); + + return changed; } diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 1028fb30ba4..07cc16aa5b6 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1474,8 +1474,10 @@ void ANIM_OT_keyframe_delete(wmOperatorType *ot) * it is more useful for animators working in the 3D view. */ -static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) +static int clear_anim_v3d_exec(bContext *C, wmOperator *op) { + int num_deleted = 0; + CTX_DATA_BEGIN (C, Object *, ob, selected_objects) { /* just those in active action... */ @@ -1515,15 +1517,19 @@ static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op)) /* delete F-Curve completely */ if (can_delete) { ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + num_deleted++; } } } - + /* update... */ DAG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; - + + if (num_deleted > 0) + BKE_reportf(op->reports, RPT_INFO, "Deleted %d animation F-Curves from selected objects", num_deleted); + /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL); @@ -1538,7 +1544,6 @@ void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot) ot->idname = "ANIM_OT_keyframe_clear_v3d"; /* callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = clear_anim_v3d_exec; ot->poll = ED_operator_areaactive; @@ -1602,7 +1607,6 @@ void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot) ot->idname = "ANIM_OT_keyframe_delete_v3d"; /* callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = delete_key_v3d_exec; ot->poll = ED_operator_areaactive; diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index 1a0841f5342..ca2dc1b66e2 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -27,7 +27,6 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc - ../../../../intern/opennl/extern ) set(INC_SYS @@ -67,4 +66,11 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_OPENNL) + add_definitions(-DWITH_OPENNL) + list(APPEND INC_SYS + ../../../../intern/opennl/extern + ) +endif() + blender_add_lib(bf_editor_armature "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index b91deab6c8d..ed8ae2d4cbb 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -789,11 +789,13 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op) copy_v3_v3(newbone->tail, ebone->tail); copy_v3_v3(ebone->tail, newbone->head); - newbone->rad_head = 0.5f * (ebone->rad_head + ebone->rad_tail); + newbone->rad_head = ((ebone->rad_head * cutratio) + (ebone->rad_tail * cutratioI)); ebone->rad_tail = newbone->rad_head; newbone->flag |= BONE_CONNECTED; - + + newbone->prop = NULL; + unique_editbone_name(arm->edbo, newbone->name, NULL); /* correct parent bones */ diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 1bc5bf0fd74..c284769ff5c 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -989,6 +989,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) bArmature *arm = (bArmature *)ob->data; EditBone *actbone = CTX_data_active_bone(C); EditBone *actmirb = NULL; + int num_selected_bones; /* there must be an active bone */ if (actbone == NULL) { @@ -1011,7 +1012,8 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) /* if there is only 1 selected bone, we assume that that is the active bone, * since a user will need to have clicked on a bone (thus selecting it) to make it active */ - if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) { + num_selected_bones = CTX_DATA_COUNT(C, selected_editable_bones); + if (num_selected_bones <= 1) { /* When only the active bone is selected, and it has a parent, * align it to the parent, as that is the only possible outcome. */ @@ -1020,6 +1022,8 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent)) bone_align_to_bone(arm->edbo, actmirb, actmirb->parent); + + BKE_reportf(op->reports, RPT_INFO, "Aligned bone '%s' to parent", actbone->name); } } else { @@ -1042,8 +1046,10 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) } } CTX_DATA_END; + + BKE_reportf(op->reports, RPT_INFO, "%d bones aligned to bone '%s'", num_selected_bones, actbone->name); } - + /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob); @@ -1058,7 +1064,6 @@ void ARMATURE_OT_align(wmOperatorType *ot) ot->description = "Align selected bones to the active bone (or to their parent)"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = armature_align_bones_exec; ot->poll = ED_operator_editarmature; @@ -1108,12 +1113,13 @@ void ARMATURE_OT_split(wmOperatorType *ot) /* previously delete_armature */ /* only editmode! */ -static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) +static int armature_delete_selected_exec(bContext *C, wmOperator *op) { bArmature *arm; EditBone *curBone, *ebone_next; bConstraint *con; Object *obedit = CTX_data_edit_object(C); // XXX get from context + int num_deleted = 0; arm = obedit->data; /* cancel if nothing selected */ @@ -1170,10 +1176,12 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) if (curBone->flag & BONE_SELECTED) { if (curBone == arm->act_edbone) arm->act_edbone = NULL; ED_armature_edit_bone_remove(arm, curBone); + num_deleted++; } } } + BKE_reportf(op->reports, RPT_INFO, "Deleted %d bones", num_deleted); ED_armature_sync_selection(arm->edbo); @@ -1190,7 +1198,6 @@ void ARMATURE_OT_delete(wmOperatorType *ot) ot->description = "Remove selected bones from the armature"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = armature_delete_selected_exec; ot->poll = ED_operator_editarmature; diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index bc7d69d1558..f3db9042879 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -68,6 +68,7 @@ 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); +void ARMATURE_OT_shortest_path_pick(struct wmOperatorType *ot); void ARMATURE_OT_delete(struct wmOperatorType *ot); void ARMATURE_OT_duplicate(struct wmOperatorType *ot); diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index c574fc6a297..a4b40f64859 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -232,14 +232,33 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n /* fix modifiers that might be using this name */ for (md = ob->modifiers.first; md; md = md->next) { - if (md->type == eModifierType_Hook) { - HookModifierData *hmd = (HookModifierData *)md; - - /* uses armature, so may use the affected bone name */ - if (hmd->object && (hmd->object->data == arm)) { - if (!strcmp(hmd->subtarget, oldname)) - BLI_strncpy(hmd->subtarget, newname, MAXBONENAME); + switch (md->type) { + case eModifierType_Hook: + { + HookModifierData *hmd = (HookModifierData *)md; + + if (hmd->object && (hmd->object->data == arm)) { + if (STREQ(hmd->subtarget, oldname)) + BLI_strncpy(hmd->subtarget, newname, MAXBONENAME); + } + break; + } + case eModifierType_UVWarp: + { + UVWarpModifierData *umd = (UVWarpModifierData *)md; + + if (umd->object_src && (umd->object_src->data == arm)) { + if (STREQ(umd->bone_src, oldname)) + BLI_strncpy(umd->bone_src, newname, MAXBONENAME); + } + if (umd->object_dst && (umd->object_dst->data == arm)) { + if (STREQ(umd->bone_dst, oldname)) + BLI_strncpy(umd->bone_dst, newname, MAXBONENAME); + } + break; } + default: + break; } } } diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index 4c7eb847054..feb9b0f939a 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -64,6 +64,7 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_select_hierarchy); WM_operatortype_append(ARMATURE_OT_select_linked); WM_operatortype_append(ARMATURE_OT_select_similar); + WM_operatortype_append(ARMATURE_OT_shortest_path_pick); WM_operatortype_append(ARMATURE_OT_delete); WM_operatortype_append(ARMATURE_OT_duplicate); @@ -264,6 +265,8 @@ void ED_keymap_armature(wmKeyConfig *keyconf) 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); + + WM_keymap_add_item(keymap, "ARMATURE_OT_shortest_path_pick", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_delete", DELKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index cd24e94f9e9..087e9a86241 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -454,7 +454,7 @@ static void separate_armature_bones(Object *ob, short sel) } /* separate selected bones into their armature */ -static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op)) +static int separate_armature_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -520,6 +520,8 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op)) ED_armature_to_edit(obedit); + BKE_report(op->reports, RPT_INFO, "Separated bones"); + /* note, notifier might evolve */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit); @@ -537,7 +539,6 @@ void ARMATURE_OT_separate(wmOperatorType *ot) ot->description = "Isolate selected bones into a separate armature"; /* callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = separate_armature_exec; ot->poll = ED_operator_editarmature; diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 003f6bf36f3..ed2d1388196 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -174,7 +174,7 @@ static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEv { bArmature *arm; EditBone *bone, *curBone, *next; - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); Object *obedit = CTX_data_edit_object(C); arm = obedit->data; @@ -1120,3 +1120,123 @@ void ARMATURE_OT_select_mirror(wmOperatorType *ot) RNA_def_boolean(ot->srna, "only_active", false, "Active Only", "Only operate on the active bone"); RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); } + + +/****************** Select Path ****************/ + +static bool armature_shortest_path_select(bArmature *arm, EditBone *ebone_parent, EditBone *ebone_child, + bool use_parent, bool is_test) +{ + do { + + if (!use_parent && (ebone_child == ebone_parent)) + break; + + if (is_test) { + if (!EBONE_SELECTABLE(arm, ebone_child)) { + return false; + } + } + else { + ED_armature_ebone_selectflag_set(ebone_child, (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL)); + } + + if (ebone_child == ebone_parent) + break; + + ebone_child = ebone_child->parent; + } while (true); + + return true; +} + +static int armature_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *obedit = CTX_data_edit_object(C); + bArmature *arm = obedit->data; + EditBone *ebone_src, *ebone_dst; + EditBone *ebone_isect_parent = NULL; + EditBone *ebone_isect_child[2]; + bool changed; + + view3d_operator_needs_opengl(C); + + ebone_src = arm->act_edbone; + ebone_dst = get_nearest_bone(C, 0, event->mval[0], event->mval[1]); + + /* fallback to object selection */ + if (ELEM(NULL, ebone_src, ebone_dst) || (ebone_src == ebone_dst)) { + return OPERATOR_PASS_THROUGH; + } + + ebone_isect_child[0] = ebone_src; + ebone_isect_child[1] = ebone_dst; + + + /* ensure 'ebone_src' is the parent of 'ebone_dst', or set 'ebone_isect_parent' */ + if (ED_armature_ebone_is_child_recursive(ebone_src, ebone_dst)) { + /* pass */ + } + else if (ED_armature_ebone_is_child_recursive(ebone_dst, ebone_src)) { + SWAP(EditBone *, ebone_src, ebone_dst); + } + else if ((ebone_isect_parent = ED_armature_bone_find_shared_parent(ebone_isect_child, 2))) { + /* pass */ + } + else { + /* disconnected bones */ + return OPERATOR_CANCELLED; + } + + + if (ebone_isect_parent) { + if (armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, true) && + armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, true)) + { + armature_shortest_path_select(arm, ebone_isect_parent, ebone_src, false, false); + armature_shortest_path_select(arm, ebone_isect_parent, ebone_dst, false, false); + changed = true; + } + else { + /* unselectable */ + changed = false; + } + } + else { + if (armature_shortest_path_select(arm, ebone_src, ebone_dst, true, true)) { + armature_shortest_path_select(arm, ebone_src, ebone_dst, true, false); + changed = true; + } + else { + /* unselectable */ + changed = false; + } + } + + if (changed) { + arm->act_edbone = ebone_dst; + ED_armature_sync_selection(arm->edbo); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "Unselectable bone in chain"); + return OPERATOR_CANCELLED; + } +} + +void ARMATURE_OT_shortest_path_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Pick Shortest Path"; + ot->idname = "ARMATURE_OT_shortest_path_pick"; + ot->description = "Select shortest path between two bones"; + + /* api callbacks */ + ot->invoke = armature_shortest_path_pick_invoke; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 5f15d15d478..7ec0acf12d1 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -386,9 +386,13 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, /* compute the weights based on gathered vertices and bones */ if (heat) { const char *error = NULL; + +#ifdef WITH_OPENNL heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip, root, tip, selected, &error); - +#else + error = "Built without OpenNL"; +#endif if (error) { BKE_report(reports, RPT_WARNING, error); } diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c index 2cbfb52db91..7d6b3710a38 100644 --- a/source/blender/editors/armature/armature_utils.c +++ b/source/blender/editors/armature/armature_utils.c @@ -156,6 +156,47 @@ bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebon return false; } +/** + * Finds the first parent shared by \a ebone_child + * + * \param ebone_child Children bones to search + * \param ebone_child_tot Size of the ebone_child array + * \return The shared parent or NULL. + */ +EditBone *ED_armature_bone_find_shared_parent(EditBone *ebone_child[], const unsigned int ebone_child_tot) +{ + unsigned int i; + EditBone *ebone_iter; + +#define EBONE_TEMP_UINT(ebone) (*((unsigned int *)(&((ebone)->temp)))) + + /* clear all */ + for (i = 0; i < ebone_child_tot; i++) { + for (ebone_iter = ebone_child[i]; ebone_iter; ebone_iter = ebone_iter->parent) { + EBONE_TEMP_UINT(ebone_iter) = 0; + } + } + + /* accumulate */ + for (i = 0; i < ebone_child_tot; i++) { + ebone_iter = ebone_child[i]; + for (ebone_iter = ebone_child[i]->parent; ebone_iter; ebone_iter = ebone_iter->parent) { + EBONE_TEMP_UINT(ebone_iter) += 1; + } + } + + /* only need search the first chain */ + for (ebone_iter = ebone_child[0]->parent; ebone_iter; ebone_iter = ebone_iter->parent) { + if (EBONE_TEMP_UINT(ebone_iter) == ebone_child_tot) { + return ebone_iter; + } + } + +#undef EBONE_TEMP_UINT + + return NULL; +} + void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]) { float delta[3]; @@ -460,6 +501,7 @@ void ED_armature_from_edit(Object *obedit) /* armature bones */ BKE_armature_bonelist_free(&arm->bonebase); + arm->act_bone = NULL; /* remove zero sized bones, this gives unstable restposes */ for (eBone = arm->edbo->first; eBone; eBone = neBone) { @@ -593,7 +635,6 @@ void ED_armature_to_edit(Object *ob) ED_armature_edit_free(ob); arm->edbo = MEM_callocN(sizeof(ListBase), "edbo armature"); arm->act_edbone = make_boneList(arm->edbo, &arm->bonebase, NULL, arm->act_bone); - arm->act_bone = NULL; // BIF_freeTemplates(); /* force template update when entering editmode */ } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index c03e7861307..2c00c5e646c 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -697,7 +697,7 @@ static int RIG_parentControl(RigControl *ctrl, EditBone *link) static void RIG_reconnectControlBones(RigGraph *rg) { RigControl *ctrl; - int change = 1; + bool changed = true; /* first pass, link to deform bones */ for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { @@ -812,8 +812,8 @@ static void RIG_reconnectControlBones(RigGraph *rg) /* second pass, make chains in control bones */ - while (change) { - change = 0; + while (changed) { + changed = false; for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { /* if control is not linked yet */ @@ -865,7 +865,7 @@ static void RIG_reconnectControlBones(RigGraph *rg) /* check if parent is already linked */ if (ctrl_parent && ctrl_parent->link) { RIG_parentControl(ctrl, ctrl_parent->bone); - change = 1; + changed = true; } else { /* check childs */ @@ -873,7 +873,7 @@ static void RIG_reconnectControlBones(RigGraph *rg) /* if a child is linked, link to that one */ if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone) { RIG_parentControl(ctrl, ctrl_child->bone); - change = 1; + changed = true; break; } } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 16d7f9c9420..3b285e12331 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -46,13 +46,14 @@ #include "BLI_polardecomp.h" #endif -#include "ONL_opennl.h" - #include "ED_mesh.h" #include "ED_armature.h" #include "meshlaplacian.h" +#ifdef WITH_OPENNL + +#include "ONL_opennl.h" /* ************* XXX *************** */ static void waitcursor(int UNUSED(val)) {} @@ -2006,3 +2007,13 @@ void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexco waitcursor(0); } +#else /* WITH_OPENNL */ + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4]) {} +void *modifier_mdef_compact_influences_link_kludge = modifier_mdef_compact_influences; + +#endif /* WITH_OPENNL */ diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 69ee794e1d9..ce10214c2ee 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -105,7 +105,7 @@ static int poselib_get_free_index(bAction *act) { TimeMarker *marker; int low = 0, high = 0; - short changed = 0; + bool changed = false; /* sanity checks */ if (ELEM(NULL, act, act->markers.first)) return 1; @@ -115,7 +115,7 @@ static int poselib_get_free_index(bAction *act) * Prevents problems with deleting then trying to add new poses [#27412] */ do { - changed = 0; + changed = false; for (marker = act->markers.first; marker; marker = marker->next) { /* only increase low if value is 1 greater than low, to find "gaps" where @@ -123,13 +123,13 @@ static int poselib_get_free_index(bAction *act) */ if (marker->frame == (low + 1)) { low++; - changed = 1; + changed = true; } /* value replaces high if it is the highest value encountered yet */ if (marker->frame > high) { high = marker->frame; - changed = 1; + changed = true; } } } while (changed != 0); diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 765437f3622..34023d365ca 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -180,7 +180,10 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor * (e.g. Mask Modifier in 'Armature' mode), force update */ else if (arm->flag & ARM_HAS_VIZ_DEPS) { - DAG_id_tag_update(&ob_act->id, OB_RECALC_DATA); + /* NOTE: ob not ob_act here is intentional - it's the source of the + * bones being selected [T37247] + */ + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } } } @@ -263,7 +266,7 @@ static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEve Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bArmature *arm = (bArmature *)ob->data; Bone *bone, *curBone, *next = NULL; - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); view3d_operator_needs_opengl(C); @@ -625,13 +628,13 @@ void POSE_OT_select_hierarchy(wmOperatorType *ot) /* -------------------------------------- */ -static short pose_select_same_group(bContext *C, Object *ob, bool extend) +static bool pose_select_same_group(bContext *C, Object *ob, bool extend) { bArmature *arm = (ob) ? ob->data : NULL; bPose *pose = (ob) ? ob->pose : NULL; char *group_flags; int numGroups = 0; - short changed = 0, tagged = 0; + bool changed = false, tagged = false; /* sanity checks */ if (ELEM3(NULL, ob, pose, arm)) @@ -653,7 +656,7 @@ static short pose_select_same_group(bContext *C, Object *ob, bool extend) /* keep track of group as group to use later? */ if (pchan->bone->flag & BONE_SELECTED) { group_flags[pchan->agrp_index] = 1; - tagged = 1; + tagged = true; } /* deselect all bones before selecting new ones? */ @@ -671,7 +674,7 @@ static short pose_select_same_group(bContext *C, Object *ob, bool extend) /* check if the group used by this bone is counted */ if (group_flags[pchan->agrp_index]) { pchan->bone->flag |= BONE_SELECTED; - changed = 1; + changed = true; } } } @@ -684,11 +687,11 @@ static short pose_select_same_group(bContext *C, Object *ob, bool extend) return changed; } -static short pose_select_same_layer(bContext *C, Object *ob, bool extend) +static bool pose_select_same_layer(bContext *C, Object *ob, bool extend) { bPose *pose = (ob) ? ob->pose : NULL; bArmature *arm = (ob) ? ob->data : NULL; - short changed = 0; + bool changed = false; int layers = 0; if (ELEM3(NULL, ob, pose, arm)) @@ -715,7 +718,7 @@ static short pose_select_same_layer(bContext *C, Object *ob, bool extend) /* if bone is on a suitable layer, and the bone can have its selection changed, select it */ if ((layers & pchan->bone->layer) && (pchan->bone->flag & BONE_UNSELECTABLE) == 0) { pchan->bone->flag |= BONE_SELECTED; - changed = 1; + changed = true; } } CTX_DATA_END; @@ -723,14 +726,14 @@ static short pose_select_same_layer(bContext *C, Object *ob, bool extend) return changed; } -static int pose_select_same_keyingset(bContext *C, Object *ob, bool extend) +static bool pose_select_same_keyingset(bContext *C, Object *ob, bool extend) { KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C)); KS_Path *ksp; bArmature *arm = (ob) ? ob->data : NULL; bPose *pose = (ob) ? ob->pose : NULL; - short changed = 0; + bool changed = false; /* sanity checks: validate Keying Set and object */ if ((ks == NULL) || (ANIM_validate_keyingset(C, NULL, ks) != 0)) @@ -765,7 +768,7 @@ static int pose_select_same_keyingset(bContext *C, Object *ob, bool extend) /* select if bone is visible and can be affected */ if (PBONE_SELECTABLE(arm, pchan->bone)) { pchan->bone->flag |= BONE_SELECTED; - changed = 1; + changed = true; } } @@ -783,8 +786,8 @@ static int pose_select_grouped_exec(bContext *C, wmOperator *op) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bArmature *arm = (bArmature *)ob->data; - short extend = RNA_boolean_get(op->ptr, "extend"); - short changed = 0; + const bool extend = RNA_boolean_get(op->ptr, "extend"); + bool changed = false; /* sanity check */ if (ob->pose == NULL) diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index da8f86580f6..3ee83c20852 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -118,6 +118,8 @@ void CURVE_OT_vertex_add(struct wmOperatorType *ot); void CURVE_OT_extrude(struct wmOperatorType *ot); void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot); +void CURVE_OT_match_texture_space(struct wmOperatorType *ot); + /* helper functions */ void ed_editnurb_translate_flag(struct ListBase *editnurb, short flag, const float vec[3]); bool ed_editnurb_extrude_flag(struct EditNurb *editnurb, short flag); diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index 1cf194e02c4..e978b81523f 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -137,6 +137,8 @@ void ED_operatortypes_curve(void) WM_operatortype_append(CURVE_OT_vertex_add); WM_operatortype_append(CURVE_OT_extrude); WM_operatortype_append(CURVE_OT_cyclic_toggle); + + WM_operatortype_append(CURVE_OT_match_texture_space); } void ED_operatormacros_curve(void) diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index f576440fe92..caa06eb15d0 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -47,6 +47,7 @@ #include "BKE_context.h" #include "BKE_curve.h" #include "BKE_depsgraph.h" +#include "BKE_displist.h" #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_key.h" @@ -2307,11 +2308,12 @@ static int smooth_exec(bContext *C, wmOperator *UNUSED(op)) BezTriple *bezt, *beztOrig; BPoint *bp, *bpOrig; float val, newval, offset; - int a, i, change = 0; + int a, i; + bool changed = false; for (nu = editnurb->first; nu; nu = nu->next) { if (nu->bezt) { - change = 0; + changed = false; beztOrig = MEM_dupallocN(nu->bezt); for (bezt = &nu->bezt[1], a = 1; a < nu->pntsu - 1; a++, bezt++) { if (bezt->f2 & SELECT) { @@ -2324,12 +2326,13 @@ static int smooth_exec(bContext *C, wmOperator *UNUSED(op)) bezt->vec[0][i] += offset; bezt->vec[2][i] += offset; } - change = 1; + changed = true; } } MEM_freeN(beztOrig); - if (change) + if (changed) { BKE_nurb_handles_calc(nu); + } } else if (nu->bp) { bpOrig = MEM_dupallocN(nu->bp); @@ -3568,7 +3571,7 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu; - bool change = false; + bool changed = false; const bool use_handles = RNA_boolean_get(op->ptr, "use_handles"); const int type = RNA_enum_get(op->ptr, "type"); @@ -3582,11 +3585,11 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) if (BKE_nurb_type_convert(nu, type, use_handles) == false) BKE_report(op->reports, RPT_ERROR, "No conversion possible"); else - change = true; + changed = true; } } - if (change) { + if (changed) { if (ED_curve_updateAnimPaths(obedit->data)) WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, obedit); @@ -4364,7 +4367,7 @@ bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3], Curve *cu = (Curve *)obedit->data; ListBase *editnurb = object_editcurve_get(obedit); Nurb *nu; - float si, phi, n[3], q[4], cmat[3][3], tmat[3][3], imat[3][3]; + float cmat[3][3], tmat[3][3], imat[3][3]; float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3]; float persmat[3][3], persinv[3][3]; bool ok, changed = false; @@ -4377,15 +4380,7 @@ bool ed_editnurb_spin(float viewmat[4][4], Object *obedit, const float axis[3], copy_m3_m4(bmat, obedit->obmat); invert_m3_m3(imat, bmat); - normalize_v3_v3(n, axis); - /* TODO - use math func */ - phi = M_PI / 8.0; - q[0] = cos(phi); - si = sin(phi); - q[1] = n[0] * si; - q[2] = n[1] * si; - q[3] = n[2] * si; - quat_to_mat3(cmat, q); + axis_angle_to_mat3(cmat, axis, M_PI / 4.0); mul_m3_m3m3(tmat, cmat, bmat); mul_m3_m3m3(rotmat, imat, tmat); @@ -6367,7 +6362,7 @@ static int curve_delete_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); Curve *cu = (Curve *)obedit->data; eCurveElem_Types type = RNA_enum_get(op->ptr, "type"); - int retval; + int retval = OPERATOR_CANCELLED; if (type == CURVE_VERTEX) retval = curve_delete_vertices(obedit); else if (type == CURVE_SEGMENT) retval = curve_delete_segments(obedit, false); @@ -6813,3 +6808,65 @@ int ED_curve_actSelection(Curve *cu, float center[3]) return 1; } + +/******************** Match texture space operator ***********************/ + +static int match_texture_space_poll(bContext *C) +{ + Object *object = CTX_data_active_object(C); + + return object && ELEM3(object->type, OB_CURVE, OB_SURF, OB_FONT); +} + +static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + Object *object = CTX_data_active_object(C); + Curve *curve = (Curve *) object->data; + float min[3], max[3], size[3], loc[3]; + int a; + + if (ELEM(NULL, object->curve_cache, object->curve_cache->disp.first)) { + BKE_displist_make_curveTypes(scene, object, FALSE); + } + + INIT_MINMAX(min, max); + BKE_displist_minmax(&object->curve_cache->disp, min, max); + + mid_v3_v3v3(loc, min, max); + + size[0] = (max[0] - min[0]) / 2.0f; + size[1] = (max[1] - min[1]) / 2.0f; + size[2] = (max[2] - min[2]) / 2.0f; + + for (a = 0; a < 3; a++) { + if (size[a] == 0.0f) size[a] = 1.0f; + else if (size[a] > 0.0f && size[a] < 0.00001f) size[a] = 0.00001f; + else if (size[a] < 0.0f && size[a] > -0.00001f) size[a] = -0.00001f; + } + + copy_v3_v3(curve->loc, loc); + copy_v3_v3(curve->size, size); + zero_v3(curve->rot); + + curve->texflag &= ~CU_AUTOSPACE; + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curve); + + return OPERATOR_FINISHED; +} + +void CURVE_OT_match_texture_space(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Match Texture Space"; + ot->idname = "CURVE_OT_match_texture_space"; + ot->description = "Match texture space to object's bounding box"; + + /* api callbacks */ + ot->exec = match_texture_space_exec; + ot->poll = match_texture_space_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 8f536575a28..baedc7ecf25 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -780,6 +780,9 @@ static int paste_selection(Object *obedit, ReportList *reports) /* Verify that the copy buffer => [copy buffer len] + cu->len < MAXTEXT */ if (cu->len + len <= MAXTEXT) { + + kill_selection(obedit, 0); + if (len) { int size = (cu->len * sizeof(wchar_t)) - (cu->pos * sizeof(wchar_t)) + sizeof(wchar_t); memmove(ef->textbuf + cu->pos + len, ef->textbuf + cu->pos, size); diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index aee97f40c31..a03a80bfbbc 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -209,21 +209,24 @@ void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short /* Frame Editing Tools */ /* Delete selected frames */ -void ED_gplayer_frames_delete(bGPDlayer *gpl) +bool ED_gplayer_frames_delete(bGPDlayer *gpl) { bGPDframe *gpf, *gpfn; + bool changed = false; /* error checking */ if (gpl == NULL) - return; + return false; /* check for frames to delete */ for (gpf = gpl->frames.first; gpf; gpf = gpfn) { gpfn = gpf->next; if (gpf->flag & GP_FRAME_SELECT) - gpencil_layer_delframe(gpl, gpf); + changed |= gpencil_layer_delframe(gpl, gpf); } + + return changed; } /* Duplicate selected frames from given gp-layer */ diff --git a/source/blender/editors/include/BIF_gl.h b/source/blender/editors/include/BIF_gl.h index cdf9b71972d..a3d3d8f05a2 100644 --- a/source/blender/editors/include/BIF_gl.h +++ b/source/blender/editors/include/BIF_gl.h @@ -53,7 +53,7 @@ * color, while not being endian-sensitive. On little-endians, this * is the same as doing a 'naive' indexing, on big-endian, it is not! * */ -#define cpack(x) glColor3ub( ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16) & 0xFF) ) +void cpack(unsigned int x); #define glMultMatrixf(x) glMultMatrixf( (float *)(x)) #define glLoadMatrixf(x) glLoadMatrixf( (float *)(x)) diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index d98fa1fc32f..8b9bb0a4ab0 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -396,15 +396,15 @@ typedef struct bAnimChannelType { /* get name (for channel lists) */ void (*name)(bAnimListElem *ale, char *name); /* get RNA property+pointer for editing the name */ - short (*name_prop)(bAnimListElem *ale, struct PointerRNA *ptr, struct PropertyRNA **prop); + bool (*name_prop)(bAnimListElem *ale, struct PointerRNA *ptr, struct PropertyRNA **prop); /* get icon (for channel lists) */ int (*icon)(bAnimListElem *ale); /* settings */ /* check if the given setting is valid in the current context */ - short (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting); + bool (*has_setting)(bAnimContext *ac, bAnimListElem *ale, int setting); /* get the flag used for this setting */ - int (*setting_flag)(bAnimContext *ac, int setting, short *neg); + int (*setting_flag)(bAnimContext *ac, int setting, bool *neg); /* get the pointer to int/short where data is stored, * with type being sizeof(ptr_data) which should be fine for runtime use... * - assume that setting has been checked to be valid for current context diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 455378fc2ce..e9caf89d9da 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -138,6 +138,7 @@ struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *na void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone); bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child); +EditBone *ED_armature_bone_find_shared_parent(EditBone *ebone_child[], const unsigned int ebone_child_tot); void ED_armature_ebone_to_mat3(EditBone *ebone, float mat[3][3]); void ED_armature_ebone_to_mat4(EditBone *ebone, float mat[4][4]); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index cb4a81be8b8..4e05c6c9fb6 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -95,7 +95,7 @@ void ED_gplayer_frames_select_border(struct bGPDlayer *gpl, float min, float ma void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode); void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode); -void ED_gplayer_frames_delete(struct bGPDlayer *gpl); +bool ED_gplayer_frames_delete(struct bGPDlayer *gpl); void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl); void ED_gplayer_snap_frames(struct bGPDlayer *gpl, struct Scene *scene, short mode); diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 3020fe6985a..5718a70208e 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -237,7 +237,7 @@ void bezt_remap_times(KeyframeEditData *ked, struct BezTriple *bezt); /* Destructive Editing API (keyframes_general.c) */ void delete_fcurve_key(struct FCurve *fcu, int index, short do_recalc); -void delete_fcurve_keys(struct FCurve *fcu); +bool delete_fcurve_keys(struct FCurve *fcu); void clear_fcurve_keys(struct FCurve *fcu); void duplicate_fcurve_keys(struct FCurve *fcu); diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h index 8da36f015dc..3f8d571b239 100644 --- a/source/blender/editors/include/ED_mask.h +++ b/source/blender/editors/include/ED_mask.h @@ -68,8 +68,8 @@ void ED_mask_draw_frames(struct Mask *mask, struct ARegion *ar, const int cfra, /* mask_shapekey.c */ void ED_mask_layer_shape_auto_key(struct MaskLayer *masklay, const int frame); -int ED_mask_layer_shape_auto_key_all(struct Mask *mask, const int frame); -int ED_mask_layer_shape_auto_key_select(struct Mask *mask, const int frame); +bool ED_mask_layer_shape_auto_key_all(struct Mask *mask, const int frame); +bool ED_mask_layer_shape_auto_key_select(struct Mask *mask, const int frame); /* ----------- Mask AnimEdit API ------------------ */ short ED_masklayer_frames_looper(struct MaskLayer *masklay, struct Scene *scene, @@ -82,7 +82,7 @@ void ED_masklayer_frames_select_border(struct MaskLayer *masklay, float min, fl void ED_mask_select_frames(struct MaskLayer *masklay, short select_mode); void ED_mask_select_frame(struct MaskLayer *masklay, int selx, short select_mode); -void ED_masklayer_frames_delete(struct MaskLayer *masklay); +bool ED_masklayer_frames_delete(struct MaskLayer *masklay); void ED_masklayer_frames_duplicate(struct MaskLayer *masklay); void ED_masklayer_snap_frames(struct MaskLayer *masklay, struct Scene *scene, short mode); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index e85f11e5b78..ed7415e6c26 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -65,8 +65,20 @@ void ED_keymap_paint(struct wmKeyConfig *keyconf); #define UNDO_PAINT_IMAGE 0 #define UNDO_PAINT_MESH 1 +typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb); +typedef void (*UndoFreeCb)(struct ListBase *lb); + int ED_undo_paint_step(struct bContext *C, int type, int step, const char *name); void ED_undo_paint_free(void); int ED_undo_paint_valid(int type, const char *name); +void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free); +void ED_undo_paint_push_end(int type); + +/* image painting specific undo */ +void ED_image_undo_restore(struct bContext *C, struct ListBase *lb); +void ED_image_undo_free(struct ListBase *lb); +void ED_imapaint_clear_partial_redraw(void); +void ED_imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h); + #endif diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index dde1aa30a26..35f12a47f82 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -121,8 +121,9 @@ struct ReportList; void BIF_clearTransformOrientation(struct bContext *C); void BIF_removeTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_removeTransformOrientationIndex(struct bContext *C, int index); -void BIF_createTransformOrientation(struct bContext *C, struct ReportList *reports, char *name, int use_view, - int use, int overwrite); +void BIF_createTransformOrientation(struct bContext *C, struct ReportList *reports, + const char *name, const bool use_view, + const bool activate, const bool overwrite); void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_selectTransformOrientationValue(struct bContext *C, int orientation); @@ -143,6 +144,7 @@ int BIF_countTransformOrientation(const struct bContext *C); #define P_OPTIONS (1 << 7) #define P_CORRECT_UV (1 << 8) #define P_NO_DEFAULTS (1 << 10) +#define P_NO_TEXSPACE (1 << 11) void Transform_Properties(struct wmOperatorType *ot, int flags); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 0f3106794f5..f155247f851 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -85,6 +85,8 @@ typedef struct ViewDepths { float *ED_view3d_cursor3d_get(struct Scene *scene, struct View3D *v3d); void ED_view3d_cursor3d_position(struct bContext *C, float fp[3], const int mval[2]); +struct Camera *ED_view3d_camera_data_get(struct View3D *v3d, struct RegionView3D *rv3d); + void ED_view3d_to_m4(float mat[4][4], const float ofs[3], const float quat[4], const float dist); void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist); @@ -216,6 +218,9 @@ bool ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *r_clipsta, float *r_clipend, const bool use_ortho_factor); bool ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *r_viewplane, float *r_clipsta, float *r_clipend, float *r_pixsize); + +void ED_view3d_polygon_offset(const struct RegionView3D *rv3d, const float dist); + void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *r_viewborder, const bool no_shift); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 50e2e53dbf0..e931aad2722 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -93,7 +93,7 @@ typedef struct uiLayout uiLayout; /* use for clamping popups within the screen */ #define UI_SCREEN_MARGIN 10 -/* uiBlock->dt */ +/* uiBlock->dt and uiBut->dt */ #define UI_EMBOSS 0 /* use widget style for drawing */ #define UI_EMBOSSN 1 /* Nothing, only icon and/or text */ #define UI_EMBOSSP 2 /* Pulldown menu style */ @@ -130,8 +130,7 @@ typedef struct uiLayout uiLayout; #define UI_BLOCK_POPUP_MEMORY (1 << 12) #define UI_BLOCK_CLIP_EVENTS (1 << 13) /* stop handling mouse events */ -/* XXX This comment is no more valid! Maybe it is now bits 14-17? */ -/* block->flag bits 12-15 are identical to but->flag bits */ +/* block->flag bits 14-17 are identical to but->drawflag bits */ #define UI_BLOCK_LIST_ITEM (1 << 19) @@ -148,46 +147,55 @@ typedef struct uiLayout uiLayout; #define UI_PNL_CLOSE (1 << 5) #define UI_PNL_SCALE (1 << 9) -/* warning the first 6 flags are internal */ -/* but->flag */ -#define UI_TEXT_LEFT (1 << 6) -#define UI_ICON_LEFT (1 << 7) -#define UI_ICON_SUBMENU (1 << 8) -#define UI_ICON_PREVIEW (1 << 9) - -#define UI_TEXT_RIGHT (1 << 10) -#define UI_BUT_NODE_LINK (1 << 11) -#define UI_BUT_NODE_ACTIVE (1 << 12) -#define UI_BUT_DRAG_LOCK (1 << 13) - -/* button align flag, for drawing groups together */ -#define UI_BUT_ALIGN (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT | UI_BUT_ALIGN_DOWN) -#define UI_BUT_ALIGN_TOP (1 << 14) -#define UI_BUT_ALIGN_LEFT (1 << 15) -#define UI_BUT_ALIGN_RIGHT (1 << 16) -#define UI_BUT_ALIGN_DOWN (1 << 17) - -#define UI_BUT_DISABLED (1 << 18) -#define UI_BUT_COLOR_LOCK (1 << 19) -#define UI_BUT_ANIMATED (1 << 20) -#define UI_BUT_ANIMATED_KEY (1 << 21) -#define UI_BUT_DRIVEN (1 << 22) -#define UI_BUT_REDALERT (1 << 23) -#define UI_BUT_INACTIVE (1 << 24) -#define UI_BUT_LAST_ACTIVE (1 << 25) -#define UI_BUT_UNDO (1 << 26) -#define UI_BUT_IMMEDIATE (1 << 27) -#define UI_BUT_NO_TOOLTIP (1 << 28) -#define UI_BUT_NO_UTF8 (1 << 29) - -#define UI_BUT_VEC_SIZE_LOCK (1 << 30) /* used to flag if color hsv-circle should keep luminance */ -#define UI_BUT_COLOR_CUBIC (1 << 31) /* cubic saturation for the color wheel */ +/* but->flag - general state flags. */ +enum { + /* warning, the first 6 flags are internal */ + UI_ICON_SUBMENU = (1 << 6), + UI_ICON_PREVIEW = (1 << 7), + + UI_BUT_NODE_LINK = (1 << 8), + UI_BUT_NODE_ACTIVE = (1 << 9), + UI_BUT_DRAG_LOCK = (1 << 10), + UI_BUT_DISABLED = (1 << 11), + UI_BUT_COLOR_LOCK = (1 << 12), + UI_BUT_ANIMATED = (1 << 13), + UI_BUT_ANIMATED_KEY = (1 << 14), + UI_BUT_DRIVEN = (1 << 15), + UI_BUT_REDALERT = (1 << 16), + UI_BUT_INACTIVE = (1 << 17), + UI_BUT_LAST_ACTIVE = (1 << 18), + UI_BUT_UNDO = (1 << 19), + UI_BUT_IMMEDIATE = (1 << 20), + UI_BUT_NO_UTF8 = (1 << 21), + + UI_BUT_VEC_SIZE_LOCK = (1 << 22), /* used to flag if color hsv-circle should keep luminance */ + UI_BUT_COLOR_CUBIC = (1 << 23), /* cubic saturation for the color wheel */ + UI_BUT_LIST_ITEM = (1 << 24), /* This but is "inside" a list item (currently used to change theme colors). */ +}; #define UI_PANEL_WIDTH 340 #define UI_COMPACT_PANEL_WIDTH 160 -/* uiBut->drawflag */ -#define UI_BUT_DRAW_ENUM_ARROWS (1 << 0) /* draw enum-like up/down arrows for button */ +/* but->drawflag - these flags should only affect how the button is drawn. */ +/* Note: currently, these flags _are not passed_ to the widget's state() or draw() functions + * (except for the 'align' ones)! + */ +enum { + /* draw enum-like up/down arrows for button */ + UI_BUT_DRAW_ENUM_ARROWS = (1 << 0), + /* Text and icon alignment (by default, they are centered). */ + UI_BUT_TEXT_LEFT = (1 << 1), + UI_BUT_ICON_LEFT = (1 << 2), + UI_BUT_TEXT_RIGHT = (1 << 3), + /* Prevent the button to show any tooltip. */ + UI_BUT_NO_TOOLTIP = (1 << 4), + /* button align flag, for drawing groups together (also used in uiBlock->flag!) */ + UI_BUT_ALIGN_TOP = (1 << 14), + UI_BUT_ALIGN_LEFT = (1 << 15), + UI_BUT_ALIGN_RIGHT = (1 << 16), + UI_BUT_ALIGN_DOWN = (1 << 17), + UI_BUT_ALIGN = (UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT | UI_BUT_ALIGN_RIGHT | UI_BUT_ALIGN_DOWN), +}; /* scale fixed button widths by this to account for DPI */ @@ -259,7 +267,6 @@ typedef enum { PROGRESSBAR = (51 << 9), SEARCH_MENU_UNLINK = (52 << 9), NODESOCKET = (53 << 9), - LISTLABEL = (54 << 9), } eButType; #define BUTTYPE (63 << 9) @@ -314,7 +321,7 @@ typedef struct uiSearchItems uiSearchItems; typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2); typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr); typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2); -typedef bool (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); +typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items); typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); @@ -425,7 +432,6 @@ void uiButSetDragValue(uiBut *but); void uiButSetDragImage(uiBut *but, const char *path, int icon, struct ImBuf *ima, float scale); int UI_but_active_drop_name(struct bContext *C); -struct uiBut *ui_but_find_mouse_over(struct ARegion *ar, int x, int y); void uiButSetFlag(uiBut *but, int flag); void uiButClearFlag(uiBut *but, int flag); @@ -468,7 +474,6 @@ uiBut *uiDefButR(uiBlock *block, int type, int retval, const char *str, int x, i uiBut *uiDefButR_prop(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip); uiBut *uiDefButO_ptr(uiBlock *block, int type, struct wmOperatorType *ot, int opcontext, const char *str, int x, int y, short width, short height, const char *tip); -uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip); uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, @@ -628,8 +633,9 @@ void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), void *arg1, void *arg2); -bool UI_textbutton_activate_event(const struct bContext *C, struct ARegion *ar, - const void *rna_poin_data, const char *rna_prop_id); +bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar, + const void *rna_poin_data, const char *rna_prop_id); +bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but); void uiButSetFocusOnEnter(struct wmWindow *win, uiBut *but); @@ -681,6 +687,7 @@ void UI_remove_popup_handlers_all(struct bContext *C, struct ListBase *handlers) void UI_init(void); void UI_init_userdef(void); +void UI_init_userdef_factory(void); void UI_reinit_font(void); void UI_exit(void); @@ -896,9 +903,9 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop /* Styled text draw */ void uiStyleFontSet(struct uiFontStyle *fs); void uiStyleFontDrawExt(struct uiFontStyle *fs, const struct rcti *rect, const char *str, - float *r_xofs, float *r_yofs); -void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, const char *str); -void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, const char *str); + size_t len, float *r_xofs, float *r_yofs); +void uiStyleFontDraw(struct uiFontStyle *fs, const struct rcti *rect, const char *str); +void uiStyleFontDrawRotated(struct uiFontStyle *fs, const struct rcti *rect, const char *str); int UI_GetStringWidth(const char *str); // XXX temp void UI_DrawString(float x, float y, const char *str); // XXX temp diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 0c8a39a6714..af0df0e0643 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -144,9 +144,17 @@ enum { TH_EMPTY, TH_NODE, - TH_NODE_IN_OUT, + TH_NODE_INPUT, + TH_NODE_OUTPUT, + TH_NODE_COLOR, + TH_NODE_FILTER, + TH_NODE_VECTOR, + TH_NODE_TEXTURE, + TH_NODE_PATTERN, + TH_NODE_SCRIPT, + TH_NODE_LAYOUT, + TH_NODE_SHADER, TH_NODE_INTERFACE, - TH_NODE_OPERATOR, TH_NODE_CONVERTOR, TH_NODE_GROUP, TH_NODE_FRAME, diff --git a/source/blender/editors/include/UI_view2d.h b/source/blender/editors/include/UI_view2d.h index c9a19ab4d8e..da26b3d71a4 100644 --- a/source/blender/editors/include/UI_view2d.h +++ b/source/blender/editors/include/UI_view2d.h @@ -155,7 +155,7 @@ void UI_view2d_totRect_set(struct View2D *v2d, int width, int height); void UI_view2d_totRect_set_resize(struct View2D *v2d, int width, int height, int resize); /* per tab offsets, returns 1 if tab changed */ -int UI_view2d_tab_set(struct View2D *v2d, int tab); +bool UI_view2d_tab_set(struct View2D *v2d, int tab); /* view matrix operations */ void UI_view2d_view_ortho(struct View2D *v2d); @@ -208,7 +208,7 @@ short UI_view2d_mouse_in_scrollers(const struct bContext *C, struct View2D *v2d, /* cached text drawing in v2d, to allow pixel-aligned draw as post process */ void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, const char col[4]); -void UI_view2d_text_cache_rectf(struct View2D *v2d, struct rctf *rect, const char *str, const char col[4]); +void UI_view2d_text_cache_rectf(struct View2D *v2d, const struct rctf *rect, const char *str, const char col[4]); void UI_view2d_text_cache_draw(struct ARegion *ar); /* operators */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 83b100db1b2..45a73e217fe 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -218,7 +218,7 @@ static void ui_text_bounds_block(uiBlock *block, float offset) for (bt = block->buttons.first; bt; bt = bt->next) { if (bt->type != SEPR) { - j = BLF_width(style->widget.uifont_id, bt->drawstr); + j = BLF_width(style->widget.uifont_id, bt->drawstr, sizeof(bt->drawstr)); if (j > i) i = j; } @@ -613,6 +613,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut { /* flags from the buttons we want to refresh, may want to add more here... */ const int flag_copy = UI_BUT_REDALERT; + const int drawflag_copy = 0; /* None currently. */ uiBlock *oldblock; uiBut *oldbut, *but = *butpp; @@ -670,8 +671,9 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut SWAP(char *, oldbut->poin, but->poin); SWAP(void *, oldbut->func_argN, but->func_argN); } - + oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); + oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position * when scrolling without moving mouse (see [#28432]) */ @@ -2436,36 +2438,47 @@ void ui_check_but(uiBut *but) case NUMSLI: if (!but->editstr) { + const char *drawstr_suffix = NULL; + size_t slen; + UI_GET_BUT_VALUE_INIT(but, value); + slen = BLI_strncpy_rlen(but->drawstr, but->str, sizeof(but->drawstr)); + if (ui_is_but_float(but)) { if (value == (double) FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%sinf", but->str); + slen += BLI_strncpy_rlen(but->drawstr + slen, "inf", sizeof(but->drawstr) - slen); } else if (value == (double) -FLT_MAX) { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s-inf", but->str); + slen += BLI_strncpy_rlen(but->drawstr + slen, "-inf", sizeof(but->drawstr) - slen); } /* 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); + slen += BLI_strncpy_rlen(but->drawstr + slen, new_str, sizeof(but->drawstr) - slen); } else { const int prec = ui_but_float_precision(but, value); - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); + slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%.*f", prec, value); } } else { - BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%d", but->str, (int)value); + slen += BLI_snprintf(but->drawstr + slen, sizeof(but->drawstr) - slen, "%d", (int)value); } if (but->rnaprop) { PropertySubType pstype = RNA_property_subtype(but->rnaprop); - if (pstype == PROP_PERCENTAGE) - strcat(but->drawstr, "%"); + if (pstype == PROP_PERCENTAGE) { + drawstr_suffix = "%"; + } + } + + if (drawstr_suffix) { + BLI_strncpy(but->drawstr + slen, drawstr_suffix, sizeof(but->drawstr) - slen); } + } break; @@ -2604,7 +2617,7 @@ static void ui_block_do_align_but(uiBut *first, short nr) next = NULL; /* clear old flag */ - but->flag &= ~UI_BUT_ALIGN; + but->drawflag &= ~UI_BUT_ALIGN; if (flag == 0) { /* first case */ if (next) { @@ -2683,7 +2696,7 @@ static void ui_block_do_align_but(uiBut *first, short nr) } } - but->flag |= flag; + but->drawflag |= flag; /* merge coordinates */ if (prev) { @@ -2863,10 +2876,15 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, if ((block->flag & UI_BLOCK_LOOP) || ELEM8(but->type, MENU, TEX, LABEL, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR, SEARCH_MENU_UNLINK)) { - but->flag |= (UI_TEXT_LEFT | UI_ICON_LEFT); + but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT); + } +#ifdef USE_NUMBUTS_LR_ALIGN + else if (ELEM(but->type, NUM, NUMSLI)) { + but->drawflag |= UI_BUT_TEXT_LEFT; } +#endif - but->flag |= (block->flag & UI_BUT_ALIGN); + but->drawflag |= (block->flag & UI_BUT_ALIGN); if (but->lock == TRUE) { if (but->lockstr) { @@ -3041,7 +3059,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s if (icon) { but->icon = (BIFIconID)icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; } if (!RNA_property_editable(&but->rnapoin, prop)) { @@ -3110,45 +3128,6 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType * return but; } -#if 0 /* UNUSED */ -static uiBut *UNUSED_FUNCTION(ui_def_but_operator) (uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip) -{ - wmOperatorType *ot = WM_operatortype_find(opname, 0); - if (str == NULL && ot == NULL) str = opname; - return ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); -} -#endif - -static uiBut *ui_def_but_operator_text(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) -{ - uiBut *but; - wmOperatorType *ot; - - ot = WM_operatortype_find(opname, 0); - - if (!str) { - if (ot) str = ot->name; - else str = opname; - } - - if ((!tip || tip[0] == '\0') && ot && ot->description) { - tip = ot->description; - } - - but = ui_def_but(block, type, -1, str, x, y, width, height, poin, min, max, a1, a2, tip); - but->optype = ot; - but->opcontext = opcontext; - but->flag &= ~UI_BUT_UNDO; /* no need for ui_is_but_rna_undo(), we never need undo here */ - - if (!ot) { - but->flag |= UI_BUT_DISABLED; - but->lock = TRUE; - but->lockstr = ""; - } - - return but; -} - uiBut *uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) { uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); @@ -3340,13 +3319,6 @@ uiBut *uiDefButO(uiBlock *block, int type, const char *opname, int opcontext, co return uiDefButO_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); } -uiBut *uiDefButTextO(uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) -{ - uiBut *but = ui_def_but_operator_text(block, type, opname, opcontext, str, x, y, width, height, poin, min, max, a1, a2, tip); - ui_check_but(but); - return but; -} - /* if a1==1.0 then a2 is an extra icon blending factor (alpha 0.0 - 1.0) */ uiBut *uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) { @@ -3430,7 +3402,7 @@ uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const ch { uiBut *but = ui_def_but(block, type, retval, str, x, y, width, height, poin, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } static uiBut *uiDefIconTextButBit(uiBlock *block, int type, int bit, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip) @@ -3481,7 +3453,7 @@ uiBut *uiDefIconTextButR(uiBlock *block, int type, int retval, int icon, const c uiBut *but; but = ui_def_but_rna_propname(block, type, retval, str, x, y, width, height, ptr, propname, index, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) @@ -3489,7 +3461,7 @@ uiBut *uiDefIconTextButR_prop(uiBlock *block, int type, int retval, int icon, co uiBut *but; but = ui_def_but_rna(block, type, retval, str, x, y, width, height, ptr, prop, index, min, max, a1, a2, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) @@ -3497,7 +3469,7 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int o uiBut *but; but = ui_def_but_operator_ptr(block, type, ot, opcontext, str, x, y, width, height, tip); ui_check_but_and_iconize(but, icon); - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; return but; } uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip) @@ -3553,7 +3525,7 @@ void uiBlockFlipOrder(uiBlock *block) return; for (but = block->buttons.first; but; but = but->next) { - if (but->flag & UI_BUT_ALIGN) return; + if (but->drawflag & UI_BUT_ALIGN) return; if (but->rect.ymin < miny) miny = but->rect.ymin; if (but->rect.ymax > maxy) maxy = but->rect.ymax; } @@ -3794,7 +3766,7 @@ uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, in but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; but->flag |= UI_ICON_SUBMENU; but->menu_create_func = func; @@ -3809,7 +3781,7 @@ uiBut *uiDefIconMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int ic but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag &= ~UI_ICON_LEFT; + but->drawflag &= ~UI_BUT_ICON_LEFT; but->menu_create_func = func; ui_check_but(but); @@ -3825,7 +3797,7 @@ uiBut *uiDefIconTextBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, /* XXX temp, old menu calls pass on icon arrow, which is now UI_ICON_SUBMENU flag */ if (icon != ICON_RIGHTARROW_THIN) { but->icon = (BIFIconID) icon; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; } but->flag |= UI_HAS_ICON; but->flag |= UI_ICON_SUBMENU; @@ -3844,7 +3816,7 @@ uiBut *uiDefIconBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, int but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT; but->block_create_func = func; ui_check_but(but); @@ -3879,7 +3851,7 @@ uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxle but->icon = (BIFIconID) icon; but->flag |= UI_HAS_ICON; - but->flag |= UI_ICON_LEFT | UI_TEXT_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; ui_check_but(but); @@ -4016,7 +3988,7 @@ void uiButGetStrInfo(bContext *C, uiBut *but, ...) const char *tc1, *tc2; tc1 = strstr(but->str, "%t"); - tc2 = strstr(but->str, "|"); /* XXX For some reason strchr seems to not work here? */ + tc2 = strstr(but->str, UI_SEP_CHAR_S); if (tc2 && (!tc1 || tc1 > tc2)) tc1 = tc2; @@ -4192,6 +4164,11 @@ void UI_init_userdef(void) uiStyleInit(); } +void UI_init_userdef_factory(void) +{ + init_userdef_factory(); +} + void UI_reinit_font(void) { uiStyleInit(); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 11062ea2bd2..b6f93726bfc 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -395,7 +395,7 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad) /* ************** SPECIAL BUTTON DRAWING FUNCTIONS ************* */ -void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) +void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect) { #ifdef WITH_HEADLESS (void)rect; @@ -526,7 +526,7 @@ static void histogram_draw_one(float r, float g, float b, float alpha, #define HISTOGRAM_TOT_GRID_LINES 4 -void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { Histogram *hist = (Histogram *)but->poin; int res = hist->x_resolution; @@ -594,7 +594,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) #undef HISTOGRAM_TOT_GRID_LINES -void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { Scopes *scopes = (Scopes *)but->poin; rctf rect; @@ -825,7 +825,7 @@ static void vectorscope_draw_target(float centerx, float centery, float diam, co glEnd(); } -void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */ Scopes *scopes = (Scopes *)but->poin; @@ -912,7 +912,7 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco glDisable(GL_BLEND); } -void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) +void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *rect) { ColorBand *coba; CBData *cbd; @@ -1037,7 +1037,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) } -void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect) +void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, const rcti *rect) { static GLuint displist = 0; int a, old[8]; @@ -1130,7 +1130,7 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect) } } -static void ui_draw_but_curve_grid(rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step) +static void ui_draw_but_curve_grid(const rcti *rect, float zoomx, float zoomy, float offsx, float offsy, float step) { float dx, dy, fx, fy; @@ -1163,7 +1163,7 @@ static void gl_shaded_color(unsigned char *col, int shade) col[2] - shade > 0 ? col[2] - shade : 0); } -void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect) +void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, const rcti *rect) { CurveMapping *cumap; CurveMap *cuma; @@ -1362,7 +1362,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } -void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { rctf rect; int ok = 0, width, height; @@ -1488,7 +1488,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc glDisable(GL_BLEND); } -void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti) { static const float size = 5.0f; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 2b8b7643f39..61761d7db41 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -60,6 +60,7 @@ #include "BKE_context.h" #include "BKE_idprop.h" #include "BKE_report.h" +#include "BKE_screen.h" #include "BKE_texture.h" #include "BKE_tracking.h" #include "BKE_unit.h" @@ -173,6 +174,7 @@ typedef struct uiHandleButtonData { int draglastx, draglasty; int dragstartx, dragstarty; int draglastvalue; + int dragstartvalue; bool dragchange, draglock; int dragsel; float dragf, dragfstart; @@ -235,9 +237,15 @@ typedef struct uiAfterFunc { +static bool ui_is_but_interactive(uiBut *but, const bool labeledit); static bool ui_but_contains_pt(uiBut *but, int mx, int my); static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y); +static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, int x, int y, bool ctrl); +static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event); +static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state); +static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data, + const bool mousemove, const bool onfree); static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata); static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type); static void button_timers_tooltip_remove(bContext *C, uiBut *but); @@ -301,7 +309,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) static bool ui_but_editable(uiBut *but) { - return ELEM6(but->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR); + return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR); } static uiBut *ui_but_prev(uiBut *but) @@ -415,7 +423,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but) after->func_arg2 = but->func_arg2; after->funcN = but->funcN; - after->func_argN = MEM_dupallocN(but->func_argN); + after->func_argN = (but->func_argN) ? MEM_dupallocN(but->func_argN) : NULL; after->rename_func = but->rename_func; after->rename_arg1 = but->rename_arg1; @@ -715,7 +723,7 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set { /* popups such as layers won't re-evaluate on redraw */ const bool do_check = (ar->regiontype == RGN_TYPE_TEMPORARY); - bool change = false; + bool changed = false; uiBlock *block; for (block = ar->uiblocks.first; block; block = block->next) { @@ -728,7 +736,9 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set ui_window_to_block_fl(ar, block, &xy_b_block[0], &xy_b_block[1]); for (but = block->buttons.first; but; but = but->next) { - if (ui_is_but_interactive(but)) { + /* Note: ctrl is always true here because (at least for now) we always want to consider text control + * in this case, even when not embossed. */ + if (ui_is_but_interactive(but, true)) { if (BLI_rctf_isect_segment(&but->rect, xy_a_block, xy_b_block)) { /* execute the button */ @@ -741,7 +751,7 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set if (do_check) { ui_check_but(but); } - change = true; + changed = true; } } /* done */ @@ -751,7 +761,7 @@ static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set } } - return change; + return changed; } static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const int xy_input[2]) @@ -768,7 +778,7 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const */ if (drag_info->is_init == false) { /* first store the buttons original coords */ - uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]); + uiBut *but = ui_but_find_mouse_over_ex(ar, xy_input[0], xy_input[1], true); if (but) { if (but->flag & UI_BUT_DRAG_LOCK) { @@ -839,7 +849,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void if (done) { wmWindow *win = CTX_wm_window(C); ARegion *ar = CTX_wm_region(C); - uiBut *but = ui_but_find_mouse_over(ar, drag_info->xy_init[0], drag_info->xy_init[1]); + uiBut *but = ui_but_find_mouse_over_ex(ar, drag_info->xy_init[0], drag_info->xy_init[1], true); if (but) { ui_apply_undo(but); @@ -881,7 +891,7 @@ static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *eve if (but->imb) { /* use button size itself */ } - else if (but->flag & UI_ICON_LEFT) { + else if (but->drawflag & UI_BUT_ICON_LEFT) { rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } else { @@ -1541,13 +1551,22 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, char *str; opptr = uiButGetOperatorPtrRNA(but); /* allocated when needed, the button owns it */ - str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr); + str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr); WM_clipboard_text_set(str, 0); MEM_freeN(str); } } + /* menu (any type) */ + else if (ELEM(but->type, MENU, PULLDOWN)) { + MenuType *mt = uiButGetMenuType(but); + if (mt) { + char str[32 + sizeof(mt->idname)]; + BLI_snprintf(str, sizeof(str), "bpy.ops.wm.call_menu(name=\"%s\")", mt->idname); + WM_clipboard_text_set(str, 0); + } + } } /* ************************ password text ****************************** @@ -1596,7 +1615,7 @@ void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but } else { /* convert text to hidden test using asterisks (e.g. pass -> ****) */ - int i, len = BLI_strlen_utf8(but->drawstr); + const size_t len = BLI_strlen_utf8(but->drawstr); /* remap cursor positions */ if (but->pos >= 0) { @@ -1608,9 +1627,8 @@ void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but /* save original string */ BLI_strncpy(password_str, but->drawstr, UI_MAX_DRAW_STR); - for (i = 0; i < len; i++) - but->drawstr[i] = '*'; - but->drawstr[i] = '\0'; + memset(but->drawstr, '*', len); + but->drawstr[len] = '\0'; } } @@ -1622,14 +1640,14 @@ static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data) { char *str = data->str; const int len = strlen(str); - bool change = false; + bool changed = false; if (but->selsta != but->selend && len) { memmove(str + but->selsta, str + but->selend, (len - but->selend) + 1); - change = true; + changed = true; } but->pos = but->selend = but->selsta; - return change; + return changed; } /* note, but->block->aspect is used here, when drawing button style is getting scaled too */ @@ -1648,9 +1666,9 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con ui_button_text_password_hide(password_str, but, FALSE); origstr = MEM_mallocN(sizeof(char) * data->maxlen, "ui_textedit origstr"); - + BLI_strncpy(origstr, but->drawstr, data->maxlen); - + /* XXX solve generic, see: #widget_draw_text_icon */ if (but->type == NUM || but->type == NUMSLI) { startx += (int)(0.5f * (BLI_rctf_size_y(&but->rect))); @@ -1672,7 +1690,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con while (i > 0) { if (BLI_str_cursor_step_prev_utf8(origstr, but->ofs, &i)) { /* 0.25 == scale factor for less sensitivity */ - if (BLF_width(fstyle->uifont_id, origstr + i) > (startx - x) * 0.25f) { + if (BLF_width(fstyle->uifont_id, origstr + i, BLF_DRAW_STR_DUMMY_MAX) > (startx - x) * 0.25f) { break; } } @@ -1694,7 +1712,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con but->pos = pos_prev = strlen(origstr) - but->ofs; while (true) { - cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs); + cdist = startx + BLF_width(fstyle->uifont_id, origstr + but->ofs, BLF_DRAW_STR_DUMMY_MAX); /* check if position is found */ if (cdist < x) { @@ -1889,7 +1907,7 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi int step; BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true); step = pos - but->pos; - memmove(&str[but->pos], &str[but->pos + step], (len + 1) - but->pos); + memmove(&str[but->pos], &str[but->pos + step], (len + 1) - (but->pos + step)); changed = true; } } @@ -1914,22 +1932,22 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi return changed; } -static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) +static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) { char *str; - bool change = true; + int changed; str = data->str; if (data->searchbox) - change = ui_searchbox_autocomplete(C, data->searchbox, but, data->str); + changed = ui_searchbox_autocomplete(C, data->searchbox, but, data->str); else - change = but->autocomplete_func(C, str, but->autofunc_arg); + changed = but->autocomplete_func(C, str, but->autofunc_arg); but->pos = strlen(str); but->selsta = but->selend = but->pos; - return change; + return changed; } /* mode for ui_textedit_copypaste() */ @@ -2097,7 +2115,7 @@ static void ui_textedit_next_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX)) + if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return; for (but = actbut->next; but; but = but->next) { @@ -2125,7 +2143,7 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa uiBut *but; /* label and roundbox can overlap real buttons (backdrops...) */ - if (ELEM5(actbut->type, LABEL, LISTLABEL, SEPR, ROUNDBOX, LISTBOX)) + if (ELEM4(actbut->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return; for (but = actbut->prev; but; but = but->prev) { @@ -2324,7 +2342,12 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle case TABKEY: /* there is a key conflict here, we can't tab with autocomplete */ if (but->autocomplete_func || data->searchbox) { - changed = ui_textedit_autocomplete(C, but, data); + int autocomplete = ui_textedit_autocomplete(C, but, data); + changed = autocomplete != AUTOCOMPLETE_NO_MATCH; + + if (autocomplete == AUTOCOMPLETE_FULL_MATCH) + button_activate_state(C, but, BUTTON_STATE_EXIT); + update = true; /* do live update for tab key */ } /* the hotkey here is not well defined, was G.qual so we check all */ @@ -2572,6 +2595,26 @@ int ui_button_open_menu_direction(uiBut *but) return 0; } +/* Hack for uiList LISTROW buttons to "give" events to overlaying TEX buttons (cltr-clic rename feature & co). */ +static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event, + uiButtonActivateType activate_type) +{ + ARegion *ar = CTX_wm_region(C); + uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true); + + if (labelbut && labelbut->type == TEX) { + /* exit listrow */ + data->cancel = true; + button_activate_exit(C, but, data, false, false); + + /* Activate the text button. */ + button_activate_init(C, ar, labelbut, activate_type); + + return labelbut; + } + return NULL; +} + /* ***************** events for different button types *************** */ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) @@ -3518,22 +3561,45 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut return retval; } +static int ui_do_but_LISTROW(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +{ + if (data->state == BUTTON_STATE_HIGHLIGHT) { + /* hack to pass on ctrl+click and double click to overlapping text + * editing field for editing list item names + */ + if ((ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS && event->ctrl) || + (event->type == LEFTMOUSE && event->val == KM_DBL_CLICK)) + { + uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_TEXT_EDITING); + if (labelbut) { + /* Nothing else to do. */ + return WM_UI_HANDLER_BREAK; + } + } + } + + return ui_do_but_EXIT(C, but, data, event); +} + + static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { uiList *ui_list = but->custom_data; int *size = (int *)but->poin; - int mx, my, raw_dir_sign; + int mx, my, dragx, dragy; int retval = WM_UI_HANDLER_CONTINUE; - mx = event->x; - my = event->y; - - /* We find the direction of the mouse since last time, before converting coordinates into block's space. - * We'll use it to avoid flickering in case some rows are higher than UI_UNIT_Y. + /* Note: Having to store org point in window space and recompute it to block "space" each time + * is not ideal, but this is a way to hack around behavior of ui_window_to_block(), which + * returns different results when the block is inside a panel or not... + * See T37739. */ - raw_dir_sign = (data->draglasty - my < 0) ? -1 : 1; - data->draglasty = my; + dragx = data->dragstartx; + dragy = data->dragstarty; + ui_window_to_block(data->region, block, &dragx, &dragy); + mx = event->x; + my = event->y; ui_window_to_block(data->region, block, &mx, &my); if (data->state == BUTTON_STATE_NUM_EDITING) { @@ -3559,52 +3625,40 @@ static int ui_do_but_LISTBOX(bContext *C, uiBlock *block, uiBut *but, uiHandleBu if (data->draglastvalue > 0 && *size == 0) { data->draglastvalue = *size; data->dragstartx = data->dragstarty; /* draglasty already used... */ - data->dragstarty = my; + data->dragstarty = event->y; } else { - int delta = data->dragstarty - my; - /* We only actually do something if the real mousemouve direction matches the "virtual" - * mousemove direction in current block's space. This avoids flickering when drag-resizing lists with - * items drawing higher that UI_UNIT_Y. - */ - if (delta * raw_dir_sign > 0) { - /* Number of rows to show/hide, UI_UNIT_Y should work nice in most cases. */ - delta = (int)floorf(((float)delta / (float)UI_UNIT_Y) + 0.5f); - - /* If we are not in autosize mode, default behavior... */ - if (*size > 0 && delta != 0) { - /* This prevents some instability in case some items draw more/less than UI_UNIT_Y height. */ - delta = (delta < -5) ? -5 : (delta > 5) ? 5 : delta; - /* We can't use ui_numedit_apply()... */ - /* list template will clamp, but we do not want to reach 0 aka autosize mode! */ - *size = max_ii(*size + delta, 1); - - /* Used to detect switch to/from autosize mode. */ - data->draglastvalue = *size; - - data->dragchange = true; - data->applied = data->applied_interactive = true; - - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; - ED_region_tag_redraw(data->region); - } - /* If we are leaving autosize mode (growing dragging), restore to minimal size. */ - else if (delta > 0) { - /* We can't use ui_numedit_apply()... */ - *size = ui_list->dyn_data->visual_height_min; + int newsize = *size; + int diff = dragy - my; - /* Restore real dragstarty value! */ - data->dragstarty = data->dragstartx; + diff = (int)floorf(((float)diff / (float)UI_UNIT_Y) + 0.5f); - /* Used to detect switch to/from autosize mode. */ - data->draglastvalue = *size; + /* If we are not in autosize mode, default behavior... */ + if (*size > 0) { + /* list template will clamp, but we do not want to reach 0 aka autosize mode! */ + newsize = data->dragstartvalue + diff; + } + /* If we are leaving autosize mode (growing dragging), restore to minimal size. */ + else if (diff > 0) { + /* We can't use ui_numedit_apply()... */ + newsize = ui_list->dyn_data->visual_height_min; - data->dragchange = true; - data->applied = data->applied_interactive = true; + /* Restore real dragstarty value! */ + data->dragstarty = data->dragstartx; + } - ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; - ED_region_tag_redraw(data->region); - } + /* Used to detect switch to/from autosize mode. */ + data->draglastvalue = newsize; + + if (newsize != *size) { + *size = newsize; + + /* We can't use ui_numedit_apply()... */ + data->dragchange = true; + data->applied = data->applied_interactive = true; + + ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; + ED_region_tag_redraw(data->region); } } } @@ -5536,7 +5590,15 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * if ((data->state == BUTTON_STATE_HIGHLIGHT) || (event->type == EVT_DROP)) { /* handle copy-paste */ if (ELEM(event->type, CKEY, VKEY) && event->val == KM_PRESS && (event->ctrl || event->oskey)) { - + /* Specific handling for listrows, we try to find their overlapping tex button. */ + if (but->type == LISTROW) { + uiBut *labelbut = ui_but_list_row_text_activate(C, but, data, event, BUTTON_ACTIVATE_OVER); + if (labelbut) { + but = labelbut; + data = but->active; + } + } + ui_but_copy_paste(C, but, data, (event->type == CKEY) ? 'c' : 'v'); return WM_UI_HANDLER_BREAK; } @@ -5673,11 +5735,12 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * case LISTBOX: retval = ui_do_but_LISTBOX(C, block, but, data, event); break; + case LISTROW: + retval = ui_do_but_LISTROW(C, but, data, event); + break; case ROUNDBOX: case LABEL: - case LISTLABEL: case ROW: - case LISTROW: case BUT_IMAGE: case PROGRESSBAR: case NODESOCKET: @@ -5745,7 +5808,8 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* reset to default (generic function, only use if not handled by switch above) */ /* XXX hardcoded keymap check.... */ - if (data->state == BUTTON_STATE_HIGHLIGHT) { + data = but->active; + if (data && data->state == BUTTON_STATE_HIGHLIGHT) { if ((retval == WM_UI_HANDLER_CONTINUE) && (event->type == BACKSPACEKEY && event->val == KM_PRESS)) { @@ -5884,11 +5948,12 @@ static bool ui_mouse_inside_button(ARegion *ar, uiBut *but, int x, int y) /** * Can we mouse over the button or is it hidden/disabled/layout. + * Note: ctrl is kind of a hack currently, so that non-embossed TEX button behaves as a label when ctrl is not pressed. */ -bool ui_is_but_interactive(uiBut *but) +static bool ui_is_but_interactive(uiBut *but, const bool labeledit) { /* note, LABEL is included for highlights, this allows drags */ - if (ELEM(but->type, LABEL, LISTLABEL) && but->dragpoin == NULL) + if ((but->type == LABEL) && but->dragpoin == NULL) return false; if (ELEM3(but->type, ROUNDBOX, SEPR, LISTBOX)) return false; @@ -5896,6 +5961,10 @@ bool ui_is_but_interactive(uiBut *but) return false; if (but->flag & UI_SCROLLED) return false; + if ((but->type == TEX) && (but->dt & UI_EMBOSSN) && !labeledit) + return false; + if ((but->type == LISTROW) && labeledit) + return false; return true; } @@ -5907,7 +5976,8 @@ bool ui_is_but_search_unlink_visible(uiBut *but) (but->drawstr[0] != '\0')); } -uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) +/* x and y are only used in case event is NULL... */ +static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit) { uiBlock *block; uiBut *but, *butover = NULL; @@ -5924,7 +5994,7 @@ uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) ui_window_to_block(ar, block, &mx, &my); for (but = block->buttons.first; but; but = but->next) { - if (ui_is_but_interactive(but)) { + if (ui_is_but_interactive(but, labeledit)) { if (ui_but_contains_pt(but, mx, my)) { butover = but; } @@ -5943,6 +6013,12 @@ uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y) return butover; } +static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event) +{ + return ui_but_find_mouse_over_ex(ar, event->x, event->y, event->ctrl != 0); +} + + static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) { uiBlock *block; @@ -6494,7 +6570,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar) uiBut *but; if (event->type == MOUSEMOVE) { - but = ui_but_find_mouse_over(ar, event->x, event->y); + but = ui_but_find_mouse_over(ar, event); if (but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); } @@ -6586,7 +6662,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) data->cancel = TRUE; button_activate_state(C, but, BUTTON_STATE_EXIT); } - else if (ui_but_find_mouse_over(ar, event->x, event->y) != but) { + else if (ui_but_find_mouse_over(ar, event) != but) { data->cancel = TRUE; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -6641,9 +6717,10 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) case MOUSEMOVE: if (ELEM(but->type, LINK, INLINK)) { + ARegion *ar = data->region; but->flag |= UI_SELECT; ui_do_button(C, block, but, event); - ED_region_tag_redraw(data->region); + ED_region_tag_redraw(ar); } else { /* deselect the button when moving the mouse away */ @@ -6698,7 +6775,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) } } - bt = ui_but_find_mouse_over(ar, event->x, event->y); + bt = ui_but_find_mouse_over(ar, event); if (bt && bt->active != data) { if (but->type != COLOR) { /* exception */ @@ -6720,7 +6797,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) /* may have been re-allocated above (eyedropper for eg) */ data = but->active; - if (data->state == BUTTON_STATE_EXIT) { + if (data && data->state == BUTTON_STATE_EXIT) { uiBut *post_but = data->postbut; uiButtonActivateType post_type = data->posttype; @@ -6738,7 +6815,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) * it stays active while the mouse is over it. * This avoids adding mousemoves, see: [#33466] */ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) { - if (ui_but_find_mouse_over(ar, event->x, event->y) == but) { + if (ui_but_find_mouse_over(ar, event) == but) { button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER); } } @@ -6779,7 +6856,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) break; } } - if (dragbut && dragbut == ui_but_find_mouse_over(ar, event->x, event->y)) { + if (dragbut && dragbut == ui_but_find_mouse_over(ar, event)) { is_over_dragbut = true; } @@ -6791,12 +6868,13 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) button_activate_state(C, but, BUTTON_STATE_INIT); data = but->active; - data->dragstarty = my; + data->dragstarty = event->y; button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); /* Again, have to override values set by ui_numedit_begin, because our listbox button also has a rnapoin... */ *size = data->origvalue = (double)dyn_data->visual_height; + data->dragstartvalue = *size; ui_list->flag |= UILST_RESIZING; retval = WM_UI_HANDLER_BREAK; @@ -7444,7 +7522,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH for (but = block->buttons.first; but; but = but->next) { int doit = FALSE; - if (but->type != LABEL && but->type != LISTLABEL && but->type != SEPR) + if (!ELEM(but->type, LABEL, SEPR)) count++; /* exception for rna layer buts */ @@ -7775,7 +7853,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use /* either handle events for already activated button or try to activate */ but = ui_but_find_activated(ar); - retval = ui_handler_panel_region(C, event); + retval = ui_handler_panel_region(C, event, ar); if (retval == WM_UI_HANDLER_CONTINUE) retval = ui_handle_list_event(C, event, ar); @@ -7961,8 +8039,8 @@ void UI_remove_popup_handlers_all(bContext *C, ListBase *handlers) WM_event_free_ui_handler_all(C, handlers, ui_handler_popup, ui_handler_remove_popup); } -bool UI_textbutton_activate_event(const bContext *C, ARegion *ar, - const void *rna_poin_data, const char *rna_prop_id) +bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar, + const void *rna_poin_data, const char *rna_prop_id) { uiBlock *block; uiBut *but = NULL; @@ -7990,6 +8068,31 @@ bool UI_textbutton_activate_event(const bContext *C, ARegion *ar, } } +bool UI_textbutton_activate_but(const bContext *C, uiBut *actbut) +{ + ARegion *ar = CTX_wm_region(C); + uiBlock *block; + uiBut *but = NULL; + + for (block = ar->uiblocks.first; block; block = block->next) { + for (but = block->buttons.first; but; but = but->next) + if (but == actbut && but->type == TEX) + break; + + if (but) + break; + } + + if (but) { + uiButActiveOnly(C, ar, block, but); + return true; + } + else { + return false; + } +} + + void ui_button_clipboard_free(void) { curvemapping_free_data(&but_copypaste_curve); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 5ecd1e55086..cbc1cd2cbbd 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -54,6 +54,9 @@ struct ImBuf; /* ****************** general defines ************** */ +#define RNA_NO_INDEX -1 +#define RNA_ENUM_VALUE -2 + /* visual types for drawing */ /* for time being separated from functional types */ typedef enum { @@ -95,7 +98,6 @@ typedef enum { UI_WTYPE_SCROLL, UI_WTYPE_LISTITEM, UI_WTYPE_PROGRESSBAR, - UI_WTYPE_LISTLABEL, } uiWidgetTypeEnum; /* menu scrolling */ @@ -108,13 +110,15 @@ typedef enum { #define UI_PANEL_MINY 70 /* uiBut->flag */ -#define UI_SELECT 1 /* use when the button is pressed */ -#define UI_SCROLLED 2 /* temp hidden, scrolled away */ -#define UI_ACTIVE 4 -#define UI_HAS_ICON 8 -#define UI_TEXTINPUT 16 -#define UI_HIDDEN 32 -/* warn: rest of uiBut->flag in UI_interface.h */ +enum { + UI_SELECT = (1 << 0), /* use when the button is pressed */ + UI_SCROLLED = (1 << 1), /* temp hidden, scrolled away */ + UI_ACTIVE = (1 << 2), + UI_HAS_ICON = (1 << 3), + UI_TEXTINPUT = (1 << 4), + UI_HIDDEN = (1 << 5), + /* warn: rest of uiBut->flag in UI_interface.h */ +}; /* internal panel drawing defines */ #define PNL_GRID (UI_UNIT_Y / 5) /* 4 default */ @@ -144,6 +148,9 @@ typedef enum { /* bit-row */ #define UI_BITBUT_ROW(min, max) (((max) >= 31 ? 0xFFFFFFFF : (1 << (max + 1)) - 1) - ((min) ? ((1 << (min)) - 1) : 0) ) +/* split numbuts by ':' and align l/r */ +#define USE_NUMBUTS_LR_ALIGN + typedef struct uiLinkLine { /* only for draw/edit */ struct uiLinkLine *next, *prev; struct uiBut *from, *to; @@ -402,7 +409,6 @@ extern bool ui_is_but_bool(uiBut *but); extern bool ui_is_but_unit(uiBut *but); extern bool ui_is_but_rna_valid(uiBut *but); extern bool ui_is_but_utf8(uiBut *but); -extern bool ui_is_but_interactive(uiBut *but); extern bool ui_is_but_search_unlink_visible(uiBut *but); extern int ui_is_but_push_ex(uiBut *but, double *value); @@ -476,7 +482,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu bool ui_searchbox_inside(struct ARegion *ar, int x, int y); int ui_searchbox_find_index(struct ARegion *ar, const char *name); void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset); -bool ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); +int ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *ar); void ui_searchbox_free(struct bContext *C, struct ARegion *ar); @@ -498,23 +504,23 @@ int ui_step_name_menu(uiBut *but, int step); struct AutoComplete; /* interface_panel.c */ -extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event); -extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, rcti *rect); +extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event, struct ARegion *ar); +extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, const rcti *rect); /* interface_draw.c */ extern void ui_dropshadow(const rctf *rct, float radius, float aspect, float alpha, int select); void ui_draw_gradient(const rcti *rect, const float hsv[3], const int type, const float alpha); -void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); -void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); +void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); +void ui_draw_but_NODESOCKET(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, const rcti *rect); /* interface_handlers.c */ extern void ui_pan_to_scroll(const struct wmEvent *event, int *type, int *val); @@ -559,6 +565,7 @@ int ui_id_icon_get(struct bContext *C, struct ID *id, const bool big); /* resources.c */ void init_userdef_do_versions(void); +void init_userdef_factory(void); void ui_theme_init_default(void); void ui_style_init_default(void); void ui_resources_init(void); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 0f6034ba1cd..85068998d9c 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -64,10 +64,6 @@ /************************ Structs and Defines *************************/ -#define RNA_NO_INDEX -1 -#define RNA_ENUM_VALUE -2 - - // #define USE_OP_RESET_BUT // we may want to make this optional, disable for now. #define UI_OPERATOR_ERROR_RET(_ot, _opname, return_statement) \ @@ -390,11 +386,15 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, const char *name, in layer_used = arm->layer_used; - if (arm->edbo && arm->act_edbone) { - layer_active |= arm->act_edbone->layer; + if (arm->edbo) { + if (arm->act_edbone) { + layer_active |= arm->act_edbone->layer; + } } - else if (arm->act_bone) { - layer_active |= arm->act_bone->layer; + else { + if (arm->act_bone) { + layer_active |= arm->act_bone->layer; + } } } @@ -580,7 +580,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt } if (ui_layout_local_dir(layout) != UI_LAYOUT_HORIZONTAL) - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } uiBlockSetCurLayout(block, layout); @@ -628,13 +628,11 @@ static uiBut *ui_item_with_label(uiLayout *layout, uiBlock *block, const char *n if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) { uiBlockSetCurLayout(block, uiLayoutRow(sub, TRUE)); - uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h); + but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, w - UI_UNIT_X, h); /* BUTTONS_OT_file_browse calls uiFileBrowseContextProperty */ - but = uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? - "BUTTONS_OT_directory_browse" : - "BUTTONS_OT_file_browse", - WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); + uiDefIconButO(block, BUT, subtype == PROP_DIRPATH ? "BUTTONS_OT_directory_browse" : "BUTTONS_OT_file_browse", + WM_OP_INVOKE_DEFAULT, ICON_FILESEL, x, y, UI_UNIT_X, h, NULL); } else if (flag & UI_ITEM_R_EVENT) { uiDefButR_prop(block, KEYEVT, 0, name, x, y, w, h, ptr, prop, index, 0, 0, -1, -1, NULL); @@ -762,7 +760,7 @@ PointerRNA uiItemFullO_ptr(uiLayout *layout, wmOperatorType *ot, const char *nam /* text alignment for toolbar buttons */ if ((layout->root->type == UI_LAYOUT_TOOLBAR) && !icon) - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; if (flag & UI_ITEM_R_NO_BG) uiBlockSetEmboss(block, UI_EMBOSS); @@ -910,9 +908,15 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname block->flag |= UI_BLOCK_NO_FLIP; } - uiItemL(column, item->name, ICON_NONE); - but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + if (item->icon) { + uiItemL(column, item->name, item->icon); + but = block->buttons.last; + } + else { + /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ + but = uiDefBut(block, LABEL, 0, item->name, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, + 0.0, 0.0, 0, 0, ""); + } ui_but_tip_from_enum_item(but, item); } else { /* XXX bug here, colums draw bottom item badly */ @@ -1138,7 +1142,7 @@ static void ui_item_rna_size(uiLayout *layout, const char *name, int icon, Point void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index, int value, int flag, const char *name, int icon) { uiBlock *block = layout->root->block; - uiBut *but; + uiBut *but = NULL; PropertyType type; char namestr[UI_MAX_NAME_STR]; int len, is_array, w, h, slider, toggle, expand, icon_only, no_bg; @@ -1227,7 +1231,12 @@ void uiItemFullR(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, int index if (layout->redalert) uiButSetFlag(but, UI_BUT_REDALERT); } - + + /* Mark non-embossed textfields inside a listbox. */ + if (but && (block->flag & UI_BLOCK_LIST_ITEM) && (but->type == TEX) && (but->dt & UI_EMBOSSN)) { + uiButSetFlag(but, UI_BUT_LIST_ITEM); + } + if (no_bg) uiBlockSetEmboss(block, UI_EMBOSS); } @@ -1336,7 +1345,7 @@ void uiItemsEnumR(uiLayout *layout, struct PointerRNA *ptr, const char *propname uiItemL(column, item[i].name, ICON_NONE); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; ui_but_tip_from_enum_item(bt, &item[i]); } @@ -1486,7 +1495,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN but->hardmax = MAX2(but->hardmax, 256.0f); but->rnasearchpoin = *searchptr; but->rnasearchprop = searchprop; - but->flag |= UI_ICON_LEFT | UI_TEXT_LEFT; + but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT; if (RNA_property_type(prop) == PROP_ENUM) { /* XXX, this will have a menu string, @@ -1629,7 +1638,7 @@ static void ui_item_menu(uiLayout *layout, const char *name, int icon, uiMenuCre (force_menu && layout->root->type != UI_LAYOUT_MENU)) /* We never want a dropdown in menu! */ { but->type = MENU; - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } } @@ -1681,13 +1690,13 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon) * make text aligned right if the layout is aligned right. */ if (uiLayoutGetAlignment(layout) == UI_LAYOUT_ALIGN_RIGHT) { - but->flag &= ~UI_TEXT_LEFT; /* default, needs to be unset */ - but->flag |= UI_TEXT_RIGHT; + but->drawflag &= ~UI_BUT_TEXT_LEFT; /* default, needs to be unset */ + but->drawflag |= UI_BUT_TEXT_RIGHT; } /* Mark as a label inside a listbox. */ if (block->flag & UI_BLOCK_LIST_ITEM) { - but->type = LISTLABEL; + but->flag |= UI_BUT_LIST_ITEM; } return but; @@ -1872,7 +1881,7 @@ static int ui_litem_min_width(int itemw) static void ui_litem_layout_row(uiLayout *litem) { uiItem *item; - int x, y, w, tot, totw, neww, itemw, minw, itemh, offset; + int x, y, w, tot, totw, neww, newtotw, itemw, minw, itemh, offset; int fixedw, freew, fixedx, freex, flag = 0, lastw = 0; /* x = litem->x; */ /* UNUSED */ @@ -1899,6 +1908,7 @@ static void ui_litem_layout_row(uiLayout *litem) freew = 0; x = 0; flag = 0; + newtotw = totw; for (item = litem->items.first; item; item = item->next) { if (item->flag) @@ -1919,7 +1929,7 @@ static void ui_litem_layout_row(uiLayout *litem) item->flag = 1; fixedw += minw; flag = 1; - totw -= itemw; + newtotw -= itemw; } else { /* keep free size */ @@ -1928,6 +1938,7 @@ static void ui_litem_layout_row(uiLayout *litem) } } + totw = newtotw; lastw = fixedw; } while (flag); @@ -2448,8 +2459,9 @@ uiLayout *uiLayoutBox(uiLayout *layout) return (uiLayout *)ui_layout_box(layout, ROUNDBOX); } -/* Check all buttons defined in this layout, and set labels as active/selected. - * Needed to handle correctly text colors of list items. */ +/* Check all buttons defined in this layout, and set any button flagged as UI_BUT_LIST_ITEM as active/selected. + * Needed to handle correctly text colors of active (selected) list item. + */ void ui_layout_list_set_labels_active(uiLayout *layout) { uiButtonItem *bitem; @@ -2457,7 +2469,7 @@ void ui_layout_list_set_labels_active(uiLayout *layout) if (bitem->item.type != ITEM_BUTTON) { ui_layout_list_set_labels_active((uiLayout *)(&bitem->item)); } - else if (bitem->but->type == LISTLABEL) { + else if (bitem->but->flag & UI_BUT_LIST_ITEM) { uiButSetFlag(bitem->but, UI_SELECT); } } @@ -2965,7 +2977,7 @@ static void ui_intro_button(DynStr *ds, uiButtonItem *bitem) BLI_dynstr_appendf(ds, "'tip':'''%s''', ", but->tip ? but->tip : ""); /* not exactly needed, rna has this */ if (but->optype) { - char *opstr = WM_operator_pystring_ex(but->block->evil_C, NULL, false, but->optype, but->opptr); + char *opstr = WM_operator_pystring_ex(but->block->evil_C, NULL, false, true, but->optype, but->opptr); BLI_dynstr_appendf(ds, "'operator':'''%s''', ", opstr ? opstr : ""); MEM_freeN(opstr); } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 3fe11ad3a6b..9759614dd4c 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -413,7 +413,7 @@ static void ui_draw_x_icon(float x, float y) #define PNL_ICON UI_UNIT_X /* could be UI_UNIT_Y too */ -static void ui_draw_panel_scalewidget(rcti *rect) +static void ui_draw_panel_scalewidget(const rcti *rect) { float xmin, xmax, dx; float ymin, ymax, dy; @@ -464,7 +464,7 @@ static void ui_draw_panel_dragwidget(const rctf *rect) } -static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, rcti *rect, char dir) +static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, const rcti *rect, char dir) { Panel *panel = block->panel; rcti hrect; @@ -496,21 +496,8 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, rcti *r } } -static void rectf_scale(rctf *rect, const float scale) -{ - float centx = BLI_rctf_cent_x(rect); - float centy = BLI_rctf_cent_y(rect); - float sizex = BLI_rctf_size_x(rect) * 0.5f * scale; - float sizey = BLI_rctf_size_y(rect) * 0.5f * scale; - - rect->xmin = centx - sizex; - rect->xmax = centx + sizex; - rect->ymin = centy - sizey; - rect->ymax = centy + sizey; -} - /* panel integrated in buttonswindow, tool/property lists etc */ -void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) +void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect) { Panel *panel = block->panel; rcti headrect; @@ -565,7 +552,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) itemrect.ymin = headrect.ymin; itemrect.ymax = headrect.ymax; - rectf_scale(&itemrect, 0.7f); + BLI_rctf_scale(&itemrect, 0.7f); ui_draw_panel_dragwidget(&itemrect); } @@ -619,7 +606,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, rcti *rect) itemrect.ymin = headrect.ymin; itemrect.ymax = headrect.ymax; - rectf_scale(&itemrect, 0.35f); + BLI_rctf_scale(&itemrect, 0.35f); if (panel->flag & PNL_CLOSEDY) ui_draw_tria_rect(&itemrect, 'h'); @@ -1133,16 +1120,15 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in /* XXX should become modal keymap */ /* AKey is opening/closing panels, independent of button state now */ -int ui_handler_panel_region(bContext *C, const wmEvent *event) +int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar) { - ARegion *ar = CTX_wm_region(C); uiBlock *block; Panel *pa; int retval, mx, my; retval = WM_UI_HANDLER_CONTINUE; for (block = ar->uiblocks.last; block; block = block->prev) { - int inside = 0, inside_header = 0, inside_scale = 0; + bool inside = false, inside_header = false, inside_scale = false; mx = event->x; my = event->y; @@ -1159,24 +1145,24 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event) /* clicked at panel header? */ if (pa->flag & PNL_CLOSEDX) { if (block->rect.xmin <= mx && block->rect.xmin + PNL_HEADER >= mx) - inside_header = 1; + inside_header = true; } else if (block->rect.xmin > mx || block->rect.xmax < mx) { /* outside left/right side */ } else if ((block->rect.ymax <= my) && (block->rect.ymax + PNL_HEADER >= my)) { - inside_header = 1; + inside_header = true; } else if (!(pa->flag & PNL_CLOSEDY)) { /* open panel */ if (pa->control & UI_PNL_SCALE) { if (block->rect.xmax - PNL_HEADER <= mx) if (block->rect.ymin + PNL_HEADER >= my) - inside_scale = 1; + inside_scale = true; } if (block->rect.xmin <= mx && block->rect.xmax >= mx) if (block->rect.ymin <= my && block->rect.ymax + PNL_HEADER >= my) - inside = 1; + inside = true; } /* XXX hardcoded key warning */ diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 1de0a278b56..167c627c32d 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -443,7 +443,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; - if (but->flag & UI_BUT_NO_TOOLTIP) + if (but->drawflag & UI_BUT_NO_TOOLTIP) return NULL; /* create tooltip data */ @@ -539,7 +539,10 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* so the context is passed to itemf functions (some py itemf functions use it) */ WM_operator_properties_sanitize(opptr, false); - str = WM_operator_pystring_ex(C, NULL, false, but->optype, opptr); + str = WM_operator_pystring_ex(C, NULL, false, false, but->optype, opptr); + + /* avoid overly verbose tips (eg, arrays of 20 layers), exact limit is arbitrary */ + WM_operator_pystring_abbreviate(str, 32); /* operator info */ if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) { @@ -660,7 +663,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) h = BLF_height_max(data->fstyle.uifont_id); for (a = 0, fontw = 0, fonth = 0; a < data->totline; a++) { - w = BLF_width(data->fstyle.uifont_id, data->lines[a]); + w = BLF_width(data->fstyle.uifont_id, data->lines[a], sizeof(data->lines[a])); fontw = max_ff(fontw, (float)w); fonth += (a == 0) ? h : h + TIP_MARGIN_Y; } @@ -873,7 +876,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) ED_region_tag_redraw(ar); } -static void ui_searchbox_butrect(rcti *rect, uiSearchboxData *data, int itemnr) +static void ui_searchbox_butrect(rcti *r_rect, uiSearchboxData *data, int itemnr) { /* thumbnail preview */ if (data->preview) { @@ -881,27 +884,27 @@ static void ui_searchbox_butrect(rcti *rect, uiSearchboxData *data, int itemnr) int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_TOP) / data->prv_rows; int row, col; - *rect = data->bbox; + *r_rect = data->bbox; col = itemnr % data->prv_cols; row = itemnr / data->prv_cols; - rect->xmin += col * butw; - rect->xmax = rect->xmin + butw; + r_rect->xmin += col * butw; + r_rect->xmax = r_rect->xmin + butw; - rect->ymax = data->bbox.ymax - MENU_TOP - (row * buth); - rect->ymin = rect->ymax - buth; + r_rect->ymax = data->bbox.ymax - MENU_TOP - (row * buth); + r_rect->ymin = r_rect->ymax - buth; } /* list view */ else { int buth = (BLI_rcti_size_y(&data->bbox) - 2 * MENU_TOP) / SEARCH_ITEMS; - *rect = data->bbox; - rect->xmin = data->bbox.xmin + 3.0f; - rect->xmax = data->bbox.xmax - 3.0f; + *r_rect = data->bbox; + r_rect->xmin = data->bbox.xmin + 3.0f; + r_rect->xmax = data->bbox.xmax - 3.0f; - rect->ymax = data->bbox.ymax - MENU_TOP - itemnr * buth; - rect->ymin = rect->ymax - buth; + r_rect->ymax = data->bbox.ymax - MENU_TOP - itemnr * buth; + r_rect->ymin = r_rect->ymax - buth; } } @@ -1051,7 +1054,7 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) ED_region_tag_redraw(ar); } -bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) +int ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) { uiSearchboxData *data = ar->regiondata; int match = AUTOCOMPLETE_NO_MATCH; @@ -1064,7 +1067,8 @@ bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) match = autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; } - return match != AUTOCOMPLETE_NO_MATCH; + + return match; } static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) @@ -1389,9 +1393,9 @@ static void ui_block_position(wmWindow *window, ARegion *butregion, uiBut *but, /* widget_roundbox_set has this correction too, keep in sync */ if (but->type != PULLDOWN) { - if (but->flag & UI_BUT_ALIGN_TOP) + if (but->drawflag & UI_BUT_ALIGN_TOP) butrct.ymax += U.pixelsize; - if (but->flag & UI_BUT_ALIGN_LEFT) + if (but->drawflag & UI_BUT_ALIGN_LEFT) butrct.xmin -= U.pixelsize; } @@ -1791,7 +1795,6 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a uiBlock *block = uiLayoutGetBlock(layout); uiPopupBlockHandle *handle = block->handle; uiLayout *split, *column = NULL; - uiBut *bt; MenuData *md; MenuEntry *entry; const char *instr = arg_str; @@ -1800,7 +1803,7 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a int nbr_entries_nosepr = 0; uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); - + /* compute menu data */ md = decompose_menu_string(instr); @@ -1838,9 +1841,8 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a uiItemL(layout, md->title, md->titleicon); } else { - uiItemL(layout, md->title, ICON_NONE); - bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ + uiDefBut(block, LABEL, 0, md->title, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); } } @@ -1874,9 +1876,13 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a if (entry->sepr) { if (entry->str[0]) { - uiItemL(column, entry->str, entry->icon); - bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + if (entry->icon) { + uiItemL(column, entry->str, entry->icon); + } + else { + /* Do not use uiItemL here, as our root layout is a menu one, it will add a fake blank icon! */ + uiDefBut(block, LABEL, 0, entry->str, 0, 0, UI_UNIT_X * 5, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + } } else { uiItemS(column); @@ -1891,7 +1897,7 @@ static void ui_block_func_MENUSTR(bContext *UNUSED(C), uiLayout *layout, void *a UI_UNIT_X * 5, UI_UNIT_X, &handle->retvalue, (float) entry->retval, 0.0, 0, -1, ""); } } - + menudata_free(md); } @@ -2191,11 +2197,11 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper /* RGB values */ uiBlockBeginAlign(block); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R "), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("R:"), 0, yco, butwidth, UI_UNIT_Y, ptr, prop, 0, 0.0, 0.0, 0, 3, TIP_("Red")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("G:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 1, 0.0, 0.0, 0, 3, TIP_("Green")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); - bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B "), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); + bt = uiDefButR_prop(block, NUMSLI, 0, IFACE_("B:"), 0, yco -= UI_UNIT_Y, butwidth, UI_UNIT_Y, ptr, prop, 2, 0.0, 0.0, 0, 3, TIP_("Blue")); uiButSetFunc(bt, do_picker_rna_cb, bt, NULL); /* could use uiItemFullR(col, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER, "", ICON_NONE); @@ -2204,11 +2210,11 @@ static void uiBlockPicker(uiBlock *block, float rgba[4], PointerRNA *ptr, Proper /* HSV values */ yco = -3.0f * UI_UNIT_Y; uiBlockBeginAlign(block); - bt = uiDefButF(block, NUMSLI, 0, IFACE_("H "), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); + bt = uiDefButF(block, NUMSLI, 0, IFACE_("H:"), 0, yco, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, TIP_("Hue")); 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")); + 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, softmax, 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); @@ -2560,7 +2566,7 @@ uiPopupMenu *uiPupMenuBegin(bContext *C, const char *title, int icon) } else { but = uiDefBut(pup->block, LABEL, 0, title, 0, 0, 200, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; } } diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 1c6263c9dd5..f9595edf616 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -144,7 +144,7 @@ static uiFont *uifont_to_blfont(int id) void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, - float *r_xofs, float *r_yofs) + size_t len, float *r_xofs, float *r_yofs) { float height; int xofs = 0, yofs; @@ -155,14 +155,14 @@ void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, yofs = ceil(0.5f * (BLI_rcti_size_y(rect) - height)); if (fs->align == UI_STYLE_TEXT_CENTER) { - xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str))); + xofs = floor(0.5f * (BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len))); /* don't center text if it chops off the start of the text, 2 gives some margin */ if (xofs < 2) { xofs = 2; } } else if (fs->align == UI_STYLE_TEXT_RIGHT) { - xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str) - 0.1f * U.widget_unit; + xofs = BLI_rcti_size_x(rect) - BLF_width(fs->uifont_id, str, len) - 0.1f * U.widget_unit; } /* clip is very strict, so we give it some space */ @@ -179,7 +179,7 @@ void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, if (fs->kerning == 1) BLF_enable(fs->uifont_id, BLF_KERNING_DEFAULT); - BLF_draw(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); + BLF_draw(fs->uifont_id, str, len); BLF_disable(fs->uifont_id, BLF_CLIPPING); if (fs->shadow) BLF_disable(fs->uifont_id, BLF_SHADOW); @@ -190,15 +190,15 @@ void uiStyleFontDrawExt(uiFontStyle *fs, const rcti *rect, const char *str, *r_yofs = yofs; } -void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, const char *str) +void uiStyleFontDraw(uiFontStyle *fs, const rcti *rect, const char *str) { float xofs, yofs; uiStyleFontDrawExt(fs, rect, str, - &xofs, &yofs); + BLF_DRAW_STR_DUMMY_MAX, &xofs, &yofs); } /* drawn same as above, but at 90 degree angle */ -void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str) +void uiStyleFontDrawRotated(uiFontStyle *fs, const rcti *rect, const char *str) { float height; int xofs, yofs; @@ -215,7 +215,7 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str) /* rotate counter-clockwise for now (assumes left-to-right language)*/ xofs += height; - yofs = BLF_width(fs->uifont_id, str) + 5; + yofs = BLF_width(fs->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX) + 5; angle = (float)M_PI / 2.0f; /* translate rect to vertical */ @@ -298,7 +298,7 @@ int UI_GetStringWidth(const char *str) BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); uiStyleFontSet(fstyle); - width = BLF_width(fstyle->uifont_id, str); + width = BLF_width(fstyle->uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); if (fstyle->kerning == 1) BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ef9b16f5445..ba827285ace 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -443,7 +443,8 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str but->icon = RNA_struct_ui_icon(type); /* default dragging of icon for id browse buttons */ uiButSetDragID(but, id); - uiButSetFlag(but, UI_HAS_ICON | UI_ICON_LEFT); + uiButSetFlag(but, UI_HAS_ICON); + uiButSetDrawFlag(but, UI_BUT_ICON_LEFT); } if ((idfrom && idfrom->lib) || !editable) @@ -1482,7 +1483,6 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand TIP_("Delete the active position")); uiButSetNFunc(bt, colorband_del_cb, MEM_dupallocN(cb), coba); - /* XXX, todo for later - convert to operator - campbell */ bt = uiDefBut(block, BUT, 0, "F", 95 + xoffs, line1_y, 20, UI_UNIT_Y, NULL, 0, 0, 0, 0, TIP_("Flip colorband")); @@ -1500,8 +1500,6 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand bt = uiDefBut(block, BUT_COLORBAND, 0, "", xoffs, line2_y, 300, UI_UNIT_Y, coba, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - - if (coba->tot) { CBData *cbd = coba->data + coba->cur; @@ -1519,8 +1517,10 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand } -static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr, RNAUpdateCb *cb) +static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr, + RNAUpdateCb *cb) { + uiLayout *row; uiBut *bt; float unit = BLI_rctf_size_x(butr) / 14.0f; float xs = butr->xmin; @@ -1537,25 +1537,35 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand uiButSetNFunc(bt, colorband_flip_cb, MEM_dupallocN(cb), coba); uiBlockEndAlign(block); - if (coba->tot) { - CBData *cbd = coba->data + coba->cur; - PointerRNA ptr; - RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr); - uiItemR(layout, &ptr, "color", 0, "", ICON_NONE); - } + row = uiLayoutRow(layout, FALSE); bt = uiDefButS(block, MENU, 0, IFACE_("Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4"), xs + 10.0f * unit, butr->ymin + UI_UNIT_Y, unit * 4, UI_UNIT_Y, &coba->ipotype, 0.0, 0.0, 0, 0, TIP_("Set interpolation between color stops")); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); + row = uiLayoutRow(layout, FALSE); + bt = uiDefBut(block, BUT_COLORBAND, 0, "", xs, butr->ymin, BLI_rctf_size_x(butr), UI_UNIT_Y, coba, 0, 0, 0, 0, ""); uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL); - uiBlockEndAlign(block); + if (coba->tot) { + CBData *cbd = coba->data + coba->cur; + PointerRNA ptr; + + RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr); + + row = uiLayoutRow(layout, FALSE); + + uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE); + bt = block->buttons.last; + uiButSetFunc(bt, colorband_update_cb, bt, coba); + + uiItemR(row, &ptr, "color", 0, "", ICON_NONE); + } } -static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, rctf *butr, +static void colorband_buttons_layout(uiLayout *layout, uiBlock *block, ColorBand *coba, const rctf *butr, int small, RNAUpdateCb *cb) { if (small) @@ -2474,11 +2484,7 @@ static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UN struct PointerRNA *UNUSED(active_dataptr), const char *UNUSED(active_propname), int UNUSED(index), int UNUSED(flt_flag)) { - char *namebuf; - const char *name; - - namebuf = RNA_struct_name_get_alloc(itemptr, NULL, 0, NULL); - name = (namebuf) ? namebuf : ""; + PropertyRNA *nameprop = RNA_struct_name_property(itemptr->type); /* Simplest one! */ switch (ui_list->layout_type) { @@ -2488,14 +2494,14 @@ static void uilist_draw_item_default(struct uiList *ui_list, struct bContext *UN case UILST_LAYOUT_DEFAULT: case UILST_LAYOUT_COMPACT: default: - uiItemL(layout, name, icon); + if (nameprop) { + uiItemFullR(layout, itemptr, nameprop, RNA_NO_INDEX, 0, UI_ITEM_R_NO_BG, "", icon); + } + else { + uiItemL(layout, "", icon); + } break; } - - /* free name */ - if (namebuf) { - MEM_freeN(namebuf); - } } static void uilist_draw_filter_default(struct uiList *ui_list, struct bContext *UNUSED(C), struct uiLayout *layout) @@ -2557,7 +2563,7 @@ static void uilist_filter_items_default(struct uiList *ui_list, struct bContext dyn_data->items_shown = 0; /* Implicitly add heading/trailing wildcards if needed. */ - if (len + 3 <= 32) { + if (slen + 3 <= sizeof(filter_buff)) { filter = filter_buff; } else { @@ -2666,8 +2672,11 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma if (columns == 0) columns = 9; - if (ui_list->list_grip >= rows) { - maxrows = rows = ui_list->list_grip; + if (ui_list->list_grip >= (rows - 1) && ui_list->list_grip != 0) { + /* Only enable auto-size mode when we have dragged one row away from minimum size. + * Avoids to switch too easily to auto-size mode when resizing to minimum size... + */ + maxrows = rows = max_ii(ui_list->list_grip, rows); } else { ui_list->list_grip = 0; /* Reset to auto-size mode. */ @@ -2712,8 +2721,8 @@ static void prepare_list(uiList *ui_list, int len, int activei, int rows, int ma } void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, - PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, - const char *active_propname, int rows, int maxrows, int layout_type, int columns) + PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, + int rows, int maxrows, int layout_type, int columns) { uiListType *ui_list_type; uiList *ui_list = NULL; @@ -2939,7 +2948,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL); - uiButSetFlag(but, UI_BUT_NO_TOOLTIP); + uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -2949,7 +2958,6 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co draw_item(ui_list, C, sub, dataptr, itemptr, icon, active_dataptr, active_propname, org_i, flt_flag); - /* If we are "drawing" active item, set all labels as active. */ if (i == activei) { ui_layout_list_set_labels_active(sub); @@ -2975,7 +2983,9 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co case UILST_LAYOUT_COMPACT: row = uiLayoutRow(layout, TRUE); - if (dataptr->data && prop && dyn_data->items_shown > 0) { + if ((dataptr->data && prop) && (dyn_data->items_shown > 0) && + (activei >= 0) && (activei < dyn_data->items_shown)) + { PointerRNA *itemptr = &items_ptr[activei].item; int org_i = items_ptr[activei].org_idx; @@ -3026,7 +3036,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co but = uiDefButR_prop(subblock, LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, active_dataptr, activeprop, 0, 0, org_i, 0, 0, NULL); - uiButSetFlag(but, UI_BUT_NO_TOOLTIP); + uiButSetDrawFlag(but, UI_BUT_NO_TOOLTIP); sub = uiLayoutRow(overlap, FALSE); @@ -3303,7 +3313,7 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C) ui_abs = uiLayoutAbsolute(layout, FALSE); block = uiLayoutGetBlock(ui_abs); - width = BLF_width(style->widget.uifont_id, report->message); + width = BLF_width(style->widget.uifont_id, report->message, report->len); width = min_ii((int)(rti->widthfac * width), width); width = max_ii(width, 10); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 97dd4f59ff6..9826f07e464 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -118,7 +118,7 @@ typedef struct uiWidgetType { void (*state)(struct uiWidgetType *, int state); void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); - void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); + void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); } uiWidgetType; @@ -606,7 +606,7 @@ static void widget_check_trias(uiWidgetTrias *tria, const rcti *rect) /* prepares shade colors */ -static void shadecolors4(char coltop[4], char *coldown, const char *color, short shadetop, short shadedown) +static void shadecolors4(char coltop[4], char coldown[4], const char *color, short shadetop, short shadedown) { coltop[0] = CLAMPIS(color[0] + shadetop, 0, 255); @@ -682,17 +682,14 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); glDrawArrays(GL_POLYGON, 0, wtb->totvert); - glDisableClientState(GL_VERTEX_ARRAY); /* light checkers */ glEnable(GL_POLYGON_STIPPLE); glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); glPolygonStipple(checker_stipple_sml); - glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); glDrawArrays(GL_POLYGON, 0, wtb->totvert); - glDisableClientState(GL_VERTEX_ARRAY); glDisable(GL_POLYGON_STIPPLE); @@ -700,7 +697,6 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4ubv((unsigned char *)wcol->inner); - glEnableClientState(GL_VERTEX_ARRAY); for (a = 0; a < wtb->totvert; a++) { x_mid += wtb->inner_v[a][0]; @@ -709,7 +705,6 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) glVertexPointer(2, GL_FLOAT, 0, wtb->inner_v); glDrawArrays(GL_POLYGON, 0, wtb->totvert); - glDisableClientState(GL_VERTEX_ARRAY); /* 1/2 solid color */ glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255); @@ -719,7 +714,6 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) inner_v_half[a][1] = wtb->inner_v[a][1]; } - glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, inner_v_half); glDrawArrays(GL_POLYGON, 0, wtb->totvert); glDisableClientState(GL_VERTEX_ARRAY); @@ -882,7 +876,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti } /* extra feature allows more alpha blending */ - if (ELEM(but->type, LABEL, LISTLABEL) && but->a1 == 1.0f) + if ((but->type == LABEL) && but->a1 == 1.0f) alpha *= but->a2; glEnable(GL_BLEND); @@ -890,7 +884,7 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, const rcti if (icon && icon != ICON_BLANK1) { float ofs = 1.0f / aspect; - if (but->flag & UI_ICON_LEFT) { + if (but->drawflag & UI_BUT_ICON_LEFT) { if (but->block->flag & UI_BLOCK_LOOP) { if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) xs = rect->xmin + 4.0f * ofs; @@ -956,7 +950,7 @@ static void ui_text_clip_give_next_off(uiBut *but) */ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = BLI_rcti_size_x(rect) - border; if (but->flag & UI_HAS_ICON) @@ -973,11 +967,11 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); but->ofs = 0; - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr)); while (but->strwidth > okwidth) { ui_text_clip_give_next_off(but); - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); if (but->strwidth < 10) break; } @@ -991,7 +985,7 @@ static void ui_text_clip_left(uiFontStyle *fstyle, uiBut *but, const rcti *rect) */ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0); if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; @@ -1007,20 +1001,16 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec if (but->ofs > but->pos) but->ofs = but->pos; - if (BLF_width(fstyle->uifont_id, but->drawstr) <= okwidth) + if (BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr)) <= okwidth) but->ofs = 0; - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); while (but->strwidth > okwidth) { float width; - char buf[UI_MAX_DRAW_STR]; - /* copy draw string */ - BLI_strncpy_utf8(buf, but->drawstr, sizeof(buf)); /* string position of cursor */ - buf[but->pos] = 0; - width = BLF_width(fstyle->uifont_id, buf + but->ofs); + width = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, but->pos - but->ofs); /* if cursor is at 20 pixels of right side button we clip left */ if (width > okwidth - 20) { @@ -1038,7 +1028,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec but->drawstr[len - bytes] = 0; } - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); if (but->strwidth < 10) break; } @@ -1055,7 +1045,7 @@ static void ui_text_clip_cursor(uiFontStyle *fstyle, uiBut *but, const rcti *rec */ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - int border = (but->flag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; + int border = (but->drawflag & UI_BUT_ALIGN_RIGHT) ? 8 : 10; int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0); char *cpoin = NULL; int drawstr_len = strlen(but->drawstr); @@ -1067,7 +1057,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti if (fstyle->kerning == 1) /* for BLF_width */ BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr, sizeof(but->drawstr)); but->ofs = 0; @@ -1095,7 +1085,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti drawstr_len -= bytes; // BLI_assert(strlen(but->drawstr) == drawstr_len); - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); if (but->strwidth < 10) break; } @@ -1103,7 +1093,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti /* after the leading text is gone, chop off the : and following space, with ofs */ while ((but->strwidth > okwidth) && (but->ofs < 2)) { ui_text_clip_give_next_off(but); - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); if (but->strwidth < 10) break; } @@ -1121,7 +1111,7 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti but->drawstr[drawstr_len] = 0; // BLI_assert(strlen(but->drawstr) == drawstr_len); - but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); + but->strwidth = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, sizeof(but->drawstr) - but->ofs); if (but->strwidth < 10) break; } @@ -1132,17 +1122,18 @@ static void ui_text_clip_right_label(uiFontStyle *fstyle, uiBut *but, const rcti static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect) { - //int transopts; // UNUSED - char *cpoin = NULL; + int drawstr_left_len = UI_MAX_DRAW_STR; + char *drawstr_right = NULL; + bool use_right_only = false; /* for underline drawing */ float font_xofs, font_yofs; uiStyleFontSet(fstyle); - if (but->editstr || (but->flag & UI_TEXT_LEFT)) + if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) fstyle->align = UI_STYLE_TEXT_LEFT; - else if (but->flag & UI_TEXT_RIGHT) + else if (but->drawflag & UI_BUT_TEXT_RIGHT) fstyle->align = UI_STYLE_TEXT_RIGHT; else fstyle->align = UI_STYLE_TEXT_CENTER; @@ -1152,7 +1143,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* text button selection and cursor */ if (but->editstr && but->pos != -1) { - short t = 0, pos = 0, ch; + short t = 0, pos = 0; short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw; if ((but->selend - but->selsta) > 0) { @@ -1163,23 +1154,13 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b if (but->drawstr[0] != 0) { if (but->selsta >= but->ofs) { - ch = but->drawstr[selsta_tmp]; - but->drawstr[selsta_tmp] = 0; - - selsta_draw = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); - - but->drawstr[selsta_tmp] = ch; + selsta_draw = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, selsta_tmp - but->ofs); } else { selsta_draw = 0; } - - ch = but->drawstr[selend_tmp]; - but->drawstr[selend_tmp] = 0; - - selwidth_draw = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); - - but->drawstr[selend_tmp] = ch; + + selwidth_draw = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, selend_tmp - but->ofs); glColor4ubv((unsigned char *)wcol->item); glRects(rect->xmin + selsta_draw, rect->ymin + 2, rect->xmin + selwidth_draw, rect->ymax - 2); @@ -1190,12 +1171,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b pos = but->pos; if (pos >= but->ofs) { if (but->drawstr[0] != 0) { - ch = but->drawstr[pos]; - but->drawstr[pos] = 0; - - t = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs) / but->aspect; - - but->drawstr[pos] = ch; + t = BLF_width(fstyle->uifont_id, but->drawstr + but->ofs, pos - but->ofs) / but->aspect; } glColor3f(0.20, 0.6, 0.9); @@ -1215,20 +1191,45 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b /* cut string in 2 parts - only for menu entries */ if ((but->block->flag & UI_BLOCK_LOOP)) { if (ELEM3(but->type, NUM, TEX, NUMSLI) == 0) { - cpoin = strchr(but->drawstr, UI_SEP_CHAR); - if (cpoin) *cpoin = 0; + drawstr_right = strchr(but->drawstr, UI_SEP_CHAR); + if (drawstr_right) { + drawstr_left_len = (drawstr_right - but->drawstr); + drawstr_right++; + } } } +#ifdef USE_NUMBUTS_LR_ALIGN + if (!drawstr_right && ELEM(but->type, NUM, NUMSLI) && (but->editstr == NULL)) { + drawstr_right = strchr(but->drawstr + but->ofs, ':'); + if (drawstr_right) { + drawstr_right++; + drawstr_left_len = (drawstr_right - but->drawstr); + + while (*drawstr_right == ' ') { + drawstr_right++; + } + } + else { + /* no prefix, even so use only cpoin */ + drawstr_right = but->drawstr + but->ofs; + use_right_only = true; + } + } +#endif + glColor4ubv((unsigned char *)wcol->text); - uiStyleFontDrawExt(fstyle, rect, but->drawstr + but->ofs, &font_xofs, &font_yofs); + if (!use_right_only) { + uiStyleFontDrawExt(fstyle, rect, but->drawstr + but->ofs, + drawstr_left_len - but->ofs, &font_xofs, &font_yofs); + } if (but->menu_key != '\0') { char fixedbuf[128]; char *str; - BLI_strncpy(fixedbuf, but->drawstr + but->ofs, sizeof(fixedbuf)); + BLI_strncpy(fixedbuf, but->drawstr + but->ofs, min_ii(sizeof(fixedbuf), drawstr_left_len)); str = strchr(fixedbuf, but->menu_key - 32); /* upper case */ if (str == NULL) @@ -1245,7 +1246,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b } fixedbuf[ul_index] = '\0'; - ul_advance = BLF_width(fstyle->uifont_id, fixedbuf); + ul_advance = BLF_width(fstyle->uifont_id, fixedbuf, ul_index); BLF_position(fstyle->uifont_id, rect->xmin + font_xofs + ul_advance, rect->ymin + font_yofs, 0.0f); BLF_draw(fstyle->uifont_id, "_", 2); @@ -1257,11 +1258,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b } /* part text right aligned */ - if (cpoin) { + if (drawstr_right) { fstyle->align = UI_STYLE_TEXT_RIGHT; rect->xmax -= ui_but_draw_menu_icon(but) ? UI_DPI_ICON_SIZE : 0.25f * U.widget_unit; - uiStyleFontDraw(fstyle, rect, cpoin + 1); - *cpoin = UI_SEP_CHAR; + uiStyleFontDraw(fstyle, rect, drawstr_right); } } @@ -1310,17 +1310,17 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB /* icons default draw 0.8f x height */ rect->xmin += (int)(0.8f * BLI_rcti_size_y(rect)); - if (but->editstr || (but->flag & UI_TEXT_LEFT)) { + if (but->editstr || (but->drawflag & UI_BUT_TEXT_LEFT)) { rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } - else if ((but->flag & UI_TEXT_RIGHT)) { + else if ((but->drawflag & UI_BUT_TEXT_RIGHT)) { rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } } - else if ((but->flag & UI_TEXT_LEFT)) { + else if ((but->drawflag & UI_BUT_TEXT_LEFT)) { rect->xmin += (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } - else if ((but->flag & UI_TEXT_RIGHT)) { + else if ((but->drawflag & UI_BUT_TEXT_RIGHT)) { rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect; } @@ -1656,8 +1656,14 @@ static void widget_state(uiWidgetType *wt, int state) { uiWidgetStateColors *wcol_state = wt->wcol_state; + if ((state & UI_BUT_LIST_ITEM) && !(state & UI_TEXTINPUT)) { + /* Override default widget's colors. */ + bTheme *btheme = UI_GetTheme(); + wt->wcol_theme = &btheme->tui.wcol_list_item; + } + wt->wcol = *(wt->wcol_theme); - + if (state & UI_SELECT) { copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); @@ -2289,7 +2295,7 @@ static void widget_numbut_draw(uiWidgetColors *wcol, rcti *rect, int state, int { uiWidgetBase wtb; const float rad = 0.5f * BLI_rcti_size_y(rect); - float textofs = rad * 0.75f; + float textofs = rad * 0.85f; if (state & UI_SELECT) SWAP(short, wcol->shadetop, wcol->shadedown); @@ -2318,9 +2324,9 @@ static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int round widget_numbut_draw(wcol, rect, state, roundboxalign, false); } -/* +/** * Draw number buttons still with triangles when field is not embossed -*/ + */ static void widget_numbut_embossn(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) { widget_numbut_draw(wcol, rect, state, roundboxalign, true); @@ -2335,7 +2341,7 @@ int ui_link_bezier_points(const rcti *rect, float coord_array[][2], int resol) vec[3][0] = rect->xmax; vec[3][1] = rect->ymax; - dist = 0.5f * ABS(vec[0][0] - vec[3][0]); + dist = 0.5f * fabsf(vec[0][0] - vec[3][0]); vec[1][0] = vec[0][0] + dist; vec[1][1] = vec[0][1]; @@ -2866,12 +2872,21 @@ static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UN /* labels use Editor theme colors for text */ static void widget_state_label(uiWidgetType *wt, int state) { - /* call this for option button */ - widget_state(wt, state); - if (state & UI_SELECT) - UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); - else - UI_GetThemeColor3ubv(TH_TEXT, (unsigned char *)wt->wcol.text); + if (state & UI_BUT_LIST_ITEM) { + /* Override default label theme's colors. */ + bTheme *btheme = UI_GetTheme(); + wt->wcol_theme = &btheme->tui.wcol_list_item; + /* call this for option button */ + widget_state(wt, state); + } + else { + /* call this for option button */ + widget_state(wt, state); + if (state & UI_SELECT) + UI_GetThemeColor3ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); + else + UI_GetThemeColor3ubv(TH_TEXT, (unsigned char *)wt->wcol.text); + } } static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) @@ -2991,11 +3006,6 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) case UI_WTYPE_REGULAR: break; - case UI_WTYPE_LISTLABEL: - wt.wcol_theme = &btheme->tui.wcol_list_item; - wt.draw = NULL; - /* Can't use usual label code. */ - break; case UI_WTYPE_LABEL: wt.draw = NULL; wt.state = widget_state_label; @@ -3139,15 +3149,15 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) int roundbox = UI_CNR_ALL; /* alignment */ - if ((but->flag & UI_BUT_ALIGN) && but->type != PULLDOWN) { + if ((but->drawflag & UI_BUT_ALIGN) && but->type != PULLDOWN) { /* ui_block_position has this correction too, keep in sync */ - if (but->flag & UI_BUT_ALIGN_TOP) + if (but->drawflag & UI_BUT_ALIGN_TOP) rect->ymax += U.pixelsize; - if (but->flag & UI_BUT_ALIGN_LEFT) + if (but->drawflag & UI_BUT_ALIGN_LEFT) rect->xmin -= U.pixelsize; - switch (but->flag & UI_BUT_ALIGN) { + switch (but->drawflag & UI_BUT_ALIGN) { case UI_BUT_ALIGN_TOP: roundbox = UI_CNR_BOTTOM_LEFT | UI_CNR_BOTTOM_RIGHT; break; @@ -3245,11 +3255,6 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct fstyle = &style->widgetlabel; } break; - - case LISTLABEL: - wt = widget_type(UI_WTYPE_LISTLABEL); - fstyle = &style->widgetlabel; - break; case SEPR: break; @@ -3295,7 +3300,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case OPTIONN: if (!(but->flag & UI_HAS_ICON)) { wt = widget_type(UI_WTYPE_OPTION); - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; } else wt = widget_type(UI_WTYPE_TOGGLE); @@ -3529,7 +3534,7 @@ void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int ic cpoin = strchr(name, UI_SEP_CHAR); if (cpoin) { *cpoin = 0; - rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1) + 10; + rect->xmax -= BLF_width(fstyle->uifont_id, cpoin + 1, INT_MAX) + 10; } } @@ -3575,7 +3580,7 @@ void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int widget_draw_preview(iconid, 1.0f, rect); - BLF_width_and_height(fstyle->uifont_id, name, &font_dims[0], &font_dims[1]); + BLF_width_and_height(fstyle->uifont_id, name, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]); /* text rect */ trect.xmin += 0; diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 55b353b1031..21176c9a25b 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -389,10 +389,26 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_NODE: cp = ts->syntaxl; break; - case TH_NODE_IN_OUT: + case TH_NODE_INPUT: cp = ts->syntaxn; break; - case TH_NODE_OPERATOR: + case TH_NODE_OUTPUT: + cp = ts->nodeclass_output; break; + case TH_NODE_COLOR: cp = ts->syntaxb; break; + case TH_NODE_FILTER: + cp = ts->nodeclass_filter; break; + case TH_NODE_VECTOR: + cp = ts->nodeclass_vector; break; + case TH_NODE_TEXTURE: + cp = ts->nodeclass_texture; break; + case TH_NODE_PATTERN: + cp = ts->nodeclass_pattern; break; + case TH_NODE_SCRIPT: + cp = ts->nodeclass_script; break; + case TH_NODE_LAYOUT: + cp = ts->nodeclass_layout; break; + case TH_NODE_SHADER: + cp = ts->nodeclass_shader; break; case TH_NODE_CONVERTOR: cp = ts->syntaxv; break; case TH_NODE_GROUP: @@ -913,6 +929,8 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tima.back, 53, 53, 53, 255); rgba_char_args_set(btheme->tima.vertex, 0, 0, 0, 255); rgba_char_args_set(btheme->tima.vertex_select, 255, 133, 0, 255); + rgba_char_args_set(btheme->tima.wire_edit, 192, 192, 192, 255); + rgba_char_args_set(btheme->tima.edge_select, 255, 133, 0, 255); btheme->tima.vertex_size = 3; btheme->tima.facedot_size = 3; rgba_char_args_set(btheme->tima.face, 255, 255, 255, 10); @@ -981,10 +999,18 @@ void ui_theme_init_default(void) btheme->tnode = btheme->tv3d; rgba_char_args_set(btheme->tnode.edge_select, 255, 255, 255, 255); /* wire selected */ rgba_char_args_set(btheme->tnode.syntaxl, 155, 155, 155, 160); /* TH_NODE, backdrop */ - rgba_char_args_set(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in/output */ + rgba_char_args_set(btheme->tnode.syntaxn, 100, 100, 100, 255); /* in */ + rgba_char_args_set(btheme->tnode.nodeclass_output, 100, 100, 100, 255); /* output */ rgba_char_args_set(btheme->tnode.syntaxb, 108, 105, 111, 255); /* operator */ rgba_char_args_set(btheme->tnode.syntaxv, 104, 106, 117, 255); /* generator */ rgba_char_args_set(btheme->tnode.syntaxc, 105, 117, 110, 255); /* group */ + rgba_char_args_set(btheme->tnode.nodeclass_texture, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_shader, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_filter, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_script, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_pattern, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_vector, 108, 105, 111, 255); /* operator */ + rgba_char_args_set(btheme->tnode.nodeclass_layout, 108, 105, 111, 255); /* operator */ rgba_char_args_set(btheme->tnode.movie, 155, 155, 155, 160); /* frame */ rgba_char_args_set(btheme->tnode.syntaxs, 151, 116, 116, 255); /* matte nodes */ rgba_char_args_set(btheme->tnode.syntaxd, 116, 151, 151, 255); /* distort nodes */ @@ -2218,13 +2244,43 @@ void init_userdef_do_versions(void) /* NOTE!! from now on use U.versionfile and U.subversionfile */ - if (U.versionfile < 269 || (U.versionfile == 268 && U.subversionfile < 3)) { + if (U.versionfile < 268 || (U.versionfile == 268 && U.subversionfile < 3)) { bTheme *btheme; for (btheme = U.themes.first; btheme; btheme = btheme->next) { rgba_char_args_test_set(btheme->tima.uv_others, 96, 96, 96, 255); rgba_char_args_test_set(btheme->tima.uv_shadow, 112, 112, 112, 255); } } + + if (U.versionfile < 269 || (U.versionfile == 269 && U.subversionfile < 5)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + rgba_char_args_set(btheme->tima.wire_edit, 192, 192, 192, 255); + rgba_char_args_set(btheme->tima.edge_select, 255, 133, 0, 255); + } + } + + if (U.versionfile < 269 || (U.versionfile == 269 && U.subversionfile < 6)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + char r, g, b; + r = btheme->tnode.syntaxn[0]; + g = btheme->tnode.syntaxn[1]; + b = btheme->tnode.syntaxn[2]; + rgba_char_args_test_set(btheme->tnode.nodeclass_output, r, g, b, 255); + r = btheme->tnode.syntaxb[0]; + g = btheme->tnode.syntaxb[1]; + b = btheme->tnode.syntaxb[2]; + rgba_char_args_test_set(btheme->tnode.nodeclass_filter, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_vector, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_texture, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_shader, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_script, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_pattern, r, g, b, 255); + rgba_char_args_test_set(btheme->tnode.nodeclass_layout, r, g, b, 255); + } + + } if (U.versionfile < 270) { /* grease pencil - new layer color */ @@ -2246,3 +2302,23 @@ void init_userdef_do_versions(void) // XXX reset_autosave(); } + +/** + * Override values in in-memory startup.blend, avoids resaving for small changes. + */ +void init_userdef_factory(void) +{ + /* defaults from T37518 */ + U.uiflag2 |= USER_REGION_OVERLAP; + + U.uiflag |= USER_AUTOPERSP; + U.uiflag |= USER_ORBIT_SELECTION; + U.uiflag |= USER_ZBUF_CURSOR; + U.uiflag |= USER_QUIT_PROMPT; + U.uiflag |= USER_CONTINUOUS_MOUSE; + + U.ogl_multisamples = USER_MULTISAMPLE_4; + + U.versions = 1; + U.savetime = 2; +} diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 037fa7c6a94..39583551bec 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -174,7 +174,7 @@ static void view2d_masks(View2D *v2d, int check_scrollers) */ void UI_view2d_region_reinit(View2D *v2d, short type, int winx, int winy) { - short tot_changed = 0, do_init; + bool tot_changed = false, do_init; uiStyle *style = UI_GetStyle(); do_init = (v2d->flag & V2D_IS_INITIALISED) == 0; @@ -937,11 +937,11 @@ void UI_view2d_totRect_set(View2D *v2d, int width, int height) } -int UI_view2d_tab_set(View2D *v2d, int tab) +bool UI_view2d_tab_set(View2D *v2d, int tab) { float default_offset[2] = {0.0f, 0.0f}; float *offset, *new_offset; - int changed = 0; + bool changed = false; /* if tab changed, change offset */ if (tab != v2d->tab_cur && v2d->tab_offset) { @@ -958,7 +958,7 @@ int UI_view2d_tab_set(View2D *v2d, int tab) /* validation should happen in subsequent totRect_set */ - changed = 1; + changed = true; } /* resize array if needed */ @@ -2172,7 +2172,7 @@ void UI_view2d_text_cache_add(View2D *v2d, float x, float y, const char *str, co } /* no clip (yet) */ -void UI_view2d_text_cache_rectf(View2D *v2d, rctf *rect, const char *str, const char col[4]) +void UI_view2d_text_cache_rectf(View2D *v2d, const rctf *rect, const char *str, const char col[4]) { int len = strlen(str) + 1; View2DString *v2s = MEM_callocN(sizeof(View2DString) + len, "View2DString"); @@ -2196,7 +2196,7 @@ void UI_view2d_text_cache_draw(ARegion *ar) int col_pack_prev = 0; /* investigate using BLF_ascender() */ - const float default_height = strings.first ? BLF_height_default("28") : 0.0f; + const float default_height = strings.first ? BLF_height_default("28", 3) : 0.0f; // glMatrixMode(GL_PROJECTION); // glPushMatrix(); diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index c5c9b1c8ce4..ce6f77afaac 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -1288,10 +1288,10 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar, } if (smooth_viewtx && fac > FLT_EPSILON) { - int changed = FALSE; + bool changed = false; if (BLI_rctf_compare(&sms.new_cur, &v2d->cur, FLT_EPSILON) == FALSE) - changed = TRUE; + changed = true; /* The new view is different from the old one * so animate the view */ diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c index 707622fa841..20d49e89771 100644 --- a/source/blender/editors/mask/mask_editaction.c +++ b/source/blender/editors/mask/mask_editaction.c @@ -207,21 +207,26 @@ void ED_masklayer_frames_select_border(MaskLayer *masklay, float min, float max, /* Frame Editing Tools */ /* Delete selected frames */ -void ED_masklayer_frames_delete(MaskLayer *masklay) +bool ED_masklayer_frames_delete(MaskLayer *masklay) { MaskLayerShape *masklay_shape, *masklay_shape_next; + bool changed = false; /* error checking */ if (masklay == NULL) - return; + return false; /* check for frames to delete */ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) { masklay_shape_next = masklay_shape->next; - if (masklay_shape->flag & MASK_SHAPE_SELECT) + if (masklay_shape->flag & MASK_SHAPE_SELECT) { BKE_mask_layer_shape_unlink(masklay, masklay_shape); + changed = true; + } } + + return changed; } /* Duplicate selected frames from given mask-layer */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 5ca0d133b0e..7d7960d2e86 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -38,6 +38,7 @@ #include "BKE_depsgraph.h" #include "BKE_main.h" #include "BKE_mask.h" +#include "BKE_report.h" #include "DNA_scene_types.h" #include "DNA_mask_types.h" @@ -942,11 +943,12 @@ static void delete_feather_points(MaskSplinePoint *point) } } -static int delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int delete_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; + int num_deleted = 0; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; @@ -972,7 +974,6 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) } if (count == 0) { - /* delete the whole spline */ BLI_remlink(&masklay->splines, spline); BKE_mask_spline_free(spline); @@ -983,6 +984,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) } BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig); + + num_deleted++; } else { MaskSplinePoint *new_points; @@ -1010,6 +1013,8 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) spline->tot_point--; BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1); + + num_deleted++; } } @@ -1031,11 +1036,16 @@ static int delete_exec(bContext *C, wmOperator *UNUSED(op)) } } + if (num_deleted == 0) + return OPERATOR_CANCELLED; + /* TODO: only update edited splines */ BKE_mask_update_display(mask, CFRA); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + BKE_reportf(op->reports, RPT_INFO, "Deleted %d control points from mask '%s'", num_deleted, mask->id.name); + return OPERATOR_FINISHED; } @@ -1047,7 +1057,6 @@ void MASK_OT_delete(wmOperatorType *ot) ot->idname = "MASK_OT_delete"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = delete_exec; ot->poll = ED_maskedit_mask_poll; @@ -1062,12 +1071,12 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; /* do actual selection */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - int change_layer = FALSE; + bool changed_layer = false; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; @@ -1076,19 +1085,19 @@ static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) for (spline = masklay->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline)) { BKE_mask_spline_direction_switch(masklay, spline); - change = TRUE; - change_layer = TRUE; + changed = true; + changed_layer = true; } } - if (change_layer) { + if (changed_layer) { if (IS_AUTOKEY_ON(scene)) { ED_mask_layer_shape_auto_key(masklay, CFRA); } } } - if (change) { + if (changed) { /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); @@ -1125,12 +1134,12 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op) MaskLayer *masklay; int i; - int change = FALSE; + bool changed = false; /* do actual selection */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; - int change_layer = FALSE; + bool changed_layer = false; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; @@ -1142,20 +1151,20 @@ static int mask_normals_make_consistent_exec(bContext *C, wmOperator *UNUSED(op) if (MASKPOINT_ISSEL_ANY(point)) { BKE_mask_calc_handle_point_auto(spline, point, FALSE); - change = TRUE; - change_layer = TRUE; + changed = true; + changed_layer = true; } } } - if (change_layer) { + if (changed_layer) { if (IS_AUTOKEY_ON(scene)) { ED_mask_layer_shape_auto_key(masklay, CFRA); } } } - if (change) { + if (changed) { /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); @@ -1193,7 +1202,7 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) MaskLayer *masklay; int handle_type = RNA_enum_get(op->ptr, "type"); - bool change = false; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; @@ -1211,13 +1220,13 @@ static int set_handle_type_exec(bContext *C, wmOperator *op) BezTriple *bezt = &point->bezt; bezt->h1 = bezt->h2 = handle_type; - change = true; + changed = true; } } } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); @@ -1258,14 +1267,14 @@ static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int changed = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { if (masklay->restrictflag & OB_RESTRICT_VIEW) { ED_mask_layer_select_set(masklay, TRUE); masklay->restrictflag &= ~OB_RESTRICT_VIEW; - changed = 1; + changed = true; } } @@ -1301,7 +1310,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; const int unselected = RNA_boolean_get(op->ptr, "unselected"); - int changed = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -1314,7 +1323,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) ED_mask_layer_select_set(masklay, FALSE); masklay->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; + changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); } @@ -1323,7 +1332,7 @@ static int mask_hide_view_set_exec(bContext *C, wmOperator *op) else { if (!ED_mask_layer_select_check(masklay)) { masklay->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; + changed = true; if (masklay == BKE_mask_layer_active(mask)) { BKE_mask_layer_active_set(mask, NULL); } @@ -1365,7 +1374,7 @@ static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int changed = FALSE; + bool changed = false; int i; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -1382,7 +1391,7 @@ static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) if (MASKPOINT_ISSEL_ANY(point)) { BezTriple *bezt = &point->bezt; bezt->weight = 0.0f; - changed = TRUE; + changed = true; } } } diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 90796e9eb93..613168e43a6 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -412,7 +412,8 @@ static int border_select_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; - int change = FALSE, mode, extend; + int mode; + bool changed = false, extend; /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); @@ -450,12 +451,12 @@ static int border_select_exec(bContext *C, wmOperator *op) BKE_mask_point_select_set_handle(point, FALSE); } - change = TRUE; + changed = true; } } } - if (change) { + if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); @@ -486,7 +487,7 @@ void MASK_OT_select_border(wmOperatorType *ot) WM_operator_properties_gesture_border(ot, TRUE); } -static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select) +static bool do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -496,7 +497,7 @@ static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, int i; rcti rect; - int change = FALSE; + bool changed = false; /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); @@ -533,18 +534,18 @@ static int do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, BKE_mask_point_select_set_handle(point, select); } - change = TRUE; + changed = true; } } } - if (change) { + if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); } - return change; + return changed; } static int clip_lasso_select_exec(bContext *C, wmOperator *op) @@ -610,8 +611,9 @@ static int circle_select_exec(bContext *C, wmOperator *op) MaskLayer *masklay; int i; - int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; + int x, y, radius, width, height, mode; + bool changed = false; /* get operator properties */ x = RNA_int_get(op->ptr, "x"); @@ -649,13 +651,13 @@ static int circle_select_exec(bContext *C, wmOperator *op) BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); - change = TRUE; + changed = true; } } } } - if (change) { + if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); @@ -703,7 +705,7 @@ static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE int is_handle = 0; const float threshold = 19; - int change = FALSE; + bool changed = false; ED_mask_mouse_pos(sa, ar, event->mval, co); @@ -714,10 +716,10 @@ static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE masklay->act_spline = spline; masklay->act_point = point; - change = TRUE; + changed = true; } - if (change) { + if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); @@ -750,7 +752,7 @@ static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; /* do actual selection */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -763,12 +765,12 @@ static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) for (spline = masklay->splines.first; spline; spline = spline->next) { if (ED_mask_spline_select_check(spline)) { ED_mask_spline_select_set(spline, TRUE); - change = TRUE; + changed = true; } } } - if (change) { + if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c index 78dba382520..cea350219c0 100644 --- a/source/blender/editors/mask/mask_shapekey.c +++ b/source/blender/editors/mask/mask_shapekey.c @@ -60,7 +60,7 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskLayerShape *masklay_shape; @@ -71,10 +71,10 @@ static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) masklay_shape = BKE_mask_layer_shape_verify_frame(masklay, frame); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); - change = TRUE; + changed = true; } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); @@ -106,7 +106,7 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskLayerShape *masklay_shape; @@ -119,11 +119,11 @@ static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) if (masklay_shape) { BKE_mask_layer_shape_unlink(masklay, masklay_shape); - change = TRUE; + changed = true; } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, OB_RECALC_DATA); @@ -155,7 +155,7 @@ static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -208,14 +208,14 @@ static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op) // printf("%s: skipping\n", __func__); } - change = TRUE; + changed = true; } BKE_mask_layer_shape_free(masklay_shape_reset); } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); @@ -255,7 +255,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op) const int frame = CFRA; Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; - int change = FALSE; + bool changed = false; const short do_feather = RNA_boolean_get(op->ptr, "feather"); const short do_location = RNA_boolean_get(op->ptr, "location"); @@ -371,7 +371,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op) BKE_mask_layer_shape_free(masklay_shape_tmp); } - change = TRUE; + changed = true; } } @@ -380,7 +380,7 @@ static int mask_shape_key_rekey_exec(bContext *C, wmOperator *op) } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); DAG_id_tag_update(&mask->id, 0); @@ -421,23 +421,23 @@ void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame) BKE_mask_layer_shape_from_mask(masklay, masklay_shape); } -int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) +bool ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) { MaskLayer *masklay; - int change = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { ED_mask_layer_shape_auto_key(masklay, frame); - change = TRUE; + changed = true; } - return change; + return changed; } -int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) +bool ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) { MaskLayer *masklay; - int change = FALSE; + bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -446,8 +446,8 @@ int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) } ED_mask_layer_shape_auto_key(masklay, frame); - change = TRUE; + changed = true; } - return change; + return changed; } diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 47b9d5e2a9e..f81eef7ac88 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -411,8 +411,8 @@ void MESH_OT_primitive_grid_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_int(ot->srna, "x_subdivisions", 10, 3, INT_MAX, "X Subdivisions", "", 3, 1000); - RNA_def_int(ot->srna, "y_subdivisions", 10, 3, INT_MAX, "Y Subdivisions", "", 3, 1000); + RNA_def_int(ot->srna, "x_subdivisions", 10, 2, INT_MAX, "X Subdivisions", "", 2, 1000); + RNA_def_int(ot->srna, "y_subdivisions", 10, 2, INT_MAX, "Y Subdivisions", "", 2, 1000); ED_object_add_unit_props(ot); ED_object_add_generic_props(ot, true); diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index 7bc3ff3ab77..c3c4bda4178 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -36,6 +36,7 @@ #include "BKE_global.h" #include "BKE_context.h" #include "BKE_editmesh.h" +#include "BKE_report.h" #include "RNA_define.h" #include "RNA_access.h" @@ -110,8 +111,15 @@ static bool mesh_bisect_interactive_calc( static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); int ret; + if (em->bm->totedgesel == 0) { + BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required"); + return OPERATOR_CANCELLED; + } + /* if the properties are set or there is no rv3d, * skip model and exec immediately */ @@ -129,8 +137,6 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) wmGesture *gesture = op->customdata; BisectData *opdata; - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data"); opdata->mesh_backup = EDBM_redo_state_store(em); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 6b99f53a5b8..102bad26e28 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -50,6 +50,7 @@ #include "BKE_context.h" #include "BKE_editmesh.h" #include "BKE_editmesh_bvh.h" +#include "BKE_report.h" #include "BIF_gl.h" #include "BIF_glutil.h" /* for paint cursor */ @@ -1075,7 +1076,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) * In such a case we should have gotten hits on edges or verts of the face. */ static bool knife_ray_intersect_face(KnifeTool_OpData *kcd, const float s[2], - const float v1[2], const float v2[2], + const float v1[3], const float v2[3], BMFace *f, const float face_tol, float intersectp[3]) @@ -2646,6 +2647,15 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event) KnifeTool_OpData *kcd; + if (only_select) { + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + if (em->bm->totfacesel == 0) { + BKE_report(op->reports, RPT_ERROR, "Selected faces required"); + return OPERATOR_CANCELLED; + } + } + view3d_operator_needs_opengl(C); /* alloc new customdata */ @@ -2903,17 +2913,16 @@ void MESH_OT_knife_tool(wmOperatorType *ot) */ static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3]) { - int tottri = f->len - 2; - BMLoop **loops = BLI_array_alloca(loops, f->len); - int (*index)[3] = BLI_array_alloca(index, tottri); + const int tottri = f->len - 2; + BMLoop **loops = BLI_array_alloca(loops, f->len); + unsigned int (*index)[3] = BLI_array_alloca(index, tottri); int j; float const *best_co[3] = {NULL}; float best_area = -1.0f; bool ok = false; - tottri = BM_face_calc_tessellation(f, loops, index); - BLI_assert(tottri <= f->len - 2); + BM_face_calc_tessellation(f, loops, index); for (j = 0; j < tottri; j++) { const float *p1 = loops[index[j][0]]->v->co; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 92bd71e128a..e429e433a4b 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -1811,7 +1811,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em) BMFace *efa; BMEdge *eed; bool ok; - bool change = false; + bool changed = false; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) @@ -1828,11 +1828,11 @@ bool EDBM_select_interior_faces(BMEditMesh *em) if (ok) { BM_face_select_set(bm, efa, true); - change = true; + changed = true; } } - return change; + return changed; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 203907226e3..fd391a31074 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -509,6 +509,18 @@ static BMElem *edbm_add_edge_face_exec__tricky_extend_sel(BMesh *bm) (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) && (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) || +#if 1 /* better support mixed cases [#37203] */ + ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire) == 1) && + (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) && + (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) && + (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) || + + ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) && + (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_wire) == 1) && + (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) && + (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) || +#endif + ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) && (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) && (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) && @@ -3210,6 +3222,10 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op) EDBM_op_init(em, &bmop, op, "triangulate faces=%hf quad_method=%i ngon_method=%i", BM_ELEM_SELECT, quad_method, ngon_method); BMO_op_exec(em->bm, &bmop); + /* select the output */ + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + EDBM_selectmode_flush(em); + if (!EDBM_op_finish(em, &bmop, op, true)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index deae9f17992..3daffe9bb37 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -200,7 +200,7 @@ static EnumPropertyItem prop_similar_types[] = { static bool mball_select_similar_type(MetaBall *mb) { MetaElem *ml; - bool change = false; + bool changed = false; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { @@ -210,20 +210,20 @@ static bool mball_select_similar_type(MetaBall *mb) if ((ml_iter->flag & SELECT) == 0) { if (ml->type == ml_iter->type) { ml_iter->flag |= SELECT; - change = true; + changed = true; } } } } } - return change; + return changed; } static bool mball_select_similar_radius(MetaBall *mb, const float thresh) { MetaElem *ml; - bool change = false; + bool changed = false; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { @@ -233,20 +233,20 @@ static bool mball_select_similar_radius(MetaBall *mb, const float thresh) if ((ml_iter->flag & SELECT) == 0) { if (fabsf(ml_iter->rad - ml->rad) <= (thresh * ml->rad)) { ml_iter->flag |= SELECT; - change = true; + changed = true; } } } } } - return change; + return changed; } static bool mball_select_similar_stiffness(MetaBall *mb, const float thresh) { MetaElem *ml; - bool change = false; + bool changed = false; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { @@ -256,21 +256,21 @@ static bool mball_select_similar_stiffness(MetaBall *mb, const float thresh) if ((ml_iter->flag & SELECT) == 0) { if (fabsf(ml_iter->s - ml->s) <= thresh) { ml_iter->flag |= SELECT; - change = true; + changed = true; } } } } } - return change; + return changed; } static bool mball_select_similar_rotation(MetaBall *mb, const float thresh) { const float thresh_rad = thresh * (float)M_PI_2; MetaElem *ml; - bool change = false; + bool changed = false; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { @@ -299,14 +299,14 @@ static bool mball_select_similar_rotation(MetaBall *mb, const float thresh) angle_normalized_v3v3(ml_mat[2], ml_iter_mat[2])) < thresh_rad) { ml_iter->flag |= SELECT; - change = true; + changed = true; } } } } } - return change; + return changed; } static int mball_select_similar_exec(bContext *C, wmOperator *op) @@ -316,27 +316,27 @@ static int mball_select_similar_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); float thresh = RNA_float_get(op->ptr, "threshold"); - bool change = false; + bool changed = false; switch (type) { case SIMMBALL_TYPE: - change = mball_select_similar_type(mb); + changed = mball_select_similar_type(mb); break; case SIMMBALL_RADIUS: - change = mball_select_similar_radius(mb, thresh); + changed = mball_select_similar_radius(mb, thresh); break; case SIMMBALL_STIFFNESS: - change = mball_select_similar_stiffness(mb, thresh); + changed = mball_select_similar_stiffness(mb, thresh); break; case SIMMBALL_ROTATION: - change = mball_select_similar_rotation(mb, thresh); + changed = mball_select_similar_rotation(mb, thresh); break; default: BLI_assert(0); break; } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 9dd686326bb..7e55d082883 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -999,7 +999,7 @@ static int object_speaker_add_exec(bContext *C, wmOperator *op) BKE_nlatrack_add_strip(nlt, strip); /* auto-name the strip, and give the track an interesting name */ - strcpy(nlt->name, DATA_("SoundTrack")); + BLI_strncpy(nlt->name, DATA_("SoundTrack"), sizeof(nlt->name)); BKE_nlastrip_validate_name(adt, strip); WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL); @@ -1057,6 +1057,7 @@ static int object_delete_exec(bContext *C, wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; const short use_global = RNA_boolean_get(op->ptr, "use_global"); + int num_deleted = 0; if (CTX_data_edit_object(C)) return OPERATOR_CANCELLED; @@ -1068,6 +1069,7 @@ static int object_delete_exec(bContext *C, wmOperator *op) /* remove from current scene only */ ED_base_object_free_and_unlink(bmain, scene, base); + num_deleted++; if (use_global) { Scene *scene_iter; @@ -1102,6 +1104,9 @@ static int object_delete_exec(bContext *C, wmOperator *op) } } + if (num_deleted > 0) + BKE_reportf(op->reports, RPT_INFO, "Deleted %d objects", num_deleted); + return OPERATOR_FINISHED; } @@ -1113,7 +1118,6 @@ void OBJECT_OT_delete(wmOperatorType *ot) ot->idname = "OBJECT_OT_delete"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = object_delete_exec; ot->poll = ED_operator_objectmode; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2e011493fce..465eb07f993 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -137,7 +137,7 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) View3D *v3d = sa->spacedata.first; Scene *scene = CTX_data_scene(C); Base *base; - int changed = 0; + bool changed = false; /* XXX need a context loop to handle such cases */ for (base = FIRSTBASE; base; base = base->next) { @@ -145,7 +145,7 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) base->flag |= SELECT; base->object->flag = base->flag; base->object->restrictflag &= ~OB_RESTRICT_VIEW; - changed = 1; + changed = true; } } if (changed) { @@ -177,7 +177,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - short changed = 0; + bool changed = false; const int unselected = RNA_boolean_get(op->ptr, "unselected"); CTX_DATA_BEGIN(C, Base *, base, visible_bases) @@ -187,7 +187,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) base->flag &= ~SELECT; base->object->flag = base->flag; base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; + changed = true; if (base == BASACT) { ED_base_object_activate(C, NULL); } @@ -196,7 +196,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) else { if (!(base->flag & SELECT)) { base->object->restrictflag |= OB_RESTRICT_VIEW; - changed = 1; + changed = true; if (base == BASACT) { ED_base_object_activate(C, NULL); } @@ -237,14 +237,14 @@ void OBJECT_OT_hide_view_set(wmOperatorType *ot) /* 99% same as above except no need for scene refreshing (TODO, update render preview) */ static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op)) { - short changed = 0; + bool changed = false; /* XXX need a context loop to handle such cases */ CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->restrictflag & OB_RESTRICT_RENDER) { ob->restrictflag &= ~OB_RESTRICT_RENDER; - changed = 1; + changed = true; } } CTX_DATA_END; diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index ce509e2ffe7..536f3f05ab2 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -142,6 +142,7 @@ 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_select_mirror(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 3425aa08955..fdc9a604c07 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -49,6 +49,7 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -226,6 +227,78 @@ void LATTICE_OT_select_random(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); } + +/* -------------------------------------------------------------------- */ +/* Select Mirror Operator */ + +static int lattice_select_mirror_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; + const bool extend = RNA_boolean_get(op->ptr, "extend"); + const int axis = RNA_enum_get(op->ptr, "axis"); + bool flip_uvw[3] = {false}; + int tot, i; + BPoint *bp; + BLI_bitmap *selpoints; + + tot = lt->pntsu * lt->pntsv * lt->pntsw; + + flip_uvw[axis] = true; + + if (!extend) { + lt->actbp = LT_ACTBP_NONE; + } + + /* store "original" selection */ + selpoints = BLI_BITMAP_NEW(tot, __func__); + BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); + + /* actual (de)selection */ + for (i = 0; i < tot; i++) { + const int i_flip = BKE_lattice_index_flip(lt, i, flip_uvw[0], flip_uvw[1], flip_uvw[2]); + bp = <->def[i]; + if (!bp->hide) { + if (BLI_BITMAP_GET(selpoints, i_flip)) { + bp->f1 |= SELECT; + } + else { + if (!extend) { + bp->f1 &= ~SELECT; + } + } + } + } + + + MEM_freeN(selpoints); + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_select_mirror(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Mirror"; + ot->description = "Select mirrored lattice points"; + ot->idname = "LATTICE_OT_select_mirror"; + + /* api callbacks */ + ot->exec = lattice_select_mirror_exec; + ot->poll = ED_operator_editlattice; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_enum(ot->srna, "axis", object_axis_unsigned_items, 0, "Axis", ""); + + 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) @@ -251,18 +324,13 @@ static int lattice_select_more_less(bContext *C, const bool select) Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; BPoint *bp; const int tot = lt->pntsu * lt->pntsv * lt->pntsw; - int i, w, u, v; + int u, v, w; 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); - } - } + BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); bp = lt->def; for (w = 0; w < lt->pntsw; w++) { diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 80543d330b3..d4c64552b38 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -2220,7 +2220,7 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_active_context(C); LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform); - + if (!lmd) return OPERATOR_CANCELLED; if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) { diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 74ac487b687..efebbe8ddd7 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -224,6 +224,7 @@ void ED_operatortypes_object(void) 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_select_mirror); WM_operatortype_append(LATTICE_OT_make_regular); WM_operatortype_append(LATTICE_OT_flip); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index c70a70c47b2..b3a2a7b6e0b 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1192,8 +1192,9 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) + if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->trackflag = TRACK_nZ; + } } } CTX_DATA_END; @@ -1212,7 +1213,7 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) { + if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->reserved1 = TRACK_nZ; data->reserved2 = UP_Y; } @@ -1234,7 +1235,7 @@ static int track_set_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME); /* Lamp, Camera and Speaker track differently by default */ - if (ob->type == OB_LAMP || ob->type == OB_CAMERA || ob->type == OB_SPEAKER) { + if (ELEM3(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { data->trackflag = TRACK_nZ; data->lockflag = LOCK_Y; } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index ffa9eed65b9..fc83919144f 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -216,7 +216,7 @@ static EnumPropertyItem prop_select_linked_types[] = { #if 0 static int object_select_all_by_ipo(bContext *C, Ipo *ipo) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -224,7 +224,7 @@ static int object_select_all_by_ipo(bContext *C, Ipo *ipo) base->flag |= SELECT; base->object->flag = base->flag; - changed = TRUE; + changed = true; } } CTX_DATA_END; @@ -233,9 +233,9 @@ static int object_select_all_by_ipo(bContext *C, Ipo *ipo) } #endif -static int object_select_all_by_obdata(bContext *C, void *obdata) +static bool object_select_all_by_obdata(bContext *C, void *obdata) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -244,7 +244,7 @@ static int object_select_all_by_obdata(bContext *C, void *obdata) base->flag |= SELECT; base->object->flag = base->flag; - changed = TRUE; + changed = true; } } } @@ -253,9 +253,9 @@ static int object_select_all_by_obdata(bContext *C, void *obdata) return changed; } -static int object_select_all_by_material_texture(bContext *C, int use_texture, Material *mat, Tex *tex) +static bool object_select_all_by_material_texture(bContext *C, int use_texture, Material *mat, Tex *tex) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -270,7 +270,7 @@ static int object_select_all_by_material_texture(bContext *C, int use_texture, M if (!use_texture) { if (mat1 == mat) { base->flag |= SELECT; - changed = TRUE; + changed = true; } } else if (mat1 && use_texture) { @@ -278,7 +278,7 @@ static int object_select_all_by_material_texture(bContext *C, int use_texture, M if (mat1->mtex[b]) { if (tex == mat1->mtex[b]->tex) { base->flag |= SELECT; - changed = TRUE; + changed = true; break; } } @@ -294,9 +294,9 @@ static int object_select_all_by_material_texture(bContext *C, int use_texture, M return changed; } -static int object_select_all_by_dup_group(bContext *C, Object *ob) +static bool object_select_all_by_dup_group(bContext *C, Object *ob) { - int changed = FALSE; + bool changed = false; Group *dup_group = (ob->transflag & OB_DUPLIGROUP) ? ob->dup_group : NULL; CTX_DATA_BEGIN (C, Base *, base, visible_bases) @@ -307,7 +307,7 @@ static int object_select_all_by_dup_group(bContext *C, Object *ob) base->flag |= SELECT; base->object->flag = base->flag; - changed = TRUE; + changed = true; } } } @@ -316,9 +316,9 @@ static int object_select_all_by_dup_group(bContext *C, Object *ob) return changed; } -static int object_select_all_by_particle(bContext *C, Object *ob) +static bool object_select_all_by_particle(bContext *C, Object *ob) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -331,7 +331,7 @@ static int object_select_all_by_particle(bContext *C, Object *ob) for (psys_act = ob->particlesystem.first; psys_act; psys_act = psys_act->next) { if (psys->part == psys_act->part) { base->flag |= SELECT; - changed = TRUE; + changed = true; break; } } @@ -349,9 +349,9 @@ static int object_select_all_by_particle(bContext *C, Object *ob) return changed; } -static int object_select_all_by_library(bContext *C, Library *lib) +static bool object_select_all_by_library(bContext *C, Library *lib) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -360,7 +360,7 @@ static int object_select_all_by_library(bContext *C, Library *lib) base->flag |= SELECT; base->object->flag = base->flag; - changed = TRUE; + changed = true; } } } @@ -369,9 +369,9 @@ static int object_select_all_by_library(bContext *C, Library *lib) return changed; } -static int object_select_all_by_library_obdata(bContext *C, Library *lib) +static bool object_select_all_by_library_obdata(bContext *C, Library *lib) { - int changed = FALSE; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, visible_bases) { @@ -380,7 +380,7 @@ static int object_select_all_by_library_obdata(bContext *C, Library *lib) base->flag |= SELECT; base->object->flag = base->flag; - changed = TRUE; + changed = true; } } } @@ -392,7 +392,7 @@ static int object_select_all_by_library_obdata(bContext *C, Library *lib) void ED_object_select_linked_by_id(bContext *C, ID *id) { int idtype = GS(id->name); - int changed = FALSE; + bool changed = false; if (OB_DATA_SUPPORT_ID(idtype)) { changed = object_select_all_by_obdata(C, id); @@ -414,7 +414,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob; int nr = RNA_enum_get(op->ptr, "type"); - short changed = FALSE, extend; + bool changed = false, extend; extend = RNA_boolean_get(op->ptr, "extend"); @@ -533,16 +533,16 @@ static EnumPropertyItem prop_select_grouped_types[] = { {0, NULL, 0, NULL, NULL} }; -static short select_grouped_children(bContext *C, Object *ob, int recursive) +static bool select_grouped_children(bContext *C, Object *ob, const bool recursive) { - short changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if (ob == base->object->parent) { if (!(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } if (recursive) @@ -553,12 +553,12 @@ static short select_grouped_children(bContext *C, Object *ob, int recursive) return changed; } -static short select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */ +static bool select_grouped_parent(bContext *C) /* Makes parent active and de-selected OBACT */ { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - short changed = 0; + bool changed = false; Base *baspar, *basact = CTX_data_active_base(C); if (!basact || !(basact->object->parent)) return 0; /* we know OBACT is valid */ @@ -570,16 +570,16 @@ static short select_grouped_parent(bContext *C) /* Makes parent active and de-se ED_base_object_select(basact, BA_DESELECT); ED_base_object_select(baspar, BA_SELECT); ED_base_object_activate(C, baspar); - changed = 1; + changed = true; } return changed; } #define GROUP_MENU_MAX 24 -static short select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */ +static bool select_grouped_group(bContext *C, Object *ob) /* Select objects in the same group as the active */ { - short changed = 0; + bool changed = false; Group *group, *ob_groups[GROUP_MENU_MAX]; int group_count = 0, i; uiPopupMenu *pup; @@ -600,7 +600,7 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in { if (!(base->flag & SELECT) && BKE_group_object_exists(group, base->object)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; @@ -620,12 +620,12 @@ static short select_grouped_group(bContext *C, Object *ob) /* Select objects in return changed; /* The operator already handle this! */ } -static short select_grouped_object_hooks(bContext *C, Object *ob) +static bool select_grouped_object_hooks(bContext *C, Object *ob) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); - short changed = 0; + bool changed = false; Base *base; ModifierData *md; HookModifierData *hmd; @@ -637,7 +637,7 @@ static short select_grouped_object_hooks(bContext *C, Object *ob) base = BKE_scene_base_find(scene, hmd->object); if (base && (BASE_SELECTABLE(v3d, base))) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } } @@ -647,25 +647,25 @@ static short select_grouped_object_hooks(bContext *C, Object *ob) /* Select objects with the same parent as the active (siblings), * parent can be NULL also */ -static short select_grouped_siblings(bContext *C, Object *ob) +static bool select_grouped_siblings(bContext *C, Object *ob) { - short changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if ((base->object->parent == ob->parent) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_similar_lamps(bContext *C, Object *ob) +static bool select_similar_lamps(bContext *C, Object *ob) { Lamp *la = ob->data; - short changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { @@ -673,88 +673,88 @@ static short select_similar_lamps(bContext *C, Object *ob) Lamp *la_test = base->object->data; if ((la->type == la_test->type) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } } CTX_DATA_END; return changed; } -static short select_similar_pass_index(bContext *C, Object *ob) +static bool select_similar_pass_index(bContext *C, Object *ob) { - char changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if ((base->object->index == ob->index) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_grouped_type(bContext *C, Object *ob) +static bool select_grouped_type(bContext *C, Object *ob) { - short changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if ((base->object->type == ob->type) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_grouped_layer(bContext *C, Object *ob) +static bool select_grouped_layer(bContext *C, Object *ob) { - char changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if ((base->lay & ob->lay) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_grouped_index_object(bContext *C, Object *ob) +static bool select_grouped_index_object(bContext *C, Object *ob) { - char changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if ((base->object->index == ob->index) && !(base->flag & SELECT)) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_grouped_color(bContext *C, Object *ob) +static bool select_grouped_color(bContext *C, Object *ob) { - char changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if (!(base->flag & SELECT) && (compare_v3v3(base->object->col, ob->col, 0.005f))) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short objects_share_gameprop(Object *a, Object *b) +static bool objects_share_gameprop(Object *a, Object *b) { bProperty *prop; /*make a copy of all its properties*/ @@ -766,25 +766,25 @@ static short objects_share_gameprop(Object *a, Object *b) return 0; } -static short select_grouped_gameprops(bContext *C, Object *ob) +static bool select_grouped_gameprops(bContext *C, Object *ob) { - char changed = 0; + bool changed = false; CTX_DATA_BEGIN (C, Base *, base, selectable_bases) { if (!(base->flag & SELECT) && (objects_share_gameprop(base->object, ob))) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; } } CTX_DATA_END; return changed; } -static short select_grouped_keyingset(bContext *C, Object *UNUSED(ob)) +static bool select_grouped_keyingset(bContext *C, Object *UNUSED(ob)) { KeyingSet *ks = ANIM_scene_get_active_keyingset(CTX_data_scene(C)); - short changed = 0; + bool changed = false; /* firstly, validate KeyingSet */ if ((ks == NULL) || (ANIM_validate_keyingset(C, NULL, ks) != 0)) @@ -806,7 +806,7 @@ static short select_grouped_keyingset(bContext *C, Object *UNUSED(ob)) /* if id matches, select then stop looping (match found) */ if (ksp->id == (ID *)base->object) { ED_base_object_select(base, BA_SELECT); - changed = 1; + changed = true; break; } } @@ -822,7 +822,7 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob; int nr = RNA_enum_get(op->ptr, "type"); - short changed = 0, extend; + bool changed = false, extend; extend = RNA_boolean_get(op->ptr, "extend"); @@ -830,7 +830,7 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { ED_base_object_select(base, BA_DESELECT); - changed = 1; + changed = true; } CTX_DATA_END; } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 6be4a2fed2c..5d10d67f0c9 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -341,16 +341,16 @@ static int shape_key_remove_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); Object *ob = ED_object_context(C); - bool change = false; + bool changed = false; if (RNA_boolean_get(op->ptr, "all")) { - change = ED_object_shape_key_remove_all(bmain, ob); + changed = ED_object_shape_key_remove_all(bmain, ob); } else { - change = ED_object_shape_key_remove(bmain, ob); + changed = ED_object_shape_key_remove(bmain, ob); } - if (change) { + if (changed) { 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/object/object_transform.c b/source/blender/editors/object/object_transform.c index fef5ae392ea..63388600398 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -380,7 +380,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; - bool change = true; + bool changed = true; /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -391,14 +391,14 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo BKE_reportf(reports, RPT_ERROR, "Cannot apply to a multi user: Object \"%s\", %s \"%s\", aborting", ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2); - change = false; + changed = false; } if (obdata->lib) { BKE_reportf(reports, RPT_ERROR, "Cannot apply to library data: Object \"%s\", %s \"%s\", aborting", ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2); - change = false; + changed = false; } } @@ -412,22 +412,22 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo BKE_reportf(reports, RPT_ERROR, "Rotation/Location can't apply to a 2D curve: Object \"%s\", %s \"%s\", aborting", ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2); - change = false; + changed = false; } if (cu->key) { BKE_reportf(reports, RPT_ERROR, "Can't apply to a curve with shape-keys: Object \"%s\", %s \"%s\", aborting", ob->id.name + 2, BKE_idcode_to_name(GS(obdata->name)), obdata->name + 2); - change = false; + changed = false; } } } CTX_DATA_END; - if (!change) + if (!changed) return OPERATOR_CANCELLED; - change = false; + changed = false; /* now execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -592,11 +592,11 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA); - change = true; + changed = true; } CTX_DATA_END; - if (!change) { + if (!changed) { BKE_report(reports, RPT_WARNING, "Objects have no data to transform"); return OPERATOR_CANCELLED; } @@ -608,7 +608,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - int change = 0; + bool changed = false; CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { @@ -619,11 +619,11 @@ static int visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) /* update for any children that may get moved */ DAG_id_tag_update(&ob->id, OB_RECALC_OB); - change = 1; + changed = true; } CTX_DATA_END; - if (!change) + if (!changed) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 16ee400fa67..f6761aab42c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -2811,7 +2811,7 @@ static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformG { MDeformVert *dv; const int def_nr = BLI_findindex(&ob->defbase, dg); - bool change = false; + bool changed = false; if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -2830,7 +2830,7 @@ static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformG if (dv && dv->dw && (allverts || BM_elem_flag_test(eve, BM_ELEM_SELECT))) { MDeformWeight *dw = defvert_find_index(dv, def_nr); defvert_remove_group(dv, dw); /* dw can be NULL */ - change = true; + changed = true; } } } @@ -2848,7 +2848,7 @@ static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformG if (dv->dw && (allverts || (mv->flag & SELECT))) { MDeformWeight *dw = defvert_find_index(dv, def_nr); defvert_remove_group(dv, dw); /* dw can be NULL */ - change = true; + changed = true; } } } @@ -2870,13 +2870,13 @@ static bool vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformG dw = defvert_find_index(dv, def_nr); defvert_remove_group(dv, dw); /* dw can be NULL */ - change = true; + changed = true; } } } } - return change; + return changed; } static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *dg) @@ -3077,16 +3077,16 @@ static void vgroup_assign_verts(Object *ob, const float weight) /* removes from all defgroup, if allverts==0 only selected vertices */ static bool vgroup_remove_verts(Object *ob, int allverts) { - bool change = false; + bool changed = false; /* To prevent code redundancy, we just use vgroup_active_remove_verts, but that * only operates on the active vgroup. So we iterate through all groups, by changing * active group index */ bDeformGroup *dg; for (dg = ob->defbase.first; dg; dg = dg->next) { - change |= vgroup_active_remove_verts(ob, allverts, dg); + changed |= vgroup_active_remove_verts(ob, allverts, dg); } - return change; + return changed; } /********************** vertex group operators *********************/ @@ -3965,22 +3965,22 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { Object *obact = ED_object_context(C); - int change = 0; + int changed_tot = 0; int fail = 0; CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (obact != ob) { - if (ED_vgroup_array_copy(ob, obact)) change++; + if (ED_vgroup_array_copy(ob, obact)) changed_tot++; else fail++; } } CTX_DATA_END; - if ((change == 0 && fail == 0) || fail) { + if ((changed_tot == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, "Copy vertex groups to selected: %d done, %d failed (object data must have matching indices)", - change, fail); + changed_tot, fail); } return OPERATOR_FINISHED; @@ -4010,7 +4010,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) char dg_act_name[MAX_VGROUP_NAME]; /* may be freed so copy */ int fail = 0; - bool change = false; + bool changed = false; WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "group_select_mode"); WT_Method method = RNA_enum_get(op->ptr, "method"); @@ -4060,7 +4060,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } if (ed_vgroup_transfer_weight(ob_act, ob_src, dg_src, scene, method, replace_mode, op)) { - change = true; + changed = true; } else { fail++; @@ -4072,7 +4072,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) bDeformGroup *dg_src; for (dg_src = ob_src->defbase.first; dg_src; dg_src = dg_src->next) { if (ed_vgroup_transfer_weight(ob_act, ob_src, dg_src, scene, method, replace_mode, op)) { - change = true; + changed = true; } else { fail++; @@ -4088,7 +4088,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) } CTX_DATA_END; - if (change) { + if (changed) { /* possible the active vertex group changed because of adding/removing */ /* note!, dg_act may be realloc'd, only check its not NULL */ diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 65a3e5b558e..808c7cc3e82 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2978,7 +2978,7 @@ static void brush_puff(PEData *data, int point_index) 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; + bool changed = false; zero_v3(ofs_prev); @@ -3056,7 +3056,7 @@ static void brush_puff(PEData *data, int point_index) * keys that come after */ sub_v3_v3v3(ofs_prev, key->co, dco); } - change = true; + changed = true; } else { @@ -3116,7 +3116,7 @@ static void brush_puff(PEData *data, int point_index) } } - if (change) + if (changed) point->flag |= PEP_EDIT_RECALC; } diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c index 698d530c22d..00b9940121c 100644 --- a/source/blender/editors/physics/rigidbody_constraint.c +++ b/source/blender/editors/physics/rigidbody_constraint.c @@ -123,7 +123,7 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op) RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene); Object *ob = (scene) ? OBACT : NULL; int type = RNA_enum_get(op->ptr, "type"); - bool change; + bool changed; /* sanity checks */ if (ELEM(NULL, scene, rbw)) { @@ -131,9 +131,9 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* apply to active object */ - change = ED_rigidbody_constraint_add(scene, ob, type, op->reports); + changed = ED_rigidbody_constraint_add(scene, ob, type, op->reports); - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c index 00304090818..ae6af7c2e0b 100644 --- a/source/blender/editors/physics/rigidbody_object.c +++ b/source/blender/editors/physics/rigidbody_object.c @@ -145,12 +145,12 @@ static int rigidbody_object_add_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); int type = RNA_enum_get(op->ptr, "type"); - bool change; + bool changed; /* apply to active object */ - change = ED_rigidbody_object_add(scene, ob, type, op->reports); + changed = ED_rigidbody_object_add(scene, ob, type, op->reports); - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); @@ -187,15 +187,15 @@ static int rigidbody_object_remove_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Object *ob = ED_object_active_context(C); - bool change = false; + bool changed = false; /* apply to active object */ if (!ELEM(NULL, ob, ob->rigidbody_object)) { ED_rigidbody_object_remove(scene, ob); - change = true; + changed = true; } - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); @@ -233,15 +233,15 @@ static int rigidbody_objects_add_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); int type = RNA_enum_get(op->ptr, "type"); - bool change = false; + bool changed = false; /* create rigid body objects and add them to the world's group */ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) { - change |= ED_rigidbody_object_add(scene, ob, type, op->reports); + changed |= ED_rigidbody_object_add(scene, ob, type, op->reports); } CTX_DATA_END; - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); @@ -277,19 +277,19 @@ void RIGIDBODY_OT_objects_add(wmOperatorType *ot) static int rigidbody_objects_remove_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - bool change = false; + bool changed = false; /* apply this to all selected objects... */ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) { if (ob->rigidbody_object) { ED_rigidbody_object_remove(scene, ob); - change = true; + changed = true; } } CTX_DATA_END; - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); @@ -325,7 +325,7 @@ void RIGIDBODY_OT_objects_remove(wmOperatorType *ot) static int rigidbody_objects_shape_change_exec(bContext *C, wmOperator *op) { int shape = RNA_enum_get(op->ptr, "type"); - bool change = false; + bool changed = false; /* apply this to all selected objects... */ CTX_DATA_BEGIN(C, Object *, ob, selected_objects) @@ -339,12 +339,12 @@ static int rigidbody_objects_shape_change_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB); - change = true; + changed = true; } } CTX_DATA_END; - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); @@ -555,7 +555,7 @@ static int rigidbody_objects_calc_mass_exec(bContext *C, wmOperator *op) { int material = RNA_enum_get(op->ptr, "material"); float density; - bool change = false; + bool changed = false; /* get density (kg/m^3) to apply */ if (material >= 0) { @@ -592,12 +592,12 @@ static int rigidbody_objects_calc_mass_exec(bContext *C, wmOperator *op) DAG_id_tag_update(&ob->id, OB_RECALC_OB); - change = true; + changed = true; } } CTX_DATA_END; - if (change) { + if (changed) { /* send updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POINTCACHE, NULL); diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 71bf67220fe..e1a271e996b 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -677,7 +677,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even rj->v3d_override = true; if (v3d->localvd) - rj->lay_override = scene->lay | v3d->localvd->lay; + rj->lay_override |= v3d->localvd->lay; } /* setup job */ diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 2bf8a48edc4..081187ef1d8 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -358,13 +358,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre /* turn off bounce lights for volume, * doesn't make much visual difference and slows it down too */ - if (mat->material_type == MA_TYPE_VOLUME) { - for (base = sce->base.first; base; base = base->next) { - if (base->object->type == OB_LAMP) { - /* if doesn't match 'Lamp.002' --> main key light */ - if (strcmp(base->object->id.name + 2, "Lamp.002") != 0) { + for (base = sce->base.first; base; base = base->next) { + if (base->object->type == OB_LAMP) { + /* if doesn't match 'Lamp.002' --> main key light */ + if (strcmp(base->object->id.name + 2, "Lamp.002") != 0) { + if (mat->material_type == MA_TYPE_VOLUME) base->object->restrictflag |= OB_RESTRICT_RENDER; - } + else + base->object->restrictflag &= ~OB_RESTRICT_RENDER; } } } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index fccce0357a4..701abab804f 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -39,6 +39,8 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_alloca.h" +#include "BLI_linklist_stack.h" #include "BLF_translation.h" @@ -160,8 +162,8 @@ static void area_draw_azone(short x1, short y1, short x2, short y2) int dx = x2 - x1; int dy = y2 - y1; - dx = copysign(ceilf(0.3f * fabsf(dx)), dx); - dy = copysign(ceilf(0.3f * fabsf(dy)), dy); + dx = copysign(ceilf(0.3f * abs(dx)), dx); + dy = copysign(ceilf(0.3f * abs(dy)), dy); glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); @@ -859,10 +861,10 @@ static void region_azone_add(ScrArea *sa, ARegion *ar, int alignment) static int rct_fits(rcti *rect, char dir, int size) { if (dir == 'h') { - return BLI_rcti_size_x(rect) - size; + return BLI_rcti_size_x(rect) + 1 - size; } else { /* 'v' */ - return BLI_rcti_size_y(rect) - size; + return BLI_rcti_size_y(rect) + 1 - size; } } @@ -1157,16 +1159,16 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti static void area_calc_totrct(ScrArea *sa, int sizex, int sizey) { - short rt = U.pixelsize > 1.0f ? 1 : 0; + short rt = (short) U.pixelsize; - if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + 1 + rt; + if (sa->v1->vec.x > 0) sa->totrct.xmin = sa->v1->vec.x + rt; else sa->totrct.xmin = sa->v1->vec.x; - if (sa->v4->vec.x < sizex - 1) sa->totrct.xmax = sa->v4->vec.x - 1 - rt; + if (sa->v4->vec.x < sizex - 1) sa->totrct.xmax = sa->v4->vec.x - rt; else sa->totrct.xmax = sa->v4->vec.x; - if (sa->v1->vec.y > 0) sa->totrct.ymin = sa->v1->vec.y + 1 + rt; + if (sa->v1->vec.y > 0) sa->totrct.ymin = sa->v1->vec.y + rt; else sa->totrct.ymin = sa->v1->vec.y; - if (sa->v2->vec.y < sizey - 1) sa->totrct.ymax = sa->v2->vec.y - 1 - rt; + if (sa->v2->vec.y < sizey - 1) sa->totrct.ymax = sa->v2->vec.y - rt; else sa->totrct.ymax = sa->v2->vec.y; /* for speedup */ @@ -1566,12 +1568,15 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * Panel *panel; View2D *v2d = &ar->v2d; View2DScrollers *scrollers; - int x, y, xco, yco, w, em, triangle, open, newcontext = 0; + int x, y, xco, yco, w, em, triangle, open; + bool is_context_new = 0; int redo; int scroll; + BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *); + if (contextnr >= 0) - newcontext = UI_view2d_tab_set(v2d, contextnr); + is_context_new = UI_view2d_tab_set(v2d, contextnr); /* before setting the view */ if (vertical) { @@ -1591,7 +1596,22 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } scroll = v2d->scroll; - + + + /* collect panels to draw */ + for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) { + /* verify context */ + if (context && pt->context[0] && !STREQ(context, pt->context)) { + continue; + } + + /* draw panel */ + if (pt->draw && (!pt->poll || pt->poll(C, pt))) { + BLI_SMALLSTACK_PUSH(pt_stack, pt); + } + } + + /* sortof hack - but we cannot predict the height of panels, until it's being generated */ /* the layout engine works with fixed width (from v2d->cur), which is being set at end of the loop */ /* in case scroller settings (hide flags) differ from previous, the whole loop gets done again */ @@ -1612,63 +1632,57 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * /* set view2d view matrix - uiBeginBlock() stores it */ UI_view2d_view_ortho(v2d); - for (pt = ar->type->paneltypes.first; pt; pt = pt->next) { - /* verify context */ - if (context) - if (pt->context[0] && strcmp(context, pt->context) != 0) - continue; + BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt) + { + block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); + panel = uiBeginPanel(sa, ar, block, pt, &open); - /* draw panel */ - if (pt->draw && (!pt->poll || pt->poll(C, pt))) { - block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - panel = uiBeginPanel(sa, ar, block, pt, &open); + /* bad fixed values */ + triangle = (int)(UI_UNIT_Y * 1.1f); - /* bad fixed values */ - triangle = (int)(UI_UNIT_Y * 1.1f); + if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + /* for enabled buttons */ + panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, + triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); - if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { - /* for enabled buttons */ - panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); + pt->draw_header(C, panel); - pt->draw_header(C, panel); + uiBlockLayoutResolve(block, &xco, &yco); + panel->labelofs = xco - triangle; + panel->layout = NULL; + } + else { + panel->labelofs = 0; + } - uiBlockLayoutResolve(block, &xco, &yco); - panel->labelofs = xco - triangle; - panel->layout = NULL; - } - else { - panel->labelofs = 0; - } + if (open) { + short panelContext; - if (open) { - short panelContext; - - /* panel context can either be toolbar region or normal panels region */ - if (ar->regiontype == RGN_TYPE_TOOLS) - panelContext = UI_LAYOUT_TOOLBAR; - else - panelContext = UI_LAYOUT_PANEL; - - panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext, - style->panelspace, 0, w - 2 * style->panelspace, em, style); - - pt->draw(C, panel); - - uiBlockLayoutResolve(block, &xco, &yco); - panel->layout = NULL; - - yco -= 2 * style->panelspace; - uiEndPanel(block, w, -yco); - } - else { - yco = 0; - uiEndPanel(block, w, 0); - } + /* panel context can either be toolbar region or normal panels region */ + if (ar->regiontype == RGN_TYPE_TOOLS) + panelContext = UI_LAYOUT_TOOLBAR; + else + panelContext = UI_LAYOUT_PANEL; - uiEndBlock(C, block); + panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext, + style->panelspace, 0, w - 2 * style->panelspace, em, style); + + pt->draw(C, panel); + + uiBlockLayoutResolve(block, &xco, &yco); + panel->layout = NULL; + + yco -= 2 * style->panelspace; + uiEndPanel(block, w, -yco); } + else { + yco = 0; + uiEndPanel(block, w, 0); + } + + uiEndBlock(C, block); } + BLI_SMALLSTACK_ITER_END; /* align panels and return size */ uiEndPanels(C, ar, &x, &y); @@ -1683,7 +1697,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } else { /* don't jump back when panels close or hide */ - if (!newcontext) + if (!is_context_new) x = max_ii(x, v2d->cur.xmax); y = -y; } @@ -1705,6 +1719,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } } + BLI_SMALLSTACK_FREE(pt_stack); /* clear */ if (ar->overlap) { @@ -1824,7 +1839,7 @@ void ED_region_info_draw(ARegion *ar, const char *text, int block, float fill_co /* box fill entire width or just around text */ if (!block) - rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, text) + 1.2f * U.widget_unit); + rect.xmax = min_ii(rect.xmax, rect.xmin + BLF_width(fontid, text, BLF_DRAW_STR_DUMMY_MAX) + 1.2f * U.widget_unit); rect.ymax = BLI_rcti_size_y(&ar->winrct); diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index d356c3d8de3..57d97178be5 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -143,7 +143,7 @@ void fdrawbezier(float vec[4][3]) float dist; float curve_res = 24, spline_step = 0.0f; - dist = 0.5f * ABS(vec[0][0] - vec[3][0]); + dist = 0.5f * fabsf(vec[0][0] - vec[3][0]); /* check direction later, for top sockets */ vec[1][0] = vec[0][0] + dist; @@ -981,7 +981,9 @@ void bgl_get_mats(bglMats *mats) /* *************** glPolygonOffset hack ************* */ -/* dist is only for ortho now... */ +/** + * \note \a viewdist is only for ortho at the moment. + */ void bglPolygonOffset(float viewdist, float dist) { static float winmat[16], offset = 0.0; @@ -1157,3 +1159,10 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int glaDrawImBuf_glsl(ibuf, x, y, zoomfilter, view_settings, display_settings); } + +void cpack(unsigned int x) +{ + glColor3ub( ( (x) & 0xFF), + (((x) >> 8) & 0xFF), + (((x) >> 16) & 0xFF) ); +} diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 356db174c2f..61d28a45fac 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -264,7 +264,10 @@ int scredge_is_horizontal(ScrEdge *se) return (se->v1->vec.y == se->v2->vec.y); } -ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) +/* need win size to make sure not to include edges along screen edge */ +ScrEdge *screen_find_active_scredge(bScreen *sc, + const int winsize_x, const int winsize_y, + const int mx, const int my) { ScrEdge *se; int safety = U.widget_unit / 10; @@ -273,20 +276,24 @@ ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my) for (se = sc->edgebase.first; se; se = se->next) { if (scredge_is_horizontal(se)) { - short min, max; - min = MIN2(se->v1->vec.x, se->v2->vec.x); - max = MAX2(se->v1->vec.x, se->v2->vec.x); - - if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) - return se; + if (se->v1->vec.y > 0 && se->v1->vec.y < winsize_y - 1) { + short min, max; + min = MIN2(se->v1->vec.x, se->v2->vec.x); + max = MAX2(se->v1->vec.x, se->v2->vec.x); + + if (abs(my - se->v1->vec.y) <= safety && mx >= min && mx <= max) + return se; + } } else { - short min, max; - min = MIN2(se->v1->vec.y, se->v2->vec.y); - max = MAX2(se->v1->vec.y, se->v2->vec.y); - - if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) - return se; + if (se->v1->vec.x > 0 && se->v1->vec.x < winsize_x - 1) { + short min, max; + min = MIN2(se->v1->vec.y, se->v2->vec.y); + max = MAX2(se->v1->vec.y, se->v2->vec.y); + + if (abs(mx - se->v1->vec.x) <= safety && my >= min && my <= max) + return se; + } } } @@ -453,6 +460,9 @@ ScrArea *area_split(bScreen *sc, ScrArea *sa, char dir, float fac, int merge) /* uses window size */ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name) { + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + bScreen *sc; ScrVert *sv1, *sv2, *sv3, *sv4; @@ -463,9 +473,9 @@ bScreen *ED_screen_add(wmWindow *win, Scene *scene, const char *name) sc->winid = win->winid; sv1 = screen_addvert(sc, 0, 0); - sv2 = screen_addvert(sc, 0, WM_window_pixels_y(win) - 1); - sv3 = screen_addvert(sc, WM_window_pixels_x(win) - 1, WM_window_pixels_y(win) - 1); - sv4 = screen_addvert(sc, WM_window_pixels_x(win) - 1, 0); + sv2 = screen_addvert(sc, 0, winsize_y - 1); + sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1); + sv4 = screen_addvert(sc, winsize_x - 1, 0); screen_addedge(sc, sv1, sv2); screen_addedge(sc, sv2, sv3); @@ -655,11 +665,16 @@ void select_connected_scredge(bScreen *sc, ScrEdge *edge) } /* test if screen vertices should be scaled */ -static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) +static void screen_test_scale(bScreen *sc, int winsize_x, int winsize_y) { + /* clamp Y size of header sized areas when expanding windows + * avoids annoying empty space around file menu */ +#define USE_HEADER_SIZE_CLAMP + + const int headery_init = ED_area_headersize(); ScrVert *sv = NULL; ScrArea *sa; - int sizex, sizey; + int winsize_x_prev, winsize_y_prev; float facx, facy, tempf, min[2], max[2]; /* calculate size */ @@ -677,14 +692,41 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) sv->vec.y -= min[1]; } - sizex = max[0] - min[0]; - sizey = max[1] - min[1]; - - if (sizex != winsizex || sizey != winsizey) { - facx = winsizex; - facx /= (float)sizex; - facy = winsizey; - facy /= (float)sizey; + winsize_x_prev = (max[0] - min[0]) + 1; + winsize_y_prev = (max[1] - min[1]) + 1; + + +#ifdef USE_HEADER_SIZE_CLAMP +#define TEMP_BOTTOM 1 +#define TEMP_TOP 2 + + /* if the window's Y axis grows, clamp header sized areas */ + if (winsize_y_prev < winsize_y) { /* growing? */ + const int headery_margin_max = headery_init + 4; + for (sa = sc->areabase.first; sa; sa = sa->next) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + sa->temp = 0; + + if (ar && !(ar->flag & RGN_FLAG_HIDDEN)) { + if (sa->v2->vec.y == winsize_y_prev - 1) { + if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) { + sa->temp = TEMP_TOP; + } + } + else if (sa->v1->vec.y == 0) { + if ((sa->v2->vec.y - sa->v1->vec.y) < headery_margin_max) { + sa->temp = TEMP_BOTTOM; + } + } + } + } + } +#endif + + + if (winsize_x_prev != winsize_x || winsize_y_prev != winsize_y) { + facx = ((float)winsize_x) / ((float)winsize_x_prev - 1); + facy = ((float)winsize_y) / ((float)winsize_y_prev - 1); /* make sure it fits! */ for (sv = sc->vertbase.first; sv; sv = sv->next) { @@ -695,25 +737,79 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) //sv->vec.x += AREAGRID - 1; //sv->vec.x -= (sv->vec.x % AREAGRID); - CLAMP(sv->vec.x, 0, winsizex); + CLAMP(sv->vec.x, 0, winsize_x - 1); tempf = ((float)sv->vec.y) * facy; sv->vec.y = (short)(tempf + 0.5f); //sv->vec.y += AREAGRID - 1; //sv->vec.y -= (sv->vec.y % AREAGRID); - CLAMP(sv->vec.y, 0, winsizey); + CLAMP(sv->vec.y, 0, winsize_y - 1); } } - + + +#ifdef USE_HEADER_SIZE_CLAMP + if (winsize_y_prev < winsize_y) { /* growing? */ + for (sa = sc->areabase.first; sa; sa = sa->next) { + ScrEdge *se = NULL; + + if (sa->temp == 0) + continue; + + if (sa->v1 == sa->v2) + continue; + + /* adjust headery if verts are along the edge of window */ + if (sa->temp == TEMP_TOP) { + /* lower edge */ + const int yval = sa->v2->vec.y - headery_init; + se = screen_findedge(sc, sa->v4, sa->v1); + select_connected_scredge(sc, se); + for (sv = sc->vertbase.first; sv; sv = sv->next) { + if (sv != sa->v2 && sv != sa->v3) { + if (sv->flag) { + sv->vec.y = yval; + } + } + } + } + else { + /* upper edge */ + const int yval = sa->v1->vec.y + headery_init; + se = screen_findedge(sc, sa->v2, sa->v3); + select_connected_scredge(sc, se); + for (sv = sc->vertbase.first; sv; sv = sv->next) { + if (sv != sa->v1 && sv != sa->v4) { + if (sv->flag) { + sv->vec.y = yval; + } + } + } + } + } + } + +#undef USE_HEADER_SIZE_CLAMP +#undef TEMP_BOTTOM +#undef TEMP_TOP +#endif + + /* test for collapsed areas. This could happen in some blender version... */ /* ton: removed option now, it needs Context... */ /* make each window at least ED_area_headersize() high */ for (sa = sc->areabase.first; sa; sa = sa->next) { - int headery = ED_area_headersize() + U.pixelsize; + int headery = headery_init; + + /* adjust headery if verts are along the edge of window */ + if (sa->v1->vec.y > 0) + headery += U.pixelsize; + if (sa->v2->vec.y < winsize_y - 1) + headery += U.pixelsize; - if (sa->v1->vec.y + headery > sa->v2->vec.y) { + if (sa->v2->vec.y - sa->v1->vec.y + 1 < headery) { /* lower edge */ ScrEdge *se = screen_findedge(sc, sa->v4, sa->v1); if (se && sa->v1 != sa->v2) { @@ -722,14 +818,14 @@ static void screen_test_scale(bScreen *sc, int winsizex, int winsizey) select_connected_scredge(sc, se); /* all selected vertices get the right offset */ - yval = sa->v2->vec.y - headery; - sv = sc->vertbase.first; - while (sv) { + yval = sa->v2->vec.y - headery + 1; + for (sv = sc->vertbase.first; sv; sv = sv->next) { /* if is a collapsed area */ if (sv != sa->v2 && sv != sa->v3) { - if (sv->flag) sv->vec.y = yval; + if (sv->flag) { + sv->vec.y = yval; + } } - sv = sv->next; } } } @@ -947,7 +1043,7 @@ static void drawscredge_area(ScrArea *sa, int sizex, int sizey, int center) if (U.pixelsize > 1.0f) { glColor3ub(0x50, 0x50, 0x50); - glLineWidth(1.5f * U.pixelsize); + glLineWidth((2.0f * U.pixelsize) - 1); drawscredge_area_draw(sizex, sizey, x1, y1, x2, y2, 0); glLineWidth(1.0f); } @@ -1022,6 +1118,9 @@ void ED_screen_do_listen(bContext *C, wmNotifier *note) /* only for edge lines between areas, and the blended join arrows */ void ED_screen_draw(wmWindow *win) { + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + ScrArea *sa; ScrArea *sa1 = NULL; ScrArea *sa2 = NULL; @@ -1035,10 +1134,10 @@ void ED_screen_draw(wmWindow *win) if (sa->flag & AREA_FLAG_DRAWJOINFROM) sa1 = sa; if (sa->flag & AREA_FLAG_DRAWJOINTO) sa2 = sa; if (sa->flag & (AREA_FLAG_DRAWSPLIT_H | AREA_FLAG_DRAWSPLIT_V)) sa3 = sa; - drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 0); + drawscredge_area(sa, winsize_x, winsize_y, 0); } for (sa = win->screen->areabase.first; sa; sa = sa->next) - drawscredge_area(sa, WM_window_pixels_x(win), WM_window_pixels_y(win), 1); + drawscredge_area(sa, winsize_x, winsize_y, 1); /* blended join arrow */ if (sa1 && sa2) { @@ -1107,18 +1206,20 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) { /* exception for bg mode, we only need the screen context */ if (!G.background) { + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); ScrArea *sa; rcti winrct; winrct.xmin = 0; - winrct.xmax = WM_window_pixels_x(win) - 1; + winrct.xmax = winsize_x - 1; winrct.ymin = 0; - winrct.ymax = WM_window_pixels_y(win) - 1; + winrct.ymax = winsize_y - 1; /* header size depends on DPI, let's verify */ screen_refresh_headersizes(); - screen_test_scale(win->screen, WM_window_pixels_x(win), WM_window_pixels_y(win)); + screen_test_scale(win->screen, winsize_x, winsize_y); if (win->screen->mainwin == 0) win->screen->mainwin = wm_subwindow_open(win, &winrct); @@ -1133,7 +1234,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win) /* wake up animtimer */ if (win->screen->animtimer) - WM_event_timer_sleep(wm, win, win->screen->animtimer, 0); + WM_event_timer_sleep(wm, win, win->screen->animtimer, false); } if (G.debug & G_DEBUG_EVENTS) { @@ -1245,6 +1346,9 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen) /* case when on area-edge or in azones, or outside window */ static void screen_cursor_set(wmWindow *win, wmEvent *event) { + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + AZone *az = NULL; ScrArea *sa; @@ -1263,7 +1367,7 @@ static void screen_cursor_set(wmWindow *win, wmEvent *event) } } else { - ScrEdge *actedge = screen_find_active_scredge(win->screen, event->x, event->y); + ScrEdge *actedge = screen_find_active_scredge(win->screen, winsize_x, winsize_y, event->x, event->y); if (actedge) { if (scredge_is_horizontal(actedge)) @@ -1410,7 +1514,7 @@ void ED_screen_set(bContext *C, bScreen *sc) /* we put timer to sleep, so screen_exit has to think there's no timer */ oldscreen->animtimer = NULL; if (wt) - WM_event_timer_sleep(wm, win, wt, 1); + WM_event_timer_sleep(wm, win, wt, true); ED_screen_exit(C, win, oldscreen); oldscreen->animtimer = wt; diff --git a/source/blender/editors/screen/screen_intern.h b/source/blender/editors/screen/screen_intern.h index b811fc46188..66677aed68f 100644 --- a/source/blender/editors/screen/screen_intern.h +++ b/source/blender/editors/screen/screen_intern.h @@ -53,7 +53,9 @@ void removedouble_scrverts(bScreen *sc); void removedouble_scredges(bScreen *sc); void removenotused_scredges(bScreen *sc); int scredge_is_horizontal(ScrEdge *se); -ScrEdge *screen_find_active_scredge(bScreen *sc, int mx, int my); +ScrEdge *screen_find_active_scredge(bScreen *sc, + const int winsize_x, const int winsize_y, + const int mx, const int my); struct AZone *is_in_area_actionzone(ScrArea *sa, const int xy[2]); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 93923c24c84..b5d7030ef82 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -695,8 +695,12 @@ static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event) static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) { + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); sActionzoneData *sad = op->customdata; - + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + switch (event->type) { case MOUSEMOVE: { @@ -719,7 +723,7 @@ static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event) /* once we drag outside the actionzone, register a gesture * check we're not on an edge so join finds the other area */ is_gesture = ((is_in_area_actionzone(sad->sa1, &event->x) != sad->az) && - (screen_find_active_scredge(CTX_wm_screen(C), event->x, event->y) == NULL)); + (screen_find_active_scredge(sc, winsize_x, winsize_y, event->x, event->y) == NULL)); } else { const int delta_min = 1; @@ -988,18 +992,30 @@ typedef struct sAreaMoveData { char dir; } sAreaMoveData; -/* helper call to move area-edge, sets limits */ -static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller) +/* helper call to move area-edge, sets limits + * need window size in order to get correct limits */ +static void area_move_set_limits(bScreen *sc, int dir, + const int winsize_x, const int winsize_y, + int *bigger, int *smaller) { ScrArea *sa; - int areaminy = ED_area_headersize() + U.pixelsize; // pixelsize is used as area divider + int areaminy = ED_area_headersize(); + int areamin; /* we check all areas and test for free space with MINSIZE */ *bigger = *smaller = 100000; for (sa = sc->areabase.first; sa; sa = sa->next) { if (dir == 'h') { - int y1 = sa->v2->vec.y - sa->v1->vec.y - areaminy; + int y1; + areamin = areaminy; + + if (sa->v1->vec.y > 0) + areamin += U.pixelsize; + if (sa->v2->vec.y < winsize_y - 1) + areamin += U.pixelsize; + + y1 = sa->v2->vec.y - sa->v1->vec.y + 1 - areamin; /* if top or down edge selected, test height */ if (sa->v1->editflag && sa->v4->editflag) @@ -1008,7 +1024,15 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller *smaller = min_ii(*smaller, y1); } else { - int x1 = sa->v4->vec.x - sa->v1->vec.x - AREAMINX; + int x1; + areamin = AREAMINX; + + if (sa->v1->vec.x > 0) + areamin += U.pixelsize; + if (sa->v4->vec.x < winsize_x - 1) + areamin += U.pixelsize; + + x1 = sa->v4->vec.x - sa->v1->vec.x + 1 - areamin; /* if left or right edge selected, test width */ if (sa->v1->editflag && sa->v2->editflag) @@ -1024,9 +1048,12 @@ static void area_move_set_limits(bScreen *sc, int dir, int *bigger, int *smaller static int area_move_init(bContext *C, wmOperator *op) { bScreen *sc = CTX_wm_screen(C); + wmWindow *win = CTX_wm_window(C); ScrEdge *actedge; sAreaMoveData *md; ScrVert *v1; + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); int x, y; /* required properties */ @@ -1034,7 +1061,7 @@ static int area_move_init(bContext *C, wmOperator *op) y = RNA_int_get(op->ptr, "y"); /* setup */ - actedge = screen_find_active_scredge(sc, x, y); + actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, x, y); if (actedge == NULL) return 0; md = MEM_callocN(sizeof(sAreaMoveData), "sAreaMoveData"); @@ -1049,7 +1076,7 @@ static int area_move_init(bContext *C, wmOperator *op) for (v1 = sc->vertbase.first; v1; v1 = v1->next) v1->editflag = v1->flag; - area_move_set_limits(sc, md->dir, &md->bigger, &md->smaller); + area_move_set_limits(sc, md->dir, winsize_x, winsize_y, &md->bigger, &md->smaller); return 1; } @@ -1058,39 +1085,53 @@ static int area_move_init(bContext *C, wmOperator *op) static void area_move_apply_do(bContext *C, int origval, int delta, int dir, int bigger, int smaller) { wmWindow *win = CTX_wm_window(C); + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); bScreen *sc = CTX_wm_screen(C); ScrVert *v1; ScrArea *sa; - int areaminy = ED_area_headersize() + 1; + int doredraw = 0; + int oldval; delta = CLAMPIS(delta, -smaller, bigger); for (v1 = sc->vertbase.first; v1; v1 = v1->next) { if (v1->editflag) { /* that way a nice AREAGRID */ - if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < WM_window_pixels_x(win) - 1) { + if ((dir == 'v') && v1->vec.x > 0 && v1->vec.x < winsize_x - 1) { + oldval = v1->vec.x; v1->vec.x = origval + delta; - if (delta != bigger && delta != -smaller) v1->vec.x -= (v1->vec.x % AREAGRID); + + if (delta != bigger && delta != -smaller) { + v1->vec.x -= (v1->vec.x % AREAGRID); + v1->vec.x = CLAMPIS(v1->vec.x, origval - smaller, origval + bigger); + } + if (oldval != v1->vec.x) + doredraw = 1; } - if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < WM_window_pixels_y(win) - 1) { + if ((dir == 'h') && v1->vec.y > 0 && v1->vec.y < winsize_y - 1) { + oldval = v1->vec.y; v1->vec.y = origval + delta; - v1->vec.y += AREAGRID - 1; - v1->vec.y -= (v1->vec.y % AREAGRID); - - /* prevent too small top header */ - if (v1->vec.y > WM_window_pixels_y(win) - areaminy) - v1->vec.y = WM_window_pixels_y(win) - areaminy; + if (delta != bigger && delta != smaller) { + v1->vec.y -= (v1->vec.y % AREAGRID); + v1->vec.y = CLAMPIS(v1->vec.y, origval - smaller, origval + bigger); + } + if (oldval != v1->vec.y) + doredraw = 1; } } } - for (sa = sc->areabase.first; sa; sa = sa->next) { - if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) - ED_area_tag_redraw(sa); - } + /* only redraw if we actually moved a screen vert, for AREAGRID */ + if (doredraw) { + for (sa = sc->areabase.first; sa; sa = sa->next) { + if (sa->v1->editflag || sa->v2->editflag || sa->v3->editflag || sa->v4->editflag) + ED_area_tag_redraw(sa); + } - WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ + WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL); /* redraw everything */ + } } static void area_move_apply(bContext *C, wmOperator *op) @@ -1410,11 +1451,15 @@ static void area_split_exit(bContext *C, wmOperator *op) /* UI callback, adds new handler */ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); sAreaSplitData *sd; + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); int dir; /* no full window splitting allowed */ - if (CTX_wm_screen(C)->full != SCREENNORMAL) + if (sc->full != SCREENNORMAL) return OPERATOR_CANCELLED; if (event->type == EVT_ACTIONZONE_AREA) { @@ -1463,7 +1508,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) else y = event->x; - actedge = screen_find_active_scredge(CTX_wm_screen(C), x, y); + actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, x, y); if (actedge == NULL) return OPERATOR_CANCELLED; @@ -1486,7 +1531,7 @@ static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* do the split */ if (area_split_apply(C, op)) { - area_move_set_limits(CTX_wm_screen(C), dir, &sd->bigger, &sd->smaller); + area_move_set_limits(sc, dir, winsize_x, winsize_y, &sd->bigger, &sd->smaller); /* add temp handler for edge move or cancel */ WM_event_add_modal_handler(C, op); @@ -2574,10 +2619,16 @@ static void SCREEN_OT_area_join(wmOperatorType *ot) static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + wmWindow *win = CTX_wm_window(C); + bScreen *sc = CTX_wm_screen(C); uiPopupMenu *pup; uiLayout *layout; PointerRNA ptr1, ptr2; - ScrEdge *actedge = screen_find_active_scredge(CTX_wm_screen(C), event->x, event->y); + ScrEdge *actedge; + const int winsize_x = WM_window_pixels_x(win); + const int winsize_y = WM_window_pixels_y(win); + + actedge = screen_find_active_scredge(sc, winsize_x, winsize_y, event->x, event->y); if (actedge == NULL) return OPERATOR_CANCELLED; @@ -2878,7 +2929,6 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot) ot->idname = "SCREEN_OT_region_quadview"; /* api callbacks */ - // ot->invoke = WM_operator_confirm; ot->exec = region_quadview_exec; ot->poll = ED_operator_region_view3d_active; ot->flag = 0; @@ -3556,9 +3606,6 @@ static void SCREEN_OT_new(wmOperatorType *ot) /* api callbacks */ ot->exec = screen_new_exec; ot->poll = WM_operator_winactive; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /********************* delete screen operator *********************/ @@ -3575,15 +3622,12 @@ static int screen_delete_exec(bContext *C, wmOperator *UNUSED(op)) static void SCREEN_OT_delete(wmOperatorType *ot) { /* identifiers */ - ot->name = "Delete Screen"; /* was scene */ + ot->name = "Delete Screen"; ot->description = "Delete active screen"; ot->idname = "SCREEN_OT_delete"; /* api callbacks */ ot->exec = screen_delete_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /********************* new scene operator *********************/ @@ -4032,12 +4076,6 @@ void ED_keymap_screen(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "SCREEN_OT_keyframe_jump", MEDIAFIRST, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "next", FALSE); - kmi = WM_keymap_add_item(keymap, "SCREEN_OT_marker_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "next", TRUE); - - kmi = WM_keymap_add_item(keymap, "SCREEN_OT_marker_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - RNA_boolean_set(kmi->ptr, "next", FALSE); - /* play (forward and backwards) */ WM_keymap_add_item(keymap, "SCREEN_OT_animation_play", AKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 56143d00afe..8f4454eb2da 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -569,7 +569,7 @@ static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush, glTranslatef(-0.5f, -0.5f, 0); /* scale based on tablet pressure */ - if (primary && ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) { + if (primary && ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { glTranslatef(0.5f, 0.5f, 0); glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1); glTranslatef(-0.5f, -0.5f, 0); @@ -694,7 +694,7 @@ static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush, } /* scale based on tablet pressure */ - if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) { + if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) { do_pop = true; glPushMatrix(); glLoadIdentity(); @@ -788,7 +788,7 @@ static void paint_cursor_on_hit(UnifiedPaintSettings *ups, Brush *brush, ViewCon projected_radius); /* scale 3D brush radius by pressure */ - if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) + if (ups->stroke_active && BKE_brush_use_size_pressure(vc->scene, brush)) unprojected_radius *= ups->pressure_value; /* set cached value in either Brush or UnifiedPaintSettings */ @@ -828,11 +828,10 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) outline_col = brush->add_col; final_radius = BKE_brush_size_get(scene, brush) * zoomx; - if (brush->flag & BRUSH_RAKE) - /* here, translation contains the mouse coordinates. */ + /* don't calculate rake angles while a stroke is active because the rake variables are global and + * we may get interference with the stroke itself. For line strokes, such interference is visible */ + if (!ups->stroke_active && (brush->flag & BRUSH_RAKE)) paint_calculate_rake_rotation(ups, translation); - else if (!(brush->flag & BRUSH_ANCHORED)) - ups->brush_rotation = 0.0; /* draw overlay */ paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode); @@ -883,7 +882,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) glTranslatef(translation[0], translation[1], 0); /* draw an inner brush */ - if (ups->draw_pressure && BKE_brush_use_size_pressure(scene, brush)) { + if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) { /* inner at full alpha */ glutil_draw_lined_arc(0.0, M_PI * 2.0, final_radius * ups->pressure_value, 40); /* outer at half alpha */ diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 345db7a0ed0..0eb019afbf7 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -100,7 +100,8 @@ static void partialvis_update_mesh(Object *ob, MVert *mvert; float *paint_mask; int *vert_indices; - int any_changed = 0, any_visible = 0, totvert, i; + int totvert, i; + bool any_changed = false, any_visible = false; BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert); BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert); @@ -118,11 +119,11 @@ static void partialvis_update_mesh(Object *ob, v->flag |= ME_HIDE; else v->flag &= ~ME_HIDE; - any_changed = 1; + any_changed = true; } if (!(v->flag & ME_HIDE)) - any_visible = 1; + any_visible = true; } if (any_changed) { @@ -143,8 +144,9 @@ static void partialvis_update_grids(Object *ob, CCGElem **grids; CCGKey key; BLI_bitmap **grid_hidden; - int any_visible = 0; - int *grid_indices, totgrid, any_changed, i; + int *grid_indices, totgrid, i; + bool any_changed = false, any_visible = false; + /* get PBVH data */ BKE_pbvh_node_get_grids(pbvh, node, @@ -154,8 +156,7 @@ static void partialvis_update_grids(Object *ob, BKE_pbvh_get_grid_key(pbvh, &key); sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); - - any_changed = 0; + for (i = 0; i < totgrid; i++) { int any_hidden = 0; int g = grid_indices[i], x, y; @@ -178,8 +179,8 @@ static void partialvis_update_grids(Object *ob, * grid */ MEM_freeN(gh); grid_hidden[g] = NULL; - any_changed = 1; - any_visible = 1; + any_changed = true; + any_visible = true; continue; } @@ -195,14 +196,14 @@ static void partialvis_update_grids(Object *ob, BLI_BITMAP_MODIFY(gh, y * key.grid_size + x, action == PARTIALVIS_HIDE); - any_changed = 1; + any_changed = true; } /* keep track of whether any elements are still hidden */ if (BLI_BITMAP_GET(gh, y * key.grid_size + x)) - any_hidden = 1; + any_hidden = true; else - any_visible = 1; + any_visible = true; } } @@ -227,8 +228,8 @@ static void partialvis_update_bmesh_verts(BMesh *bm, PartialVisAction action, PartialVisArea area, float planes[4][4], - int *any_changed, - int *any_visible) + bool *any_changed, + bool *any_visible) { GSetIterator gs_iter; @@ -244,24 +245,24 @@ static void partialvis_update_bmesh_verts(BMesh *bm, BM_elem_flag_enable(v, BM_ELEM_HIDDEN); else BM_elem_flag_disable(v, BM_ELEM_HIDDEN); - (*any_changed) = TRUE; + (*any_changed) = true; } if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) - (*any_visible) = TRUE; + (*any_visible) = true; } } static void partialvis_update_bmesh(Object *ob, - PBVH *pbvh, - PBVHNode *node, - PartialVisAction action, - PartialVisArea area, - float planes[4][4]) + PBVH *pbvh, + PBVHNode *node, + PartialVisAction action, + PartialVisArea area, + float planes[4][4]) { BMesh *bm; GSet *unique, *other; - int any_changed = 0, any_visible = 0; + bool any_changed = false, any_visible = false; bm = BKE_pbvh_get_bmesh(pbvh); unique = BKE_pbvh_bmesh_node_unique_verts(node); @@ -270,20 +271,20 @@ static void partialvis_update_bmesh(Object *ob, sculpt_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); partialvis_update_bmesh_verts(bm, - unique, - action, - area, - planes, - &any_changed, - &any_visible); + unique, + action, + area, + planes, + &any_changed, + &any_visible); partialvis_update_bmesh_verts(bm, - other, - action, - area, - planes, - &any_changed, - &any_visible); + other, + action, + area, + planes, + &any_changed, + &any_visible); if (any_changed) { BKE_pbvh_node_mark_rebuild_draw(node); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 003db8a9c43..47ca3e5ce0c 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -238,7 +238,7 @@ void image_undo_remove_masks(void) } } -void image_undo_restore(bContext *C, ListBase *lb) +void ED_image_undo_restore(bContext *C, ListBase *lb) { Main *bmain = CTX_data_main(C); Image *ima = NULL; @@ -304,7 +304,7 @@ void image_undo_restore(bContext *C, ListBase *lb) IMB_freeImBuf(tmpibuf); } -void image_undo_free(ListBase *lb) +void ED_image_undo_free(ListBase *lb) { UndoImageTile *tile; @@ -314,7 +314,7 @@ void image_undo_free(ListBase *lb) /* Imagepaint Partial Redraw & Dirty Region */ -void imapaint_clear_partial_redraw(void) +void ED_imapaint_clear_partial_redraw(void) { memset(&imapaintpartial, 0, sizeof(imapaintpartial)); } @@ -331,7 +331,7 @@ void imapaint_region_tiles(ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty = (y >> IMAPAINT_TILE_BITS); } -void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h) +void ED_imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h) { ImBuf *tmpibuf = NULL; int tilex, tiley, tilew, tileh, tx, ty; @@ -506,12 +506,12 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, float mou } settings->imapaint.flag |= IMAGEPAINT_DRAWING; - undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, - image_undo_restore, image_undo_free); + ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, + ED_image_undo_restore, ED_image_undo_free); { UnifiedPaintSettings *ups = &settings->unified_paint_settings; - ups->draw_pressure = true; + ups->stroke_active = true; } return pop; @@ -582,7 +582,7 @@ static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke) paint_2d_stroke_done(pop->custom_paint); } - undo_paint_push_end(UNDO_PAINT_IMAGE); + ED_undo_paint_push_end(UNDO_PAINT_IMAGE); /* duplicate warning, see texpaint_init */ #if 0 @@ -595,7 +595,7 @@ static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - ups->draw_pressure = false; + ups->stroke_active = false; } } @@ -766,7 +766,7 @@ void brush_drawcursor_texpaint_uvsculpt(bContext *C, int x, int y, void *UNUSED( { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; /* hrmf, duplicate paint_draw_cursor logic here */ - if (ups->draw_pressure && BKE_brush_use_size_pressure(scene, brush)) { + if (ups->stroke_active && BKE_brush_use_size_pressure(scene, brush)) { /* inner at full alpha */ glutil_draw_lined_arc(0, (float)(M_PI * 2.0), size * ups->pressure_value, 40); /* outer at half alpha */ diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index 1a19341acec..b2f429c31a1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -49,6 +49,7 @@ #include "BKE_report.h" #include "ED_screen.h" +#include "ED_sculpt.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -275,6 +276,10 @@ static ImBuf *brush_painter_imbuf_new(BrushPainter *painter, int size) if (is_texbrush) { brush_imbuf_tex_co(&tex_mapping, x, y, texco); BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool); + /* TODO(sergey): Support texture paint color space. */ + if (!use_float) { + linearrgb_to_srgb_v3_v3(rgba, rgba); + } mul_v3_v3(rgba, brush_rgb); } else { @@ -362,6 +367,10 @@ static void brush_painter_imbuf_update(BrushPainter *painter, ImBuf *oldtexibuf, if (is_texbrush) { brush_imbuf_tex_co(&tex_mapping, x, y, texco); BKE_brush_sample_tex_3D(scene, brush, texco, rgba, thread, pool); + /* TODO(sergey): Support texture paint color space. */ + if (!use_float) { + linearrgb_to_srgb_v3_v3(rgba, rgba); + } mul_v3_v3(rgba, brush_rgb); } else { @@ -894,7 +903,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *maskb, const f /* blend into canvas */ for (a = 0; a < tot; a++) { - imapaint_dirty_region(s->image, s->canvas, + ED_imapaint_dirty_region(s->image, s->canvas, region[a].destx, region[a].desty, region[a].width, region[a].height); @@ -1103,7 +1112,7 @@ void paint_2d_redraw(const bContext *C, void *ps, bool final) ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL); imapaint_image_update(s->sima, s->image, ibuf, false); - imapaint_clear_partial_redraw(); + ED_imapaint_clear_partial_redraw(); BKE_image_release_ibuf(s->image, ibuf, NULL); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 88cc954fb17..d6989c082a1 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -3294,8 +3294,7 @@ static void project_paint_begin(ProjPaintState *ps) projIma->ima = node->link; projIma->touch = 0; projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL); - projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); - memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); + projIma->partRedrawRect = BLI_memarena_calloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED); } /* we have built the array, discard the linked list */ @@ -3344,8 +3343,7 @@ static void project_paint_end(ProjPaintState *ps) for (a = 0, last_projIma = ps->projImages; a < ps->image_tot; a++, last_projIma++) { int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y); - last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size); - memset(last_projIma->undoRect, 0, size); + last_projIma->undoRect = (void **) BLI_memarena_calloc(arena, size); last_projIma->ibuf->userflags |= IB_BITMAPDIRTY; } @@ -3760,8 +3758,9 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const copy_v3_v3(rgb, ps->brush->rgb); if (ps->is_texbrush) { - /* XXX actually should convert texrgb from linear to srgb here */ mul_v3_v3(rgb, texrgb); + /* TODO(sergey): Support texture paint color space. */ + linearrgb_to_srgb_v3_v3(rgb, rgb); } rgb_float_to_uchar(rgba_ub, rgb); @@ -4414,8 +4413,8 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING; - undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, - image_undo_restore, image_undo_free); + ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, + ED_image_undo_restore, ED_image_undo_free); /* allocate and initialize spatial data structures */ project_paint_begin(&ps); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 5fff02f016b..01f5d53594e 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -146,13 +146,9 @@ int image_texture_paint_poll(struct bContext *C); void *image_undo_find_tile(struct Image *ima, struct ImBuf *ibuf, int x_tile, int y_tile, unsigned short **mask); void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile); void image_undo_remove_masks(void); -void image_undo_restore(struct bContext *C, struct ListBase *lb); -void image_undo_free(struct ListBase *lb); void imapaint_image_update(struct SpaceImage *sima, struct Image *image, struct ImBuf *ibuf, short texpaint); struct ImagePaintPartialRedraw *get_imapaintpartial(void); void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr); -void imapaint_clear_partial_redraw(void); -void imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h); void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th); int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy); void *paint_2d_new_stroke(struct bContext *, struct wmOperator *); @@ -232,13 +228,8 @@ typedef enum BrushStrokeMode { } BrushStrokeMode; /* paint_undo.c */ -typedef void (*UndoRestoreCb)(struct bContext *C, struct ListBase *lb); -typedef void (*UndoFreeCb)(struct ListBase *lb); - -void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free); struct ListBase *undo_paint_push_get_list(int type); void undo_paint_push_count_alloc(int type, int size); -void undo_paint_push_end(int type); /* paint_hide.c */ diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 9b906c460e3..320bf4f0f5e 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -165,15 +165,15 @@ static int is_effected(float planes[4][4], const float co[3]) static void flip_plane(float out[4], const float in[4], const char symm) { - if (symm & SCULPT_SYMM_X) + if (symm & PAINT_SYMM_X) out[0] = -in[0]; else out[0] = in[0]; - if (symm & SCULPT_SYMM_Y) + if (symm & PAINT_SYMM_Y) out[1] = -in[1]; else out[1] = in[1]; - if (symm & SCULPT_SYMM_Z) + if (symm & PAINT_SYMM_Z) out[2] = -in[2]; else out[2] = in[2]; @@ -198,7 +198,7 @@ int do_sculpt_mask_box_select(ViewContext *vc, rcti *rect, bool select, bool UNU PBVH *pbvh; PBVHNode **nodes; int totnode, i, symmpass; - int symm = sd->flags & 7; + int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; mode = PAINT_MASK_FLOOD_VALUE; value = select ? 1.0 : 0.0; diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 397baeae4c9..0c28081723f 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -76,6 +76,7 @@ typedef struct PaintStroke { ViewContext vc; bglMats mats; Brush *brush; + UnifiedPaintSettings *ups; /* Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES prior inputs * to smooth the stroke */ @@ -174,7 +175,7 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode, /* Truly temporary data that isn't stored in properties */ - ups->draw_pressure = TRUE; + ups->stroke_active = true; ups->pressure_value = stroke->cached_pressure; ups->pixel_radius = BKE_brush_size_get(scene, brush); @@ -247,7 +248,7 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode, else copy_v2_v2(ups->anchored_initial_mouse, stroke->initial_mouse); - ups->draw_anchored = 1; + ups->draw_anchored = true; } else if (brush->flag & BRUSH_RAKE) { if (!stroke->brush_init) @@ -467,8 +468,10 @@ PaintStroke *paint_stroke_new(bContext *C, StrokeDone done, int event_type) { PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke"); - + ToolSettings *toolsettings = CTX_data_tool_settings(C); + UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings; Brush *br = stroke->brush = BKE_paint_brush(BKE_paint_get_active_from_context(C)); + view3d_set_viewcontext(C, &stroke->vc); if (stroke->vc.v3d) view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats); @@ -479,6 +482,7 @@ PaintStroke *paint_stroke_new(bContext *C, stroke->redraw = redraw; stroke->done = done; stroke->event_type = event_type; /* for modal, return event */ + stroke->ups = ups; /* initialize here to avoid initialization conflict with threaded strokes */ curvemapping_initialize(br->curve); @@ -498,6 +502,14 @@ void paint_stroke_data_free(struct wmOperator *op) static void stroke_done(struct bContext *C, struct wmOperator *op) { struct PaintStroke *stroke = op->customdata; + UnifiedPaintSettings *ups = stroke->ups; + + ups->draw_anchored = false; + ups->stroke_active = false; + + /* reset rotation here to avoid doing so in cursor display */ + if (!(stroke->brush->flag & BRUSH_RAKE)) + ups->brush_rotation = 0.0f; if (stroke->stroke_started) { if (stroke->redraw) @@ -556,7 +568,7 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode) { if (!(br->flag & BRUSH_SMOOTH_STROKE) || (br->flag & BRUSH_ANCHORED) || - (br->flag & BRUSH_RESTORE_MESH)) + (br->flag & BRUSH_DRAG_DOT)) { return false; } diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c index 50a79005ee3..b4bd46376d3 100644 --- a/source/blender/editors/sculpt_paint/paint_undo.c +++ b/source/blender/editors/sculpt_paint/paint_undo.c @@ -223,7 +223,7 @@ static void undo_stack_free(UndoStack *stack) /* Exported Functions */ -void undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free) +void ED_undo_paint_push_begin(int type, const char *name, UndoRestoreCb restore, UndoFreeCb free) { if (type == UNDO_PAINT_IMAGE) undo_stack_push_begin(&ImageUndoStack, name, restore, free); @@ -253,7 +253,7 @@ void undo_paint_push_count_alloc(int type, int size) MeshUndoStack.current->undosize += size; } -void undo_paint_push_end(int type) +void ED_undo_paint_push_end(int type) { if (type == UNDO_PAINT_IMAGE) undo_stack_push_end(&ImageUndoStack); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 714d67c8039..9d7bad2591e 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1088,7 +1088,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even { ViewContext vc; Mesh *me; - short change = FALSE; + bool changed = false; view3d_set_viewcontext(C, &vc); me = BKE_mesh_from_object(vc.obact); @@ -1122,11 +1122,11 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even const int vgroup_active = vc.obact->actdef - 1; float vgroup_weight = defvert_find_weight(&me->dvert[v_idx_best], vgroup_active); BKE_brush_weight_set(vc.scene, brush, vgroup_weight); - change = TRUE; + changed = true; } } - if (change) { + if (changed) { /* not really correct since the brush didnt change, but redraws the toolbar */ WM_main_add_notifier(NC_BRUSH | NA_EDITED, NULL); /* ts->wpaint->paint.brush */ @@ -1468,14 +1468,14 @@ static float redistribute_change(MDeformVert *ndv, const int defbase_tot, float totchange, float total_valid, char do_auto_normalize) { - float was_change; + bool changed; float change; float oldval; MDeformWeight *ndw; int i; do { /* assume there is no change until you see one */ - was_change = FALSE; + changed = false; /* change each group by the same amount each time */ change = totchange / total_valid; for (i = 0; i < ndv->totweight && total_valid && totchange; i++) { @@ -1507,14 +1507,14 @@ static float redistribute_change(MDeformVert *ndv, const int defbase_tot, } /* see if there was a change */ if (oldval != ndw->weight) { - was_change = TRUE; + changed = true; } } } } /* don't go again if there was no change, if there is no valid group, * or there is no change left */ - } while (was_change && total_valid && totchange); + } while (changed && total_valid && totchange); /* left overs */ return totchange; } @@ -2255,11 +2255,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU if (me->editflag & ME_EDIT_MIRROR_X) { wpd->vgroup_mirror = wpaint_mirror_vgroup_ensure(ob, wpd->vgroup_active); } - - { - UnifiedPaintSettings *ups = &ts->unified_paint_settings; - ups->draw_pressure = true; - } return TRUE; } @@ -2366,12 +2361,13 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P else totindex = 0; } - if (use_face_sel && me->mpoly) { + if (use_face_sel && me->totpoly) { + MPoly *mpoly = me->mpoly; for (index = 0; index < totindex; index++) { if (indexar[index] && indexar[index] <= me->totpoly) { - MPoly *mpoly = ((MPoly *)me->mpoly) + (indexar[index] - 1); + MPoly *mp = &mpoly[indexar[index] - 1]; - if ((mpoly->flag & ME_FACE_SEL) == 0) { + if ((mp->flag & ME_FACE_SEL) == 0) { indexar[index] = 0; } } @@ -2552,11 +2548,6 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) } } - { - UnifiedPaintSettings *ups = &ts->unified_paint_settings; - ups->draw_pressure = false; - } - DAG_id_tag_update(ob->data, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -2874,11 +2865,6 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl invert_m4_m4(imat, mat); copy_m3_m4(vpd->vpimat, imat); - { - UnifiedPaintSettings *ups = &ts->unified_paint_settings; - ups->draw_pressure = true; - } - return 1; } @@ -3102,11 +3088,6 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) if (vpd->mfacetag) MEM_freeN(vpd->mfacetag); - { - UnifiedPaintSettings *ups = &ts->unified_paint_settings; - ups->draw_pressure = false; - } - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); MEM_freeN(vpd); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 6bd935af436..fa938eca487 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -418,7 +418,7 @@ static int sculpt_stroke_dynamic_topology(const SculptSession *ss, /* Requires mesh restore, which doesn't work with * dynamic-topology */ !(brush->flag & BRUSH_ANCHORED) && - !(brush->flag & BRUSH_RESTORE_MESH) && + !(brush->flag & BRUSH_DRAG_DOT) && (!ELEM6(brush->sculpt_tool, /* These brushes, as currently coded, cannot @@ -762,15 +762,15 @@ static float integrate_overlap(Brush *br) /* Uses symm to selectively flip any axis of a coordinate. */ static void flip_v3_v3(float out[3], const float in[3], const char symm) { - if (symm & SCULPT_SYMM_X) + if (symm & PAINT_SYMM_X) out[0] = -in[0]; else out[0] = in[0]; - if (symm & SCULPT_SYMM_Y) + if (symm & PAINT_SYMM_Y) out[1] = -in[1]; else out[1] = in[1]; - if (symm & SCULPT_SYMM_Z) + if (symm & PAINT_SYMM_Z) out[2] = -in[2]; else out[2] = in[2]; @@ -820,7 +820,7 @@ static float calc_radial_symmetry_feather(Sculpt *sd, StrokeCache *cache, const static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) { - if (sd->flags & SCULPT_SYMMETRY_FEATHER) { + if (sd->paint.symmetry_flags & PAINT_SYMMETRY_FEATHER) { float overlap; int symm = cache->symmetry; int i; @@ -3076,9 +3076,12 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush) /* Only act if some verts are inside the brush area */ if (totnode) { - PBVHTopologyUpdateMode mode = PBVH_Subdivide; + PBVHTopologyUpdateMode mode = 0; float location[3]; + if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) + mode |= PBVH_Subdivide; + if ((sd->flags & SCULPT_DYNTOPO_COLLAPSE) || (brush->sculpt_tool == SCULPT_TOOL_SIMPLIFY)) { @@ -3464,7 +3467,7 @@ static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob, Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; StrokeCache *cache = ss->cache; - const char symm = sd->flags & 7; + const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; int i; float feather = calc_symmetry_feather(sd, ss->cache); @@ -4012,7 +4015,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru /* location stays the same for finding vertices in brush radius */ copy_v3_v3(cache->true_location, cache->orig_grab_location); - ups->draw_anchored = 1; + ups->draw_anchored = true; copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse); ups->anchored_size = ups->pixel_radius; } @@ -4139,7 +4142,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, #undef PIXEL_INPUT_THRESHHOLD } - ups->draw_anchored = 1; + ups->draw_anchored = true; copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse); copy_v3_v3(cache->anchored_location, cache->true_location); ups->anchored_size = ups->pixel_radius; @@ -4311,7 +4314,7 @@ static void sculpt_restore_mesh(Sculpt *sd, Object *ob) if ((brush->flag & BRUSH_ANCHORED) || (brush->sculpt_tool == SCULPT_TOOL_GRAB && BKE_brush_use_size_pressure(ss->cache->vc->scene, brush)) || - (brush->flag & BRUSH_RESTORE_MESH)) + (brush->flag & BRUSH_DRAG_DOT)) { paint_mesh_restore_co(sd, ob); } @@ -4453,7 +4456,6 @@ static void sculpt_brush_exit_tex(Sculpt *sd) static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(stroke)) { - UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; Object *ob = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); SculptSession *ss = ob->sculpt; @@ -4461,10 +4463,6 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str sculpt_omp_done(ss); - /* reset values used to draw brush after completing the stroke */ - ups->draw_anchored = 0; - ups->draw_pressure = 0; - /* Finished */ if (ss->cache) { Brush *brush = BKE_paint_brush(&sd->paint); @@ -5065,7 +5063,10 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op) ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data"); /* Turn on X plane mirror symmetry by default */ - ts->sculpt->flags |= SCULPT_SYMM_X; + ts->sculpt->paint.symmetry_flags |= PAINT_SYMM_X; + + /* Make sure at least dyntopo subdivision is enabled */ + ts->sculpt->flags |= SCULPT_DYNTOPO_SUBDIVIDE; } if (!ts->sculpt->detail_size) diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index 8861777f326..846801ae85d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -819,7 +819,7 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node, void sculpt_undo_push_begin(const char *name) { - undo_paint_push_begin(UNDO_PAINT_MESH, name, + ED_undo_paint_push_begin(UNDO_PAINT_MESH, name, sculpt_undo_restore, sculpt_undo_free); } @@ -839,5 +839,5 @@ void sculpt_undo_push_end(void) BKE_pbvh_node_layer_disp_free(unode->node); } - undo_paint_push_end(UNDO_PAINT_MESH); + ED_undo_paint_push_end(UNDO_PAINT_MESH); } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 7c9d867aad6..aafbc6af558 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -780,11 +780,12 @@ void ACTION_OT_duplicate(wmOperatorType *ot) /* ******************** Delete Keyframes Operator ************************* */ -static void delete_action_keys(bAnimContext *ac) +static bool delete_action_keys(bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; + bool changed = false; /* filter data */ if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) @@ -796,17 +797,17 @@ static void delete_action_keys(bAnimContext *ac) /* loop through filtered data and delete selected keys */ for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { - ED_gplayer_frames_delete((bGPDlayer *)ale->data); + changed |= ED_gplayer_frames_delete((bGPDlayer *)ale->data); } else if (ale->type == ANIMTYPE_MASKLAYER) { - ED_masklayer_frames_delete((MaskLayer *)ale->data); + changed |= ED_masklayer_frames_delete((MaskLayer *)ale->data); } else { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ale->adt; /* delete selected keyframes only */ - delete_fcurve_keys(fcu); + changed |= delete_fcurve_keys(fcu); /* Only delete curve too if it won't be doing anything anymore */ if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) @@ -816,20 +817,23 @@ static void delete_action_keys(bAnimContext *ac) /* free filtered list */ BLI_freelistN(&anim_data); + + return changed; } /* ------------------- */ -static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int actkeys_delete_exec(bContext *C, wmOperator *op) { bAnimContext ac; + bool changed; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; /* delete keyframes */ - delete_action_keys(&ac); + changed = delete_action_keys(&ac); /* validate keyframes after editing */ if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) @@ -838,6 +842,9 @@ static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* set notifier that keyframes have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + if (changed) + BKE_report(op->reports, RPT_INFO, "Deleted selected keyframes"); + return OPERATOR_FINISHED; } @@ -849,7 +856,6 @@ void ACTION_OT_delete(wmOperatorType *ot) ot->description = "Remove all selected keyframes"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = actkeys_delete_exec; ot->poll = ED_operator_action_active; diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index d62dd88418f..c256dbb3b59 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -305,7 +305,8 @@ static int actkeys_borderselect_exec(bContext *C, wmOperator *op) bAnimContext ac; rcti rect; short mode = 0, selectmode = 0; - int gesture_mode, extend; + int gesture_mode; + bool extend; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 8508123f942..975123f244c 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -516,7 +516,7 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUS if (!last_category || strcmp(last_category, user->category) != 0) { uiItemL(layout, user->category, ICON_NONE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; } /* create button */ @@ -577,7 +577,7 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C) /* some cosmetic tweaks */ but->type = MENU; - but->flag |= UI_TEXT_LEFT; + but->drawflag |= UI_BUT_TEXT_LEFT; but->flag &= ~UI_ICON_SUBMENU; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index 059b8ace7b9..e85b055bc59 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -341,7 +341,7 @@ void clip_draw_dopesheet_channels(const bContext *C, ARegion *ar) else UI_ThemeColor(TH_TEXT); - font_height = BLF_height(fontid, channel->name); + font_height = BLF_height(fontid, channel->name, sizeof(channel->name)); BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, y - font_height / 2.0f, 0.0f); BLF_draw(fontid, channel->name, strlen(channel->name)); diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index e5cd7247c43..0fbed2c3c1e 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -96,7 +96,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) MovieTrackingDopesheetChannel *channel; ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); float location[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); int current_channel_index = 0, channel_index; RNA_float_get_array(op->ptr, "location", location); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 3c9eb1fe79e..79607163913 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -48,6 +48,7 @@ #include "BLI_math_base.h" #include "BKE_context.h" +#include "BKE_image.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_mask.h" @@ -86,7 +87,7 @@ void clip_draw_curfra_label(const int framenr, const float x, const float y) BLF_size(fontid, 11.0f, U.dpi); BLI_snprintf(numstr, sizeof(numstr), "%d", framenr); - BLF_width_and_height(fontid, numstr, &font_dims[0], &font_dims[1]); + BLF_width_and_height(fontid, numstr, sizeof(numstr), &font_dims[0], &font_dims[1]); glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f); @@ -1038,12 +1039,129 @@ static void getArrowEndPoint(const int width, const int height, const float zoom add_v2_v2v2(end_point, start_corner, direction); } -static void draw_plane_marker_ex(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track, +static void homogeneous_2d_to_gl_matrix(/*const*/ float matrix[3][3], + float gl_matrix[4][4]) +{ + gl_matrix[0][0] = matrix[0][0]; + gl_matrix[0][1] = matrix[0][1]; + gl_matrix[0][2] = 0.0f; + gl_matrix[0][3] = matrix[0][2]; + + gl_matrix[1][0] = matrix[1][0]; + gl_matrix[1][1] = matrix[1][1]; + gl_matrix[1][2] = 0.0f; + gl_matrix[1][3] = matrix[1][2]; + + gl_matrix[2][0] = 0.0f; + gl_matrix[2][1] = 0.0f; + gl_matrix[2][2] = 1.0f; + gl_matrix[2][3] = 0.0f; + + gl_matrix[3][0] = matrix[2][0]; + gl_matrix[3][1] = matrix[2][1]; + gl_matrix[3][2] = 0.0f; + gl_matrix[3][3] = matrix[2][2]; +} + +static void draw_plane_marker_image(Scene *scene, + MovieTrackingPlaneTrack *plane_track, + MovieTrackingPlaneMarker *plane_marker) +{ + Image *image = plane_track->image; + ImBuf *ibuf; + void *lock; + + if (image == NULL) { + return; + } + + ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + + if (ibuf) { + unsigned char *display_buffer; + void *cache_handle; + + if (image->flag & IMA_VIEW_AS_RENDER) { + display_buffer = IMB_display_buffer_acquire(ibuf, + &scene->view_settings, + &scene->display_settings, + &cache_handle); + } + else { + display_buffer = IMB_display_buffer_acquire(ibuf, NULL, + &scene->display_settings, + &cache_handle); + } + + if (display_buffer) { + GLuint texid, last_texid; + float frame_corners[4][2] = {{0.0f, 0.0f}, + {1.0f, 0.0f}, + {1.0f, 1.0f}, + {0.0f, 1.0f}}; + float perspective_matrix[3][3]; + float gl_matrix[4][4]; + bool transparent = false; + BKE_tracking_homography_between_two_quads(frame_corners, + plane_marker->corners, + perspective_matrix); + + homogeneous_2d_to_gl_matrix(perspective_matrix, gl_matrix); + + if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) { + transparent = true; + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glColor4f(1.0, 1.0, 1.0, plane_track->image_opacity); + + last_texid = glaGetOneInteger(GL_TEXTURE_2D); + glEnable(GL_TEXTURE_2D); + glGenTextures(1, (GLuint *)&texid); + + glBindTexture(GL_TEXTURE_2D, texid); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, + GL_UNSIGNED_BYTE, display_buffer); + + glPushMatrix(); + glMultMatrixf(gl_matrix); + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); + glTexCoord2f(1.0f, 0.0f); glVertex2f(1.0f, 0.0f); + glTexCoord2f(1.0f, 1.0f); glVertex2f(1.0f, 1.0f); + glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, 1.0f); + glEnd(); + + glPopMatrix(); + + glBindTexture(GL_TEXTURE_2D, last_texid); + glDisable(GL_TEXTURE_2D); + + if (transparent) { + glDisable(GL_BLEND); + } + } + + IMB_display_buffer_release(cache_handle); + } + + BKE_image_release_ibuf(image, ibuf, lock); +} + +static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker, bool is_active_track, bool draw_outline, int width, int height) { bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0; bool is_selected_track = plane_track->flag & SELECT; + bool draw_plane_quad = plane_track->image == NULL || plane_track->image_opacity == 0.0f; float px[2]; if (draw_outline) { @@ -1063,6 +1181,11 @@ static void draw_plane_marker_ex(SpaceClip *sc, MovieTrackingPlaneTrack *plane_t px[0] = 1.0f / width / sc->zoom; px[1] = 1.0f / height / sc->zoom; + /* Draw image */ + if (draw_outline == false) { + draw_plane_marker_image(scene, plane_track, plane_marker); + } + if (draw_outline) { if (!tiny) { glLineWidth(3.0f); @@ -1073,34 +1196,36 @@ static void draw_plane_marker_ex(SpaceClip *sc, MovieTrackingPlaneTrack *plane_t glEnable(GL_LINE_STIPPLE); } - /* Draw rectangle itself. */ - glBegin(GL_LINE_LOOP); - glVertex2fv(plane_marker->corners[0]); - glVertex2fv(plane_marker->corners[1]); - glVertex2fv(plane_marker->corners[2]); - glVertex2fv(plane_marker->corners[3]); - glEnd(); - - /* Draw axis. */ - if (!draw_outline) { - float end_point[2]; - glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); - - getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point); - glColor3f(1.0, 0.0, 0.0f); - glBegin(GL_LINES); + if (draw_plane_quad) { + /* Draw rectangle itself. */ + glBegin(GL_LINE_LOOP); glVertex2fv(plane_marker->corners[0]); - glVertex2fv(end_point); + glVertex2fv(plane_marker->corners[1]); + glVertex2fv(plane_marker->corners[2]); + glVertex2fv(plane_marker->corners[3]); glEnd(); - getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point); - glColor3f(0.0, 1.0, 0.0f); - glBegin(GL_LINES); - glVertex2fv(plane_marker->corners[0]); - glVertex2fv(end_point); - glEnd(); + /* Draw axis. */ + if (!draw_outline) { + float end_point[2]; + glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); + + getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point); + glColor3f(1.0, 0.0, 0.0f); + glBegin(GL_LINES); + glVertex2fv(plane_marker->corners[0]); + glVertex2fv(end_point); + glEnd(); + + getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point); + glColor3f(0.0, 1.0, 0.0f); + glBegin(GL_LINES); + glVertex2fv(plane_marker->corners[0]); + glVertex2fv(end_point); + glEnd(); - glPopAttrib(); + glPopAttrib(); + } } /* Draw sliders. */ @@ -1122,32 +1247,32 @@ static void draw_plane_marker_ex(SpaceClip *sc, MovieTrackingPlaneTrack *plane_t } } -static void draw_plane_marker_outline(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track, +static void draw_plane_marker_outline(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker, int width, int height) { - draw_plane_marker_ex(sc, plane_track, plane_marker, false, true, width, height); + draw_plane_marker_ex(sc, scene, plane_track, plane_marker, false, true, width, height); } -static void draw_plane_marker(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track, +static void draw_plane_marker(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker, bool is_active_track, int width, int height) { - draw_plane_marker_ex(sc, plane_track, plane_marker, is_active_track, false, width, height); + draw_plane_marker_ex(sc, scene, plane_track, plane_marker, is_active_track, false, width, height); } -static void draw_plane_track(SpaceClip *sc, MovieTrackingPlaneTrack *plane_track, +static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track, int framenr, bool is_active_track, int width, int height) { MovieTrackingPlaneMarker *plane_marker; plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr); - draw_plane_marker_outline(sc, plane_track, plane_marker, width, height); - draw_plane_marker(sc, plane_track, plane_marker, is_active_track, width, height); + draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height); + draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height); } /* Draw all kind of tracks. */ -static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, +static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) { float x, y; @@ -1180,6 +1305,15 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, act_track = BKE_tracking_track_get_active(tracking); + /* Draw plane tracks */ + active_plane_track = BKE_tracking_plane_track_get_active(tracking); + for (plane_track = plane_tracks_base->first; + plane_track; + plane_track = plane_track->next) + { + draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height); + } + if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { int count = 0; @@ -1348,15 +1482,6 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, glDisable(GL_POINT_SMOOTH); } - /* Draw plane tracks */ - active_plane_track = BKE_tracking_plane_track_get_active(tracking); - for (plane_track = plane_tracks_base->first; - plane_track; - plane_track = plane_track->next) - { - draw_plane_track(sc, plane_track, framenr, plane_track == active_plane_track, width, height); - } - glPopMatrix(); if (sc->flag & SC_SHOW_NAMES) { @@ -1666,7 +1791,7 @@ void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar) if (width && height) { draw_stabilization_border(sc, ar, width, height, zoomx, zoomy); - draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy); + draw_tracking_tracks(sc, scene, ar, clip, width, height, zoomx, zoomy); draw_distortion(sc, ar, clip, width, height, zoomx, zoomy); } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index d1c44693995..ffb805cdc5f 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -43,6 +43,7 @@ #include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_depsgraph.h" +#include "BKE_report.h" #include "WM_api.h" #include "WM_types.h" @@ -319,7 +320,7 @@ void CLIP_OT_graph_select(wmOperatorType *ot) typedef struct BorderSelectuserData { rctf rect; int mode; - bool change, extend; + bool changed, extend; } BorderSelectuserData; static void border_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track), @@ -340,7 +341,7 @@ static void border_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track), else marker->flag &= ~flag; - data->change = TRUE; + data->changed = true; } else if (!data->extend) { marker->flag &= ~MARKER_GRAPH_SEL; @@ -368,13 +369,13 @@ static int border_select_graph_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, rect.xmin, rect.ymin, &userdata.rect.xmin, &userdata.rect.ymin); UI_view2d_region_to_view(&ar->v2d, rect.xmax, rect.ymax, &userdata.rect.xmax, &userdata.rect.ymax); - userdata.change = false; + userdata.changed = false; userdata.mode = RNA_int_get(op->ptr, "gesture_mode"); userdata.extend = RNA_boolean_get(op->ptr, "extend"); clip_graph_tracking_values_iterate_track(sc, act_track, &userdata, border_select_cb, NULL, NULL); - if (userdata.change) { + if (userdata.changed) { WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); return OPERATOR_FINISHED; @@ -471,16 +472,19 @@ void CLIP_OT_graph_select_all_markers(wmOperatorType *ot) /******************** delete curve operator ********************/ -static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op)) +static int delete_curve_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking); - if (act_track) + if (act_track) { clip_delete_track(C, clip, act_track); + BKE_report(op->reports, RPT_INFO, "Deleted track"); + } + return OPERATOR_FINISHED; } @@ -488,11 +492,10 @@ void CLIP_OT_graph_delete_curve(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete Curve"; - ot->description = "Delete selected curves"; + ot->description = "Delete track corresponding to the selected curve"; ot->idname = "CLIP_OT_graph_delete_curve"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = delete_curve_exec; ot->poll = ED_space_clip_tracking_poll; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 5607d7dc635..b198b68b95a 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -234,7 +234,7 @@ void CLIP_OT_add_marker_at_click(wmOperatorType *ot) /********************** delete track operator *********************/ -static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) +static int delete_track_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); @@ -243,7 +243,7 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); MovieTrackingTrack *track = tracksbase->first, *next; MovieTrackingPlaneTrack *plane_track, *next_plane_track; - bool modified = false; + bool changed = false; /* Delete selected plane tracks. */ for (plane_track = plane_tracks_base->first; @@ -255,7 +255,7 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) if (plane_track->flag & SELECT) { BKE_tracking_plane_track_free(plane_track); BLI_freelinkN(plane_tracks_base, plane_track); - modified = true; + changed = true; } } @@ -263,8 +263,10 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) while (track) { next = track->next; - if (TRACK_VIEW_SELECTED(sc, track)) + if (TRACK_VIEW_SELECTED(sc, track)) { clip_delete_track(C, clip, track); + changed = true; + } track = next; } @@ -272,7 +274,8 @@ static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) /* nothing selected now, unlock view so it can be scrolled nice again */ sc->flag &= ~SC_LOCK_SELECTION; - if (modified) { + if (changed) { + BKE_report(op->reports, RPT_INFO, "Deleted selected tracks"); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip); } @@ -287,7 +290,6 @@ void CLIP_OT_delete_track(wmOperatorType *ot) ot->description = "Delete selected tracks"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = delete_track_exec; ot->poll = ED_space_clip_tracking_poll; @@ -297,7 +299,7 @@ void CLIP_OT_delete_track(wmOperatorType *ot) /********************** delete marker operator *********************/ -static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) +static int delete_marker_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); @@ -307,6 +309,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) MovieTrackingPlaneTrack *plane_track, *plane_track_next; int framenr = ED_space_clip_get_clip_frame_number(sc); int has_selection = 0; + bool changed = false; while (track) { next = track->next; @@ -318,6 +321,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) has_selection |= track->markersnr > 1; clip_delete_marker(C, clip, track, marker); + changed = true; } } @@ -341,6 +345,8 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) else { BKE_tracking_plane_marker_delete(plane_track, framenr); } + + changed = true; } } } @@ -350,6 +356,11 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) sc->flag &= ~SC_LOCK_SELECTION; } + if (!changed) + return OPERATOR_CANCELLED; + + BKE_report(op->reports, RPT_INFO, "Deleted markers for current frame from selected tracks"); + return OPERATOR_FINISHED; } @@ -361,7 +372,6 @@ void CLIP_OT_delete_marker(wmOperatorType *ot) ot->description = "Delete marker for current frame from selected tracks"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = delete_marker_exec; ot->poll = ED_space_clip_tracking_poll; diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 7cb5f9b5dc0..65b7a5dee65 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -402,7 +402,7 @@ static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event) ARegion *ar = CTX_wm_region(C); float co[2]; - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); if (!extend) { MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL); @@ -461,7 +461,7 @@ static int border_select_exec(bContext *C, wmOperator *op) ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); rcti rect; rctf rectf; - bool change = false; + bool changed = false; int mode, extend; int framenr = ED_space_clip_get_clip_frame_number(sc); @@ -491,7 +491,7 @@ static int border_select_exec(bContext *C, wmOperator *op) BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } - change = true; + changed = true; } } @@ -521,11 +521,11 @@ static int border_select_exec(bContext *C, wmOperator *op) } } - change = true; + changed = true; } } - if (change) { + if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); @@ -570,7 +570,7 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); rcti rect; - bool change = false; + bool changed = false; int framenr = ED_space_clip_get_clip_frame_number(sc); /* get rectangle from operator */ @@ -597,7 +597,7 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); } - change = true; + changed = true; } } @@ -631,17 +631,17 @@ static int do_lasso_select_marker(bContext *C, const int mcords[][2], const shor } } - change = true; + changed = true; } } - if (change) { + if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); } - return change; + return changed; } static int clip_lasso_select_exec(bContext *C, wmOperator *op) @@ -715,7 +715,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking); ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking); int x, y, radius, width, height, mode; - bool change = false; + bool changed = false; float zoomx, zoomy, offset[2], ellipse[2]; int framenr = ED_space_clip_get_clip_frame_number(sc); @@ -747,7 +747,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) else BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT); - change = true; + changed = true; } } @@ -774,11 +774,11 @@ static int circle_select_exec(bContext *C, wmOperator *op) } } - change = true; + changed = true; } } - if (change) { + if (changed) { BKE_tracking_dopesheet_tag_update(tracking); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index c4e6ca97418..e31d813fc5e 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -75,25 +75,6 @@ #include "file_intern.h" // own include -/* button events */ -enum { - B_FS_DIRNAME, - B_FS_FILENAME -} /*eFile_ButEvents*/; - - -static void do_file_buttons(bContext *C, void *UNUSED(arg), int event) -{ - switch (event) { - case B_FS_FILENAME: - file_filename_exec(C, NULL); - break; - case B_FS_DIRNAME: - file_directory_exec(C, NULL); - break; - } -} - /* Note: This function uses pixelspace (0, 0, winx, winy), not view2d. * The controls are laid out as follows: * @@ -139,7 +120,6 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* Initialize UI block. */ BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar); block = uiBeginBlock(C, ar, uiblockstr, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_file_buttons, NULL); /* exception to make space for collapsed region icon */ for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) { @@ -180,21 +160,31 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* callbacks for operator check functions */ uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL); - but = uiDefButTextO(block, TEX, "FILE_OT_directory", 0, "", - min_x, line1_y, line1_w - chan_offs, btn_h, - params->dir, 0.0, (float)FILE_MAX, 0, 0, - TIP_("File path")); + but = uiDefBut(block, TEX, -1, "", + min_x, line1_y, line1_w - chan_offs, btn_h, + params->dir, 0.0, (float)FILE_MAX, 0, 0, + TIP_("File path")); uiButSetCompleteFunc(but, autocomplete_directory, NULL); uiButSetFlag(but, UI_BUT_NO_UTF8); + uiButClearFlag(but, UI_BUT_UNDO); + uiButSetNFunc(but, file_directory_enter_handle, NULL, but); + + /* TODO, directory editing is non-functional while a library is loaded + * until this is properly supported just disable it. */ + if (sfile->files && filelist_lib(sfile->files)) + uiButSetFlag(but, UI_BUT_DISABLED); if ((params->flag & FILE_DIRSEL_ONLY) == 0) { - but = uiDefBut(block, TEX, B_FS_FILENAME, "", + but = uiDefBut(block, TEX, -1, "", min_x, line2_y, line2_w - chan_offs, btn_h, params->file, 0.0, (float)FILE_MAXFILE, 0, 0, TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name"))); uiButSetCompleteFunc(but, autocomplete_file, NULL); uiButSetFlag(but, UI_BUT_NO_UTF8); - uiButClearFlag(but, UI_BUT_UNDO); /* operator button above does this automatic */ + uiButClearFlag(but, UI_BUT_UNDO); + /* silly workaround calling NFunc to ensure this does not get called + * immediate ui_apply_but_func but only after button deactivates */ + uiButSetNFunc(but, file_filename_enter_handle, NULL, but); /* check if this overrides a file and if the operator option is used */ if (overwrite_alert) { diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index d01286442be..841cb0d5f77 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -72,7 +72,6 @@ void FILE_OT_execute(struct wmOperatorType *ot); void FILE_OT_cancel(struct wmOperatorType *ot); void FILE_OT_parent(struct wmOperatorType *ot); void FILE_OT_directory_new(struct wmOperatorType *ot); -void FILE_OT_directory(struct wmOperatorType *ot); void FILE_OT_previous(struct wmOperatorType *ot); void FILE_OT_next(struct wmOperatorType *ot); void FILE_OT_refresh(struct wmOperatorType *ot); @@ -87,11 +86,12 @@ int file_cancel_exec(bContext *C, struct wmOperator *unused); int file_parent_exec(bContext *C, struct wmOperator *unused); int file_previous_exec(bContext *C, struct wmOperator *unused); int file_next_exec(bContext *C, struct wmOperator *unused); -int file_filename_exec(bContext *C, struct wmOperator *unused); -int file_directory_exec(bContext *C, struct wmOperator *unused); int file_directory_new_exec(bContext *C, struct wmOperator *unused); int file_delete_exec(bContext *C, struct wmOperator *unused); +void file_directory_enter_handle(bContext *C, void *arg_unused, void *arg_but); +void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but); + int file_highlight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my); void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile, char *filepath); @@ -105,8 +105,8 @@ float file_string_width(const char *str); float file_font_pointsize(void); void file_change_dir(bContext *C, int checkdir); int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file); -bool autocomplete_directory(struct bContext *C, char *str, void *arg_v); -bool autocomplete_file(struct bContext *C, char *str, void *arg_v); +int autocomplete_directory(struct bContext *C, char *str, void *arg_v); +int autocomplete_file(struct bContext *C, char *str, void *arg_v); /* file_panels.c */ void file_panels_register(struct ARegionType *art); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index a97b3b1d719..f4cae0c462f 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -32,6 +32,8 @@ #include "BLI_utildefines.h" #include "BLI_fileops_types.h" +#include "BLO_readfile.h" + #include "BKE_context.h" #include "BKE_screen.h" #include "BKE_global.h" @@ -45,6 +47,8 @@ #include "ED_screen.h" #include "ED_fileselect.h" +#include "UI_interface.h" + #include "MEM_guardedalloc.h" #include "RNA_access.h" @@ -270,8 +274,8 @@ static int file_border_select_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); rcti rect; FileSelect ret; - int extend = RNA_boolean_get(op->ptr, "extend"); - short select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); + const bool select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); + const bool extend = RNA_boolean_get(op->ptr, "extend"); WM_operator_properties_border_to_rcti(op, &rect); @@ -317,9 +321,9 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) SpaceFile *sfile = CTX_wm_space_file(C); FileSelect ret; rcti rect; - int extend = RNA_boolean_get(op->ptr, "extend"); - int fill = RNA_boolean_get(op->ptr, "fill"); - int do_diropen = RNA_boolean_get(op->ptr, "open"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); + const bool fill = RNA_boolean_get(op->ptr, "fill"); + const bool do_diropen = RNA_boolean_get(op->ptr, "open"); if (ar->regiontype != RGN_TYPE_WINDOW) return OPERATOR_CANCELLED; @@ -1131,6 +1135,12 @@ int file_directory_new_exec(bContext *C, wmOperator *op) /* reload dir to make sure we're seeing what's in the directory */ ED_fileselect_clear(wm, sfile); + + if (RNA_boolean_get(op->ptr, "open")) { + BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); + file_change_dir(C, 1); + } + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); return OPERATOR_FINISHED; @@ -1153,7 +1163,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot) prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); - + prop = RNA_def_boolean(ot->srna, "open", false, "Open", "Open new directory"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -1194,36 +1205,13 @@ static void file_expand_directory(bContext *C) } } -static int file_directory_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - - if (sfile->params) { - file_expand_directory(C); - - if (!BLI_exists(sfile->params->dir)) { - return WM_operator_confirm_message(C, op, "Create new directory?"); - } - - return file_directory_exec(C, op); - } - - return OPERATOR_CANCELLED; -} - - - -int file_directory_exec(bContext *C, wmOperator *UNUSED(unused)) +void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UNUSED(arg_but)) { SpaceFile *sfile = CTX_wm_space_file(C); if (sfile->params) { file_expand_directory(C); - if (!BLI_exists(sfile->params->dir)) { - BLI_dir_create_recursive(sfile->params->dir); - } - /* special case, user may have pasted a filepath into the directory */ if (BLI_is_file(sfile->params->dir)) { char path[sizeof(sfile->params->dir)]; @@ -1232,21 +1220,53 @@ int file_directory_exec(bContext *C, wmOperator *UNUSED(unused)) } BLI_cleanup_dir(G.main->name, sfile->params->dir); - file_change_dir(C, 1); + + if (BLI_exists(sfile->params->dir)) { + /* if directory exists, enter it immediately */ + file_change_dir(C, 1); + + /* don't do for now because it selects entire text instead of + * placing cursor at the end */ + /* UI_textbutton_activate_but(C, but); */ + } + else { + const char *lastdir = folderlist_peeklastdir(sfile->folders_prev); + + /* if not, ask to create it and enter if confirmed */ + PointerRNA ptr; + WM_operator_properties_create(&ptr, "FILE_OT_directory_new"); + RNA_string_set(&ptr, "directory", sfile->params->dir); + RNA_boolean_set(&ptr, "open", true); + + if (lastdir) + BLI_strncpy(sfile->params->dir, lastdir, sizeof(sfile->params->dir)); + + + WM_operator_name_call(C, "FILE_OT_directory_new", WM_OP_INVOKE_DEFAULT, &ptr); + WM_operator_properties_free(&ptr); + } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } - - return OPERATOR_FINISHED; } -int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) +void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg_but) { SpaceFile *sfile = CTX_wm_space_file(C); + uiBut *but = arg_but; char matched_file[FILE_MAX]; + char filepath[sizeof(sfile->params->dir)]; + if (sfile->params) { + int matches; matched_file[0] = '\0'; - if (file_select_match(sfile, sfile->params->file, matched_file)) { + filepath[0] = '\0'; + + file_expand_directory(C); + + matches = file_select_match(sfile, sfile->params->file, matched_file); + + if (matches) { /* int i, numfiles = filelist_numfiles(sfile->files); */ /* XXX UNUSED */ sfile->params->file[0] = '\0'; /* replace the pattern (or filename that the user typed in, with the first selected file of the match */ @@ -1254,31 +1274,34 @@ int file_filename_exec(bContext *C, wmOperator *UNUSED(unused)) WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } - } - return OPERATOR_FINISHED; -} + if (matches == 1) { -/* TODO, directory operator is non-functional while a library is loaded - * until this is properly supported just disable it. */ -static int file_directory_poll(bContext *C) -{ - /* sfile->files can be NULL on file load */ - SpaceFile *sfile = CTX_wm_space_file(C); - return ED_operator_file_active(C) && (sfile->files == NULL || filelist_lib(sfile->files) == NULL); -} + BLI_join_dirfile(filepath, sizeof(sfile->params->dir), sfile->params->dir, sfile->params->file); -void FILE_OT_directory(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Enter Directory Name"; - ot->description = "Enter a directory name"; - ot->idname = "FILE_OT_directory"; - - /* api callbacks */ - ot->invoke = file_directory_invoke; - ot->exec = file_directory_exec; - ot->poll = file_directory_poll; /* <- important, handler is on window level */ + /* if directory, open it and empty filename field */ + if (BLI_is_dir(filepath)) { + BLI_cleanup_dir(G.main->name, filepath); + BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + sfile->params->file[0] = '\0'; + file_change_dir(C, 1); + UI_textbutton_activate_but(C, but); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + } + else if (sfile->params->type == FILE_LOADLIB) { + char tdir[FILE_MAX], tgroup[FILE_MAX]; + BLI_add_slash(filepath); + if (BLO_is_a_library(filepath, tdir, tgroup)) { + BLI_cleanup_dir(G.main->name, filepath); + BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); + sfile->params->file[0] = '\0'; + file_change_dir(C, 0); + UI_textbutton_activate_but(C, but); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); + } + } + } + } } void FILE_OT_refresh(struct wmOperatorType *ot) diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index f4161c7da1c..1809c6cb835 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -116,7 +116,7 @@ static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory cat but = uiDefIconTextButS(block, LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry); uiButSetFunc(but, file_panel_cb, entry, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - uiButSetFlag(but, UI_ICON_LEFT | UI_TEXT_LEFT); + uiButSetDrawFlag(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT); /* create delete button */ if (allow_delete && fsmenu_can_save(fsmenu, category, i)) { diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index a2f81498dd3..872960432d9 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -479,6 +479,17 @@ void folderlist_pushdir(ListBase *folderlist, const char *dir) BLI_addtail(folderlist, folder); } +const char *folderlist_peeklastdir(ListBase *folderlist) +{ + struct FolderList *folder; + + if (!folderlist->last) + return NULL; + + folder = folderlist->last; + return folder->foldername; +} + int folderlist_clear_next(struct SpaceFile *sfile) { struct FolderList *folder; diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index d093d427eae..eb99b0d21ab 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -98,6 +98,7 @@ void folderlist_free(struct ListBase *folderlist); struct ListBase * folderlist_duplicate(ListBase *folderlist); void folderlist_popdir(struct ListBase *folderlist, char *dir); void folderlist_pushdir(struct ListBase *folderlist, const char *dir); +const char * folderlist_peeklastdir(struct ListBase *folderdist); int folderlist_clear_next(struct SpaceFile *sfile); void thumbnails_start(struct FileList *filelist, const struct bContext *C); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index c6e1541352d..d329d505138 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -435,7 +435,7 @@ float file_string_width(const char *str) { uiStyle *style = UI_GetStyle(); uiStyleFontSet(&style->widget); - return BLF_width(style->widget.uifont_id, str); + return BLF_width(style->widget.uifont_id, str, BLF_DRAW_STR_DUMMY_MAX); } float file_font_pointsize(void) @@ -627,14 +627,14 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche if (!match) { BLI_strncpy(matched_file, file->relname, FILE_MAX); } - match = 1; + match++; } } return match; } -bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) +int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); int match = AUTOCOMPLETE_NO_MATCH; @@ -684,10 +684,10 @@ bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) } } - return match == AUTOCOMPLETE_FULL_MATCH; + return match; } -bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) +int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); int match = AUTOCOMPLETE_NO_MATCH; @@ -700,13 +700,14 @@ bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) for (i = 0; i < nentries; ++i) { struct direntry *file = filelist_file(sfile->files, i); - if (file && S_ISREG(file->type)) { + if (file && (S_ISREG(file->type) || S_ISDIR(file->type))) { autocomplete_do_name(autocpl, file->relname); } } match = autocomplete_end(autocpl, str); } - return match != AUTOCOMPLETE_NO_MATCH; + + return match; } void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile) diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 1a8565a58b1..62048752fa1 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -395,7 +395,6 @@ static void file_operatortypes(void) WM_operatortype_append(FILE_OT_delete); WM_operatortype_append(FILE_OT_rename); WM_operatortype_append(FILE_OT_smoothscroll); - WM_operatortype_append(FILE_OT_directory); } /* NOTE: do not add .blend file reading on this level */ diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 295f8bd9ff2..a01f4bcaaf1 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -301,11 +301,11 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) { uiItemL(col, IFACE_("Key:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); uiButSetUnitType(but, unit); @@ -315,11 +315,11 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); uiButSetUnitType(but, unit); @@ -329,11 +329,11 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) if (bezt->ipo == BEZT_IPO_BEZ) { uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); uiButSetUnitType(but, unit); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index db13e2a4024..a35395abaf2 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -872,11 +872,12 @@ void GRAPH_OT_duplicate(wmOperatorType *ot) /* ******************** Delete Keyframes Operator ************************* */ -static void delete_graph_keys(bAnimContext *ac) +static bool delete_graph_keys(bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; int filter; + bool changed = false; /* filter data */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); @@ -888,7 +889,7 @@ static void delete_graph_keys(bAnimContext *ac) AnimData *adt = ale->adt; /* delete selected keyframes only */ - delete_fcurve_keys(fcu); + changed |= delete_fcurve_keys(fcu); /* Only delete curve too if it won't be doing anything anymore */ if ((fcu->totvert == 0) && @@ -901,20 +902,23 @@ static void delete_graph_keys(bAnimContext *ac) /* free filtered list */ BLI_freelistN(&anim_data); + + return changed; } /* ------------------- */ -static int graphkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) +static int graphkeys_delete_exec(bContext *C, wmOperator *op) { bAnimContext ac; + bool changed; /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; /* delete keyframes */ - delete_graph_keys(&ac); + changed = delete_graph_keys(&ac); /* validate keyframes after editing */ ANIM_editkeyframes_refresh(&ac); @@ -922,6 +926,9 @@ static int graphkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* set notifier that keyframes have changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + if (changed) + BKE_report(op->reports, RPT_INFO, "Deleted selected keyframes"); + return OPERATOR_FINISHED; } @@ -933,7 +940,6 @@ void GRAPH_OT_delete(wmOperatorType *ot) ot->description = "Remove all selected keyframes"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = graphkeys_delete_exec; ot->poll = graphop_editable_keyframes_poll; diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index 50d8051a73e..62ac3c2d985 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC ../../render/extern/include ../../windowmanager ../../../../intern/guardedalloc + ../../gpu ) set(INC_SYS diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript index 89def32e70f..d878a726b55 100644 --- a/source/blender/editors/space_image/SConscript +++ b/source/blender/editors/space_image/SConscript @@ -42,6 +42,7 @@ incs = [ '../../makesrna', '../../render/extern/include', '../../windowmanager', + '../../gpu', ] incs = ' '.join(incs) diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 89e57955339..3d5f6a6ce7e 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -195,21 +195,21 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), "X:%-4d Y:%-4d |", x, y); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_Y, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); if (zp) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.4f |", 0.5f + 0.5f * (((float)*zp) / (float)0x7fffffff)); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } if (zpf) { glColor3ub(255, 255, 255); BLI_snprintf(str, sizeof(str), " Z:%-.3f |", *zpf); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } if (channels >= 3) { @@ -222,7 +222,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " R:-"); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); glColor3ubv(green); if (fp) @@ -233,7 +233,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " G:-"); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); glColor3ubv(blue); if (fp) @@ -244,7 +244,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " B:-"); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); if (channels == 4) { glColor3ub(255, 255, 255); @@ -256,7 +256,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), "- "); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } if (color_manage) { @@ -276,7 +276,7 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), " | CM R:%-.4f G:%-.4f B:%-.4f", rgba[0], rgba[1], rgba[2]); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } } @@ -350,12 +350,12 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), "V:%-.4f", val); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } else if (channels >= 3) { rgb_to_hsv(finalcol[0], finalcol[1], finalcol[2], &hue, &sat, &val); @@ -364,22 +364,22 @@ void ED_image_draw_info(Scene *scene, ARegion *ar, int color_manage, int use_def BLI_snprintf(str, sizeof(str), "H:%-.4f", hue); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " S:%-.4f", sat); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " V:%-.4f", val); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); BLI_snprintf(str, sizeof(str), " L:%-.4f", lum); BLF_position(blf_mono_font, dx, 0.3f * UI_UNIT_X, 0); BLF_draw_ascii(blf_mono_font, str, sizeof(str)); - dx += BLF_width(blf_mono_font, str); + dx += BLF_width(blf_mono_font, str, sizeof(str)); } (void)dx; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index b7d3407b826..2ea77bba681 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -58,6 +58,8 @@ #include "BKE_report.h" #include "BKE_screen.h" +#include "GPU_draw.h" + #include "IMB_colormanagement.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -85,6 +87,7 @@ #include "PIL_time.h" #include "image_intern.h" +#include "ED_sculpt.h" /******************** view navigation utilities *********************/ @@ -1792,6 +1795,8 @@ static int image_new_exec(bContext *C, wmOperator *op) else { Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data; if (tex && tex->type == TEX_IMAGE) { + if (tex->ima) + id_us_min(&tex->ima->id); tex->ima = ima; ED_area_tag_redraw(CTX_wm_area(C)); } @@ -1858,6 +1863,9 @@ static int image_invert_exec(bContext *C, wmOperator *op) { Image *ima = CTX_data_edit_image(C); ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + SpaceImage *sima = CTX_wm_space_image(C); + /* undo is supported only on image paint mode currently */ + bool support_undo = ((sima != NULL) && (sima->mode == SI_MODE_PAINT)); /* flags indicate if this channel should be inverted */ const short r = RNA_boolean_get(op->ptr, "invert_r"); @@ -1870,6 +1878,14 @@ static int image_invert_exec(bContext *C, wmOperator *op) if (ibuf == NULL) /* TODO: this should actually never happen, but does for render-results -> cleanup */ return OPERATOR_CANCELLED; + if (support_undo) { + ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name, + ED_image_undo_restore, ED_image_undo_free); + /* not strictly needed, because we only imapaint_dirty_region to invalidate all tiles + * but better do this right in case someone copies this for a tool that uses partial redraw better */ + ED_imapaint_clear_partial_redraw(); + ED_imapaint_dirty_region(ima, ibuf, 0, 0, ibuf->x, ibuf->y); + } /* TODO: make this into an IMB_invert_channels(ibuf,r,g,b,a) method!? */ if (ibuf->rect_float) { @@ -1901,9 +1917,16 @@ static int image_invert_exec(bContext *C, wmOperator *op) } ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; + if (ibuf->mipmap[0]) ibuf->userflags |= IB_MIPMAP_INVALID; + if (support_undo) + ED_undo_paint_push_end(UNDO_PAINT_IMAGE); + + /* force GPU reupload, all image is invalid */ + GPU_free_image(ima); + WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); BKE_image_release_ibuf(ima, ibuf, NULL); diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c index b096b8f3e2b..827e4427ca0 100644 --- a/source/blender/editors/space_info/info_report.c +++ b/source/blender/editors/space_info/info_report.c @@ -223,7 +223,7 @@ static int borderselect_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); ReportList *reports = CTX_wm_reports(C); int report_mask = info_report_mask(sinfo); - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); Report *report_min, *report_max, *report; //View2D *v2d = UI_view2d_fromcontext(C); @@ -231,7 +231,7 @@ static int borderselect_exec(bContext *C, wmOperator *op) rcti rect; //rctf rectf, rq; - short selecting = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); + const bool select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); //int mval[2]; WM_operator_properties_border_to_rcti(op, &rect); @@ -287,7 +287,7 @@ static int borderselect_exec(bContext *C, wmOperator *op) if ((report->type & report_mask) == 0) continue; - if (selecting) + if (select) report->flag |= SELECT; else report->flag &= ~SELECT; diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 9686c6dfc29..4babda08898 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -296,7 +296,16 @@ static void stats_dupli_object(Base *base, Object *ob, SceneStats *stats) } else if (ob->parent && (ob->parent->transflag & (OB_DUPLIVERTS | OB_DUPLIFACES))) { /* Dupli Verts/Faces */ - int tot = count_duplilist(ob->parent); + int tot; + + /* metaball dupli-instances are tessellated once */ + if (ob->type == OB_MBALL) { + tot = 1; + } + else { + tot = count_duplilist(ob->parent); + } + stats->totobj += tot; stats_object(ob, base->flag & SELECT, tot, stats); } diff --git a/source/blender/editors/space_info/space_info.c b/source/blender/editors/space_info/space_info.c index aaa52597357..96e0de17918 100644 --- a/source/blender/editors/space_info/space_info.c +++ b/source/blender/editors/space_info/space_info.c @@ -220,6 +220,9 @@ static void info_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "INFO_OT_report_delete", XKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "INFO_OT_report_delete", DELKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "INFO_OT_report_copy", CKEY, KM_PRESS, KM_CTRL, 0); +#ifdef __APPLE__ + WM_keymap_add_item(keymap, "INFO_OT_report_copy", CKEY, KM_PRESS, KM_OSKEY, 0); +#endif } /* add handlers, stuff you only do once or on area/region changes */ diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 30c7b5de2f1..6b0460ce5cd 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -32,7 +32,6 @@ set(INC ../../windowmanager ../../compositor ../../../../intern/guardedalloc - ../../../../intern/opennl/extern ) set(INC_SYS diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 50a4b515490..da599f8608d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -406,7 +406,7 @@ static void node_draw_frame_label(bNodeTree *ntree, bNode *node, const float asp /* title color */ UI_ThemeColorBlendShade(TH_TEXT, color_id, 0.8f, 10); - width = BLF_width(fontid, label); + width = BLF_width(fontid, label, sizeof(label)); ascender = BLF_ascender(fontid); /* 'x' doesn't need aspect correction */ @@ -753,6 +753,11 @@ static void node_shader_buts_geometry(uiLayout *layout, bContext *C, PointerRNA } } +static void node_shader_buts_lamp(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "lamp_object", 0, IFACE_("Lamp Object"), ICON_NONE); +} + static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "attribute_name", 0, IFACE_("Name"), ICON_NONE); @@ -1002,6 +1007,9 @@ static void node_shader_set_butfunc(bNodeType *ntype) case SH_NODE_GEOMETRY: ntype->draw_buttons = node_shader_buts_geometry; break; + case SH_NODE_LAMP: + ntype->draw_buttons = node_shader_buts_lamp; + break; case SH_NODE_ATTRIBUTE: ntype->draw_buttons = node_shader_buts_attribute; break; @@ -1635,7 +1643,7 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi else { col = uiLayoutColumn(layout, TRUE); - uiItemL(col, IFACE_("File Path:"), ICON_NONE); + uiItemL(col, IFACE_("File Subpath:"), ICON_NONE); row = uiLayoutRow(col, FALSE); uiItemR(row, &active_input_ptr, "path", 0, "", ICON_NONE); uiItemFullO(row, "NODE_OT_output_file_remove_active_socket", "", @@ -2002,7 +2010,7 @@ static void node_composit_backdrop_boxmask(SpaceNode *snode, ImBuf *backdrop, bN const float backdropWidth = backdrop->x; const float backdropHeight = backdrop->y; const float aspect = backdropWidth / backdropHeight; - const float rad = DEG2RADF(-boxmask->rotation); + const float rad = -boxmask->rotation; const float cosine = cosf(rad); const float sine = sinf(rad); const float halveBoxWidth = backdropWidth * (boxmask->width / 2.0f); @@ -2040,7 +2048,7 @@ static void node_composit_backdrop_ellipsemask(SpaceNode *snode, ImBuf *backdrop const float backdropWidth = backdrop->x; const float backdropHeight = backdrop->y; const float aspect = backdropWidth / backdropHeight; - const float rad = DEG2RADF(-ellipsemask->rotation); + const float rad = -ellipsemask->rotation; const float cosine = cosf(rad); const float sine = sinf(rad); const float halveBoxWidth = backdropWidth * (ellipsemask->width / 2.0f); @@ -3115,7 +3123,7 @@ int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, floa toreroute = 0; } - dist = UI_GetThemeValue(TH_NODE_CURVING) * 0.10f * ABS(vec[0][0] - vec[3][0]); + dist = UI_GetThemeValue(TH_NODE_CURVING) * 0.10f * fabsf(vec[0][0] - vec[3][0]); deltax = vec[3][0] - vec[0][0]; deltay = vec[3][1] - vec[0][1]; /* check direction later, for top sockets */ diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index 00769975893..4b1a06fa923 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -90,9 +90,6 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx ntreeUpdateTree(bmain, snode->edittree); ED_node_set_active(bmain, snode->edittree, node); - if (snode->flag & SNODE_USE_HIDDEN_PREVIEW) - node->flag &= ~NODE_PREVIEW; - snode_update(snode, node); if (snode->nodetree->type == NTREE_TEXTURE) { diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 6f2f8dee105..5ca853e6020 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -562,16 +562,21 @@ int node_tweak_area_default(bNode *node, int x, int y) int node_get_colorid(bNode *node) { switch (node->typeinfo->nclass) { - case NODE_CLASS_INPUT: return TH_NODE_IN_OUT; - case NODE_CLASS_OUTPUT: return (node->flag & NODE_DO_OUTPUT) ? TH_NODE_IN_OUT : TH_NODE; + case NODE_CLASS_INPUT: return TH_NODE_INPUT; + case NODE_CLASS_OUTPUT: return (node->flag & NODE_DO_OUTPUT) ? TH_NODE_OUTPUT : TH_NODE; case NODE_CLASS_CONVERTOR: return TH_NODE_CONVERTOR; - case NODE_CLASS_OP_COLOR: - case NODE_CLASS_OP_VECTOR: - case NODE_CLASS_OP_FILTER: return TH_NODE_OPERATOR; + case NODE_CLASS_OP_COLOR: return TH_NODE_COLOR; + case NODE_CLASS_OP_VECTOR: return TH_NODE_VECTOR; + case NODE_CLASS_OP_FILTER: return TH_NODE_FILTER; case NODE_CLASS_GROUP: return TH_NODE_GROUP; case NODE_CLASS_INTERFACE: return TH_NODE_INTERFACE; case NODE_CLASS_MATTE: return TH_NODE_MATTE; case NODE_CLASS_DISTORT: return TH_NODE_DISTORT; + case NODE_CLASS_TEXTURE: return TH_NODE_TEXTURE; + case NODE_CLASS_SHADER: return TH_NODE_SHADER; + case NODE_CLASS_SCRIPT: return TH_NODE_SCRIPT; + case NODE_CLASS_PATTERN: return TH_NODE_PATTERN; + case NODE_CLASS_LAYOUT: return TH_NODE_LAYOUT; default: return TH_NODE; } } diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 2e3e747618b..64326bd7993 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -448,7 +448,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool extend = RNA_boolean_get(op->ptr, "extend"); WM_operator_properties_border_to_rcti(op, &rect); @@ -573,7 +573,7 @@ void NODE_OT_select_circle(wmOperatorType *ot) /* ****** Lasso Select ****** */ -static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, short select) +static bool do_lasso_select_node(bContext *C, const int mcords[][2], short moves, short select) { SpaceNode *snode = CTX_wm_space_node(C); bNode *node; @@ -581,7 +581,7 @@ static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, ARegion *ar = CTX_wm_region(C); rcti rect; - int change = FALSE; + bool changed = false; /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); @@ -601,15 +601,15 @@ static int do_lasso_select_node(bContext *C, const int mcords[][2], short moves, BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) { nodeSetSelected(node, select); - change = TRUE; + changed = true; } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_NODE | NA_SELECTED, NULL); } - return change; + return changed; } static int node_lasso_select_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index a67a8791a64..b544e753965 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -436,6 +436,7 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) char name[UI_MAX_NAME_STR]; const char *cur_node_name = NULL; int i, num = 0; + int icon = ICON_NONE; if (compatibility && !(ntype->compatibility & compatibility)) continue; @@ -461,7 +462,6 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) uiItemL(column, IFACE_(cname), ICON_NODE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; first = 0; } @@ -469,18 +469,21 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) if (num > 1) { if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) { cur_node_name = items[i].node_name; - uiItemL(column, IFACE_(cur_node_name), ICON_NODE); - but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + /* XXX Do not use uiItemL here, it would add an empty icon as we are in a menu! */ + uiDefBut(block, LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, ""); } - - BLI_snprintf(name, UI_MAX_NAME_STR, " %s", IFACE_(items[i].socket_name)); + + BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(items[i].socket_name)); + icon = ICON_BLANK1; } - else + else { BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR); + icon = ICON_NONE; + } - but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, - NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input")); + but = uiDefIconTextBut(block, BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input")); argN = MEM_dupallocN(arg); argN->item = items[i]; @@ -528,7 +531,7 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_ if (sock->link) { uiItemL(column, IFACE_("Link"), ICON_NONE); but = block->buttons.last; - but->flag = UI_TEXT_LEFT; + but->drawflag = UI_BUT_TEXT_LEFT; but = uiDefBut(block, BUT, 0, IFACE_("Remove"), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Remove nodes connected to the input")); @@ -564,7 +567,8 @@ void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSo but = uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, ""); but->type = MENU; - but->flag |= UI_TEXT_LEFT | UI_BUT_NODE_LINK; + but->drawflag |= UI_BUT_TEXT_LEFT; + but->flag |= UI_BUT_NODE_LINK; but->poin = (char *)but; but->func_argN = arg; @@ -654,7 +658,7 @@ static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, uiItemL(row, label, ICON_NONE); bt = block->buttons.last; - bt->flag = UI_TEXT_LEFT; + bt->drawflag = UI_BUT_TEXT_LEFT; if (dependency_loop) { row = uiLayoutRow(split, FALSE); diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 6ae8a1f94b1..2fe63c4b895 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -555,11 +555,15 @@ static SpaceLink *node_duplicate(SpaceLink *sl) SpaceNode *snode = (SpaceNode *)sl; SpaceNode *snoden = MEM_dupallocN(snode); + BLI_duplicatelist(&snoden->treepath, &snode->treepath); + /* clear or remove stuff from old */ - snoden->nodetree = NULL; snoden->linkdrag.first = snoden->linkdrag.last = NULL; - - BLI_duplicatelist(&snoden->treepath, &snode->treepath); + + /* Note: no need to set node tree user counts, + * the editor only keeps at least 1 (id_us_ensure_real), + * which is already done by the original SpaceNode. + */ return (SpaceLink *)snoden; } diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 26fe2edd0d1..4db47b75502 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -28,7 +28,6 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc - ../../../../intern/opennl/extern ) set(INC_SYS diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 559fb6f932e..3f0ad45de56 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -273,18 +273,18 @@ static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), const wmEve SpaceOops *soops = CTX_wm_space_outliner(C); TreeElement *te; float fmval[2]; - bool change = false; + bool changed = false; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1); for (te = soops->tree.first; te; te = te->next) { if (do_outliner_item_rename(C, ar, soops, te, fmval)) { - change = true; + changed = true; break; } } - return change ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH; + return changed ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index d1d512409ee..b10b8a46ec6 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -78,7 +78,7 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se { TreeElement *te; TreeStoreElem *tselem; - int change = 0; + bool changed = false; for (te = lb->first; te && *index >= 0; te = te->next, (*index)--) { tselem = TREESTORE(te); @@ -101,7 +101,7 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se else tselem->flag &= ~TSE_SELECTED; - change |= 1; + changed |= true; } } else if (TSELEM_OPEN(tselem, soops)) { @@ -113,12 +113,12 @@ static int outliner_select(SpaceOops *soops, ListBase *lb, int *index, short *se * function correctly */ (*index)--; - change |= outliner_select(soops, &te->subtree, index, selecting); + changed |= outliner_select(soops, &te->subtree, index, selecting); (*index)++; } } - return change; + return changed; } /* ****************************************************** */ diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 63aa92517a7..2952bdb042c 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -826,8 +826,8 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) * may generate strips with the same name (which will mess up animdata) */ -static int cut_seq_list(Scene *scene, ListBase *slist, int cutframe, - Sequence * (*cut_seq)(Scene *, Sequence *, int)) +static bool cut_seq_list(Scene *scene, ListBase *slist, int cutframe, + Sequence * (*cut_seq)(Scene *, Sequence *, int)) { Sequence *seq, *seq_next_iter; Sequence *seq_first_new = NULL; @@ -1569,7 +1569,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op) Editing *ed = BKE_sequencer_editing_get(scene, FALSE); int cut_side, cut_hard, cut_frame; - int changed; + bool changed; cut_frame = RNA_int_get(op->ptr, "frame"); cut_hard = RNA_enum_get(op->ptr, "type"); @@ -1601,6 +1601,15 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op) } SEQ_END; } + + SEQP_BEGIN (ed, seq) + { + if (seq->seq1 || seq->seq2 || seq->seq3) { + BKE_sequence_calc(scene, seq); + } + } + SEQ_END; + /* as last: */ BKE_sequencer_sort(scene); } @@ -2075,7 +2084,6 @@ void SEQUENCER_OT_meta_make(wmOperatorType *ot) ot->description = "Group selected strips into a metastrip"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = sequencer_meta_make_exec; ot->poll = sequencer_edit_poll; @@ -2146,7 +2154,6 @@ void SEQUENCER_OT_meta_separate(wmOperatorType *ot) ot->description = "Put the contents of a metastrip back in the sequencer"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = sequencer_meta_separate_exec; ot->poll = sequencer_edit_poll; @@ -2479,20 +2486,20 @@ static int find_next_prev_edit(Scene *scene, int cfra, return cfra; } -static int strip_jump_internal(Scene *scene, - const short side, - const short do_skip_mute, const short do_center) +static bool strip_jump_internal(Scene *scene, + const short side, + const short do_skip_mute, const short do_center) { - int change = FALSE; + bool changed = false; int cfra = CFRA; int nfra = find_next_prev_edit(scene, cfra, side, do_skip_mute, do_center); if (nfra != cfra) { CFRA = nfra; - change = TRUE; + changed = true; } - return change; + return changed; } static int sequencer_strip_jump_poll(bContext *C) diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 45f05d56076..d1cc2091265 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -188,7 +188,7 @@ static void select_neighbor_from_last(Scene *scene, int lr) { Sequence *seq = BKE_sequencer_active_get(scene); Sequence *neighbor; - int change = 0; + bool changed = false; if (seq) { neighbor = find_neighboring_sequence(scene, seq, lr, -1); if (neighbor) { @@ -207,10 +207,10 @@ static void select_neighbor_from_last(Scene *scene, int lr) break; } seq->flag |= SELECT; - change = 1; + changed = true; } } - if (change) { + if (changed) { } } #endif @@ -553,14 +553,15 @@ void SEQUENCER_OT_select(wmOperatorType *ot) /* run recursively to select linked */ -static int select_more_less_seq__internal(Scene *scene, int sel, int linked) +static bool select_more_less_seq__internal(Scene *scene, bool sel, const bool linked) { Editing *ed = BKE_sequencer_editing_get(scene, FALSE); Sequence *seq, *neighbor; - int change = 0; + bool changed = false; int isel; - if (ed == NULL) return 0; + if (ed == NULL) + return changed; if (sel) { sel = SELECT; @@ -587,20 +588,20 @@ static int select_more_less_seq__internal(Scene *scene, int sel, int linked) if (sel) { neighbor->flag |= SELECT; recurs_sel_seq(neighbor); } else neighbor->flag &= ~SELECT; if (linked == 0) neighbor->tmp = (Sequence *)1; - change = 1; + changed = true; } neighbor = find_neighboring_sequence(scene, seq, SEQ_SIDE_RIGHT, isel); if (neighbor) { if (sel) { neighbor->flag |= SELECT; recurs_sel_seq(neighbor); } else neighbor->flag &= ~SELECT; if (linked == 0) neighbor->tmp = (void *)1; - change = 1; + changed = true; } } } } - return change; + return changed; } @@ -850,8 +851,8 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op) Sequence *seq; rcti rect; rctf rectf, rq; - short selecting = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); - int extend = RNA_boolean_get(op->ptr, "extend"); + const bool select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT); + const bool extend = RNA_boolean_get(op->ptr, "extend"); int mval[2]; if (ed == NULL) @@ -870,7 +871,7 @@ static int sequencer_borderselect_exec(bContext *C, wmOperator *op) seq_rectf(seq, &rq); if (BLI_rctf_isect(&rq, &rectf, NULL)) { - if (selecting) seq->flag |= SELECT; + if (select) seq->flag |= SELECT; else seq->flag &= ~SEQ_ALLSEL; recurs_sel_seq(seq); } @@ -930,16 +931,16 @@ static EnumPropertyItem sequencer_prop_select_grouped_types[] = { #define SEQ_USE_DATA(_seq) (ELEM3(_seq->type, SEQ_TYPE_SCENE, SEQ_TYPE_MOVIECLIP, SEQ_TYPE_MASK) || SEQ_HAS_PATH(_seq)) -static short select_grouped_type(Editing *ed, Sequence *actseq) +static bool select_grouped_type(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; SEQP_BEGIN (ed, seq) { if (seq->type == actseq->type) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -947,17 +948,17 @@ static short select_grouped_type(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_type_basic(Editing *ed, Sequence *actseq) +static bool select_grouped_type_basic(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; short is_sound = SEQ_IS_SOUND(actseq); SEQP_BEGIN (ed, seq) { if (is_sound ? SEQ_IS_SOUND(seq) : !SEQ_IS_SOUND(seq)) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -965,17 +966,17 @@ static short select_grouped_type_basic(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_type_effect(Editing *ed, Sequence *actseq) +static bool select_grouped_type_effect(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; short is_effect = SEQ_IS_EFFECT(actseq); SEQP_BEGIN (ed, seq) { if (is_effect ? SEQ_IS_EFFECT(seq) : !SEQ_IS_EFFECT(seq)) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -983,10 +984,10 @@ static short select_grouped_type_effect(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_data(Editing *ed, Sequence *actseq) +static bool select_grouped_data(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; char *dir = actseq->strip ? actseq->strip->dir : NULL; if (!SEQ_USE_DATA(actseq)) @@ -997,7 +998,7 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) { if (SEQ_HAS_PATH(seq) && seq->strip && strcmp(seq->strip->dir, dir) == 0) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1008,7 +1009,7 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) { if (seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1019,7 +1020,7 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) { if (seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1030,7 +1031,7 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) { if (seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1039,10 +1040,10 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_effect(Editing *ed, Sequence *actseq) +static bool select_grouped_effect(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; short effects[SEQ_TYPE_EFFECT_MAX + 1]; int i; @@ -1063,7 +1064,7 @@ static short select_grouped_effect(Editing *ed, Sequence *actseq) if (seq->seq1) seq->seq1->flag |= SELECT; if (seq->seq2) seq->seq2->flag |= SELECT; if (seq->seq3) seq->seq3->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1071,16 +1072,16 @@ static short select_grouped_effect(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_time_overlap(Editing *ed, Sequence *actseq) +static bool select_grouped_time_overlap(Editing *ed, Sequence *actseq) { Sequence *seq; - short changed = FALSE; + bool changed = false; SEQP_BEGIN (ed, seq) { if (!((seq->startdisp >= actseq->enddisp) || (seq->enddisp < actseq->startdisp))) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } SEQ_END; @@ -1088,10 +1089,10 @@ static short select_grouped_time_overlap(Editing *ed, Sequence *actseq) return changed; } -static short select_grouped_effect_link(Editing *ed, Sequence *actseq) +static bool select_grouped_effect_link(Editing *ed, Sequence *actseq) { Sequence *seq = NULL; - short changed = FALSE; + bool changed = false; short is_audio = ((actseq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(actseq)); int startdisp = actseq->startdisp; int enddisp = actseq->enddisp; @@ -1131,7 +1132,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) seq->tmp = SET_INT_IN_POINTER(TRUE); seq->flag |= SELECT; - changed = TRUE; + changed = true; /* Unfortunately, we must restart checks from the beginning. */ BKE_sequence_iterator_end(&iter); @@ -1141,7 +1142,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) /* Video strips bellow active one, or any strip for audio (order do no matters here!). */ else if (seq->machine < machine || is_audio) { seq->flag |= SELECT; - changed = TRUE; + changed = true; } } BKE_sequence_iterator_end(&iter); @@ -1159,7 +1160,7 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) Editing *ed = BKE_sequencer_editing_get(scene, 0); Sequence *seq, *actseq = BKE_sequencer_active_get(scene); int type = RNA_enum_get(op->ptr, "type"); - short changed = 0, extend; + bool changed = false, extend; extend = RNA_boolean_get(op->ptr, "extend"); @@ -1172,7 +1173,7 @@ static int sequencer_select_grouped_exec(bContext *C, wmOperator *op) SEQP_BEGIN (ed, seq) { seq->flag &= ~SELECT; - changed = TRUE; + changed = true; } SEQ_END; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 4a4754e8adc..ae34754b108 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -234,28 +234,28 @@ static void sequencer_refresh(const bContext *C, ScrArea *sa) SpaceSeq *sseq = (SpaceSeq *)sa->spacedata.first; ARegion *ar_main = sequencer_find_region(sa, RGN_TYPE_WINDOW); ARegion *ar_preview = sequencer_find_region(sa, RGN_TYPE_PREVIEW); - int view_changed = 0; + bool view_changed = false; switch (sseq->view) { case SEQ_VIEW_SEQUENCE: if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) { ar_main->flag &= ~RGN_FLAG_HIDDEN; ar_main->v2d.flag &= ~V2D_IS_INITIALISED; - view_changed = 1; + view_changed = true; } if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) { ar_preview->flag |= RGN_FLAG_HIDDEN; ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; WM_event_remove_handlers((bContext *)C, &ar_preview->handlers); - view_changed = 1; + view_changed = true; } if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { ar_main->alignment = RGN_ALIGN_NONE; - view_changed = 1; + view_changed = true; } if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { ar_preview->alignment = RGN_ALIGN_NONE; - view_changed = 1; + view_changed = true; } break; case SEQ_VIEW_PREVIEW: @@ -263,42 +263,42 @@ static void sequencer_refresh(const bContext *C, ScrArea *sa) ar_main->flag |= RGN_FLAG_HIDDEN; ar_main->v2d.flag &= ~V2D_IS_INITIALISED; WM_event_remove_handlers((bContext *)C, &ar_main->handlers); - view_changed = 1; + view_changed = true; } if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { ar_preview->flag &= ~RGN_FLAG_HIDDEN; ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; ar_preview->v2d.cur = ar_preview->v2d.tot; - view_changed = 1; + view_changed = true; } if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { ar_main->alignment = RGN_ALIGN_NONE; - view_changed = 1; + view_changed = true; } if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { ar_preview->alignment = RGN_ALIGN_NONE; - view_changed = 1; + view_changed = true; } break; case SEQ_VIEW_SEQUENCE_PREVIEW: if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) { ar_main->flag &= ~RGN_FLAG_HIDDEN; ar_main->v2d.flag &= ~V2D_IS_INITIALISED; - view_changed = 1; + view_changed = true; } if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { ar_preview->flag &= ~RGN_FLAG_HIDDEN; ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; ar_preview->v2d.cur = ar_preview->v2d.tot; - view_changed = 1; + view_changed = true; } if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { ar_main->alignment = RGN_ALIGN_NONE; - view_changed = 1; + view_changed = true; } if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) { ar_preview->alignment = RGN_ALIGN_TOP; - view_changed = 1; + view_changed = true; } break; } diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c index ee64d680319..37f7cf13928 100644 --- a/source/blender/editors/space_text/space_text.c +++ b/source/blender/editors/space_text/space_text.c @@ -534,7 +534,7 @@ static void text_properties_area_draw(const bContext *C, ARegion *ar) /* this flag trick is make sure buttons have been added already */ if (st->flags & ST_FIND_ACTIVATE) { - if (UI_textbutton_activate_event(C, ar, st, "find_text")) { + if (UI_textbutton_activate_rna(C, ar, st, "find_text")) { /* if the panel was already open we need to do another redraw */ ScrArea *sa = CTX_wm_area(C); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_TEXT, sa); diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 7d5cff6a2d0..51477ec2ae7 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -46,9 +46,11 @@ set(SRC drawvolume.c space_view3d.c view3d_buttons.c + view3d_camera_control.c view3d_draw.c view3d_edit.c view3d_fly.c + view3d_walk.c view3d_header.c view3d_iterators.c view3d_ops.c diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index de6fafb2cd8..8aced487160 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -1878,7 +1878,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* if solid && posemode, we draw again with polygonoffset */ else if ((dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) { - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); } else { /* and we use selection indices if not done yet */ @@ -1986,7 +1986,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* restore things */ if (!ELEM(arm->drawtype, ARM_WIRE, ARM_LINE) && (dt > OB_WIRE) && (arm->flag & ARM_POSEMODE)) - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); } /* restore */ @@ -2154,7 +2154,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) index = 0; } else if (dt > OB_WIRE) - bglPolygonOffset(rv3d->dist, 1.0f); + ED_view3d_polygon_offset(rv3d, 1.0); else if (arm->flag & ARM_EDITMODE) index = 0; /* do selection codes */ @@ -2221,7 +2221,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) /* pass */ } else if (dt > OB_WIRE) { - bglPolygonOffset(rv3d->dist, 0.0f); + ED_view3d_polygon_offset(rv3d, 0.0); } /* finally names and axes */ diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index a08a6cc1478..52897aa023e 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -170,7 +170,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); /* Draw (Hidden) Edges */ setlinestyle(1); @@ -188,7 +188,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) glDisable(GL_BLEND); } - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); /* Draw Stippled Outline for selected faces */ glColor3ub(255, 255, 255); @@ -196,7 +196,7 @@ void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); setlinestyle(0); - bglPolygonOffset(rv3d->dist, 0.0); /* resets correctly now, even after calling accumulated offsets */ + ED_view3d_polygon_offset(rv3d, 0.0); /* resets correctly now, even after calling accumulated offsets */ MEM_freeN(data.edge_flags); } @@ -1055,7 +1055,7 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const boo * rather than the shading, this is also forced in wire view */ if (use_depth) { - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ } else { @@ -1070,7 +1070,7 @@ void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const boo dm->drawMappedEdges(dm, (DMSetDrawOptions)edgemask_cb, user_data); if (use_depth) { - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); glDepthMask(1); } else { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 2083da2d64f..225c58207e7 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1210,18 +1210,16 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* skip drawing extra info */ } else if ((la->type == LA_SPOT) || (la->type == LA_YF_PHOTON)) { - lvec[0] = lvec[1] = 0.0; - lvec[2] = 1.0; - x = rv3d->persmat[0][2]; - y = rv3d->persmat[1][2]; - z = rv3d->persmat[2][2]; - vvec[0] = x * ob->obmat[0][0] + y * ob->obmat[0][1] + z * ob->obmat[0][2]; - vvec[1] = x * ob->obmat[1][0] + y * ob->obmat[1][1] + z * ob->obmat[1][2]; - vvec[2] = x * ob->obmat[2][0] + y * ob->obmat[2][1] + z * ob->obmat[2][2]; - - y = cosf(la->spotsize * (float)(M_PI / 360.0)); - spotvolume(lvec, vvec, y); + + copy_v3_fl3(lvec, 0.0f, 0.0f, 1.0f); + copy_v3_fl3(vvec, rv3d->persmat[0][2], rv3d->persmat[1][2], rv3d->persmat[2][2]); + mul_mat3_m4_v3(ob->obmat, vvec); + x = -la->dist; + y = cosf(la->spotsize * 0.5f); + z = x * sqrtf(1.0f - y * y); + + spotvolume(lvec, vvec, y); mul_v3_fl(lvec, x); mul_v3_fl(vvec, x); @@ -1232,7 +1230,6 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glVertex3fv(lvec); glEnd(); - z = x * sqrtf(1.0f - y * y); x *= y; /* draw the circle/square at the end of the cone */ @@ -3126,7 +3123,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, if (dt > OB_WIRE) { draw_mesh_paint_weight_faces(finalDM, true, draw_em_fancy__setFaceOpts, me->edit_btmesh); - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); glDepthMask(0); } else { @@ -3176,7 +3173,7 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, * write to show selected edge wires better */ UI_ThemeColor(TH_WIRE_EDIT); - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); glDepthMask(0); } else { @@ -3322,12 +3319,12 @@ static void draw_em_fancy(Scene *scene, ARegion *ar, View3D *v3d, if (dt > OB_WIRE) { glDepthMask(1); - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); GPU_disable_material(); } #if 0 /* currently not needed */ else if (use_occlude_wire) { - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); } #endif } @@ -3568,7 +3565,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D * otherwise this wire is to overlay solid mode faces so do some depth buffer tricks. */ if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ } @@ -3576,7 +3573,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if (dt != OB_WIRE && (draw_wire == OBDRAW_WIRE_ON_DEPTH)) { glDepthMask(1); - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); } } @@ -3586,10 +3583,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); if (!use_depth) glDisable(GL_DEPTH_TEST); - else bglPolygonOffset(rv3d->dist, 1.0); + else ED_view3d_polygon_offset(rv3d, 1.0); drawSelectedVertices(dm, ob->data); if (!use_depth) glEnable(GL_DEPTH_TEST); - else bglPolygonOffset(rv3d->dist, 0.0); + else ED_view3d_polygon_offset(rv3d, 0.0); glPointSize(1.0f); } @@ -4058,7 +4055,7 @@ static bool drawDispList_nobackface(Scene *scene, View3D *v3d, RegionView3D *rv3 if (BKE_mball_is_basis(ob)) { lb = ob->curve_cache ? &ob->curve_cache->disp : NULL; - if (ELEM(lb, lb->first, NULL)) { + if (ELEM(NULL, lb, lb->first)) { BKE_displist_make_mball(scene, ob); lb = &ob->curve_cache->disp; } @@ -5759,7 +5756,7 @@ static void draw_empty_cone(float size) static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2]) { cpack(0); - bglPolygonOffset(rv3d->dist, -1.0); + ED_view3d_polygon_offset(rv3d, -1.0); set_inverted_drawing(1); glBegin(GL_QUADS); glVertex2fv(textcurs[0]); @@ -5768,7 +5765,7 @@ static void draw_textcurs(RegionView3D *rv3d, float textcurs[4][2]) glVertex2fv(textcurs[3]); glEnd(); set_inverted_drawing(0); - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); } static void drawspiral(const float cent[3], float rad, float tmat[4][4], int start) @@ -6380,7 +6377,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign glColor3ubv(ob_wire_col); } - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) { @@ -6406,7 +6403,7 @@ static void draw_wire_extra(Scene *scene, RegionView3D *rv3d, Object *ob, unsign } glDepthMask(1); - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); } } @@ -7559,7 +7556,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec else bm_solidoffs = 1; - bglPolygonOffset(rv3d->dist, 1.0); + ED_view3d_polygon_offset(rv3d, 1.0); /* we draw edges always, for loop (select) tools */ bbs_mesh_wire(em, dm, bm_solidoffs); @@ -7574,7 +7571,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec bm_vertoffs = bm_wireoffs; } - bglPolygonOffset(rv3d->dist, 0.0); + ED_view3d_polygon_offset(rv3d, 0.0); dm->release(dm); } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index b803a4a8473..3f7d599f5d5 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -46,6 +46,7 @@ #include "BKE_icons.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "ED_render.h" @@ -260,6 +261,19 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d) } #endif +static void view3d_stop_render_preview(wmWindowManager *wm, ARegion *ar) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->render_engine) { + WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW); + if (rv3d->render_engine->re) + RE_Database_Free(rv3d->render_engine->re); + RE_engine_free(rv3d->render_engine); + rv3d->render_engine = NULL; + } +} + void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) { wmWindowManager *wm = bmain->wm.first; @@ -268,15 +282,8 @@ void ED_view3d_shade_update(Main *bmain, View3D *v3d, ScrArea *sa) ARegion *ar; for (ar = sa->regionbase.first; ar; ar = ar->next) { - RegionView3D *rv3d = ar->regiondata; - - if (rv3d && rv3d->render_engine) { - WM_jobs_kill_type(wm, ar, WM_JOB_TYPE_RENDER_PREVIEW); - if (rv3d->render_engine->re) - RE_Database_Free(rv3d->render_engine->re); - RE_engine_free(rv3d->render_engine); - rv3d->render_engine = NULL; - } + if (ar->regiondata) + view3d_stop_render_preview(wm, ar); } } } @@ -507,14 +514,11 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) } -static void view3d_main_area_exit(wmWindowManager *UNUSED(wm), ARegion *ar) +static void view3d_main_area_exit(wmWindowManager *wm, ARegion *ar) { RegionView3D *rv3d = ar->regiondata; - if (rv3d->render_engine) { - RE_engine_free(rv3d->render_engine); - rv3d->render_engine = NULL; - } + view3d_stop_render_preview(wm, ar); if (rv3d->gpuoffscreen) { GPU_offscreen_free(rv3d->gpuoffscreen); @@ -770,6 +774,7 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN case ND_OB_VISIBLE: case ND_LAYER: case ND_RENDER_OPTIONS: + case ND_MARKERS: case ND_MODE: ED_region_tag_redraw(ar); break; @@ -827,7 +832,9 @@ static void view3d_main_area_listener(bScreen *sc, ScrArea *sa, ARegion *ar, wmN case ND_SHADING: case ND_NODES: if ((v3d->drawtype == OB_MATERIAL) || - (v3d->drawtype == OB_TEXTURE && scene->gm.matmode == GAME_MAT_GLSL)) + (v3d->drawtype == OB_TEXTURE && + (scene->gm.matmode == GAME_MAT_GLSL || + BKE_scene_use_new_shading_nodes(scene)))) { ED_region_tag_redraw(ar); } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c4fdacaa915..3b4405a2c1c 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -422,11 +422,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } /* Curve... */ else if (totcurvedata == 1) { - uiDefButR(block, NUM, 0, IFACE_("Weight"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); - uiDefButR(block, NUM, 0, IFACE_("Radius"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, NUM, 0, IFACE_("Radius:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); - uiDefButR(block, NUM, 0, IFACE_("Tilt"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, NUM, 0, IFACE_("Tilt:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "tilt", 0, -tilt_limit, tilt_limit, 1, 3, NULL); } else if (totcurvedata > 1) { @@ -444,7 +444,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } /* Lattice... */ else if (totlattdata == 1) { - uiDefButR(block, NUM, 0, IFACE_("Weight"), 0, yi -= buth + but_margin, 200, buth, + uiDefButR(block, NUM, 0, IFACE_("Weight:"), 0, yi -= buth + but_margin, 200, buth, &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); } else if (totlattdata > 1) { @@ -859,7 +859,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) xco, yco, (x = UI_UNIT_X * 5), UI_UNIT_Y, ""); but_ptr = uiButGetOperatorPtrRNA(but); RNA_int_set(but_ptr, "weight_group", i); - uiButSetFlag(but, UI_TEXT_RIGHT); + uiButSetDrawFlag(but, UI_BUT_TEXT_RIGHT); if (ob->actdef != i + 1) { uiButSetFlag(but, UI_BUT_INACTIVE); } @@ -873,7 +873,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *pa) but = uiDefButF(block, NUM, B_VGRP_PNL_EDIT_SINGLE + i, "", xco, yco, (x = UI_UNIT_X * 4), UI_UNIT_Y, &dw->weight, 0.0, 1.0, 1, 3, ""); - uiButSetFlag(but, UI_TEXT_LEFT); + uiButSetDrawFlag(but, UI_BUT_TEXT_LEFT); if (locked) { lock_count++; } diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c new file mode 100644 index 00000000000..2797125485c --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -0,0 +1,364 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_camera_control.c + * \ingroup spview3d + * + * The purpose of View3DCameraControl is to allow editing \a rv3d manipulation + * (mainly \a ofs and \a viewquat) for the purpose of view navigation + * without having to worry about positioning the camera, its parent... + * or other details. + * + * + * Typical view-control usage: + * + * - aquire a view-control (#ED_view3d_control_aquire). + * - modify ``rv3d->ofs``, ``rv3d->viewquat``. + * - update the view data (#ED_view3d_control_aquire) - within a loop which draws the viewport. + * - finish and release the view-control (#ED_view3d_control_release), + * either keeping the current view or restoring the initial view. + * + * Notes: + * + * - when acquiring ``rv3d->dist`` is set to zero + * (so ``rv3d->ofs`` is always the view-point) + * - updating can optionally keyframe the camera object. + */ + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_camera_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_object.h" + +#include "BKE_depsgraph.h" /* for object updating */ + +#include "ED_keyframing.h" +#include "ED_screen.h" + +#include "view3d_intern.h" /* own include */ + +#include "BLI_strict_flags.h" + + +typedef struct View3DCameraControl { + + /* -------------------------------------------------------------------- */ + /* Context (assign these to vars before use) */ + Scene *ctx_scene; + View3D *ctx_v3d; + RegionView3D *ctx_rv3d; + + + /* -------------------------------------------------------------------- */ + /* internal vars */ + + /* for parenting calculation */ + float view_mat_prev[4][4]; + + + /* -------------------------------------------------------------------- */ + /* optional capabilities */ + + bool use_parent_root; + + + /* -------------------------------------------------------------------- */ + /* intial values */ + + /* root most parent */ + Object *root_parent; + + /* backup values */ + float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ + float ofs_backup[3]; /* backup the views offset in case the user cancels flying in non camera mode */ + + /* backup the views quat in case the user cancels flying in non camera mode. + * (quat for view, eul for camera) */ + float rot_backup[4]; + char persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ + + /* are we flying an ortho camera in perspective view, + * which was originally in ortho view? + * could probably figure it out but better be explicit */ + bool is_ortho_cam; + + void *obtfm; /* backup the objects transform */ +} View3DCameraControl; + + +BLI_INLINE Object *view3d_cameracontrol_object(View3DCameraControl *vctrl) +{ + return vctrl->root_parent ? vctrl->root_parent : vctrl->ctx_v3d->camera; +} + + +/** + * Returns the object which is being manipulated or NULL. + */ +Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl) +{ + RegionView3D *rv3d = vctrl->ctx_rv3d; + + if (rv3d->persp == RV3D_CAMOB) { + return view3d_cameracontrol_object(vctrl); + } + else { + return NULL; + } +} + + +/** + * Creates a #View3DControl handle and sets up + * the view for first-person style navigation. + */ +struct View3DCameraControl *ED_view3d_cameracontrol_aquire( + Scene *scene, View3D *v3d, RegionView3D *rv3d, + const bool use_parent_root) +{ + View3DCameraControl *vctrl; + + vctrl = MEM_callocN(sizeof(View3DCameraControl), __func__); + + /* Store context */ + vctrl->ctx_scene = scene; + vctrl->ctx_v3d = v3d; + vctrl->ctx_rv3d = rv3d; + + vctrl->use_parent_root = use_parent_root; + + vctrl->persp_backup = rv3d->persp; + vctrl->dist_backup = rv3d->dist; + + /* check for flying ortho camera - which we cant support well + * we _could_ also check for an ortho camera but this is easier */ + if ((rv3d->persp == RV3D_CAMOB) && + (rv3d->is_persp == false)) + { + ((Camera *)v3d->camera->data)->type = CAM_PERSP; + vctrl->is_ortho_cam = true; + } + + if (rv3d->persp == RV3D_CAMOB) { + Object *ob_back; + if (use_parent_root && (vctrl->root_parent = v3d->camera->parent)) { + while (vctrl->root_parent->parent) + vctrl->root_parent = vctrl->root_parent->parent; + ob_back = vctrl->root_parent; + } + else { + ob_back = v3d->camera; + } + + /* store the original camera loc and rot */ + vctrl->obtfm = BKE_object_tfm_backup(ob_back); + + BKE_object_where_is_calc(scene, v3d->camera); + negate_v3_v3(rv3d->ofs, v3d->camera->obmat[3]); + + rv3d->dist = 0.0; + } + else { + float tvec[3]; + /* perspective or ortho */ + if (rv3d->persp == RV3D_ORTHO) + rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ + + copy_qt_qt(vctrl->rot_backup, rv3d->viewquat); + copy_v3_v3(vctrl->ofs_backup, rv3d->ofs); + + /* the dist defines a vector that is infront of the offset + * to rotate the view about. + * this is no good for fly mode because we + * want to rotate about the viewers center. + * but to correct the dist removal we must + * alter offset so the view doesn't jump. */ + + rv3d->dist = 0.0f; + + copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup); + mul_mat3_m4_v3(rv3d->viewinv, tvec); + sub_v3_v3(rv3d->ofs, tvec); + /* Done with correcting for the dist */ + } + + ED_view3d_to_m4(vctrl->view_mat_prev, rv3d->ofs, rv3d->viewquat, rv3d->dist); + + return vctrl; +} + + +/** + * Updates cameras from the ``rv3d`` values, optionally auto-keyframing. + */ +void ED_view3d_cameracontrol_update( + View3DCameraControl *vctrl, + /* args for keyframing */ + const bool use_autokey, + struct bContext *C, const bool do_rotate, const bool do_translate) +{ + /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ + + Scene *scene = vctrl->ctx_scene; + View3D *v3d = vctrl->ctx_v3d; + RegionView3D *rv3d = vctrl->ctx_rv3d; + + ID *id_key; + + /* transform the parent or the camera? */ + if (vctrl->root_parent) { + Object *ob_update; + + float view_mat[4][4]; + float prev_view_imat[4][4]; + float diff_mat[4][4]; + float parent_mat[4][4]; + + invert_m4_m4(prev_view_imat, vctrl->view_mat_prev); + ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); + mul_m4_m4m4(diff_mat, view_mat, prev_view_imat); + mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat); + + BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false); + + ob_update = v3d->camera->parent; + while (ob_update) { + DAG_id_tag_update(&ob_update->id, OB_RECALC_OB); + ob_update = ob_update->parent; + } + + copy_m4_m4(vctrl->view_mat_prev, view_mat); + + id_key = &vctrl->root_parent->id; + } + else { + float view_mat[4][4]; + float size_mat[4][4]; + float size_back[3]; + + /* even though we handle the size matrix, this still changes over time */ + copy_v3_v3(size_back, v3d->camera->size); + + ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); + size_to_mat4(size_mat, v3d->camera->size); + mul_m4_m4m4(view_mat, view_mat, size_mat); + + BKE_object_apply_mat4(v3d->camera, view_mat, true, true); + + copy_v3_v3(v3d->camera->size, size_back); + + id_key = &v3d->camera->id; + } + + /* record the motion */ + if (use_autokey && autokeyframe_cfra_can_key(scene, id_key)) { + ListBase dsources = {NULL, NULL}; + + /* add data-source override for the camera object */ + ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); + + /* insert keyframes + * 1) on the first frame + * 2) on each subsequent frame + * TODO: need to check in future that frame changed before doing this + */ + if (do_rotate) { + struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + if (do_translate) { + struct KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); + ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); + } + + /* free temp data */ + BLI_freelistN(&dsources); + } +} + + +/** + * Release view control. + * + * \param restore Sets the view state to the values that were set + * before #ED_view3d_control_aquire was called. + */ +void ED_view3d_cameracontrol_release( + View3DCameraControl *vctrl, + const bool restore) +{ + View3D *v3d = vctrl->ctx_v3d; + RegionView3D *rv3d = vctrl->ctx_rv3d; + + rv3d->dist = vctrl->dist_backup; + if (restore) { + /* Revert to original view? */ + if (vctrl->persp_backup == RV3D_CAMOB) { /* a camera view */ + Object *ob_back = view3d_cameracontrol_object(vctrl); + + /* store the original camera loc and rot */ + BKE_object_tfm_restore(ob_back, vctrl->obtfm); + + DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); + } + else { + /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ + copy_qt_qt(rv3d->viewquat, vctrl->rot_backup); + rv3d->persp = vctrl->persp_backup; + } + /* always, is set to zero otherwise */ + copy_v3_v3(rv3d->ofs, vctrl->ofs_backup); + } + else if (vctrl->persp_backup == RV3D_CAMOB) { /* camera */ + DAG_id_tag_update((ID *)view3d_cameracontrol_object(vctrl), OB_RECALC_OB); + + /* always, is set to zero otherwise */ + copy_v3_v3(rv3d->ofs, vctrl->ofs_backup); + } + else { /* not camera */ + float tvec[3]; + + /* Apply the fly mode view */ + /* restore the dist */ + copy_v3_fl3(tvec, 0.0f, 0.0f, vctrl->dist_backup); + mul_mat3_m4_v3(rv3d->viewinv, tvec); + add_v3_v3(rv3d->ofs, tvec); + /* Done with correcting for the dist */ + } + + if (vctrl->is_ortho_cam) { + ((Camera *)v3d->camera->data)->type = CAM_ORTHO; + } + + if (vctrl->obtfm) { + MEM_freeN(vctrl->obtfm); + } + + MEM_freeN(vctrl); +} diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index dc00e55e0f4..9dd6ab8f841 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -583,7 +583,9 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect) float ydisp = 0.0; /* vertical displacement to allow obj info text */ int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */ float vec[3]; + char axis_text[2] = "x"; float dx, dy; + int i; startx += rect->xmin; starty += rect->ymin; @@ -594,60 +596,27 @@ static void draw_view_axis(RegionView3D *rv3d, rcti *rect) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - /* X */ - vec[0] = 1; - vec[1] = vec[2] = 0; - mul_qt_v3(rv3d->viewquat, vec); - dx = vec[0] * k; - dy = vec[1] * k; - - UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright); - glBegin(GL_LINES); - glVertex2f(startx, starty + ydisp); - glVertex2f(startx + dx, starty + dy + ydisp); - glEnd(); - - if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1); - } - - /* BLF_draw_default disables blending */ - glEnable(GL_BLEND); - - /* Y */ - vec[1] = 1; - vec[0] = vec[2] = 0; - mul_qt_v3(rv3d->viewquat, vec); - dx = vec[0] * k; - dy = vec[1] * k; - - UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright); - glBegin(GL_LINES); - glVertex2f(startx, starty + ydisp); - glVertex2f(startx + dx, starty + dy + ydisp); - glEnd(); + for (i = 0; i < 3; i++) { + zero_v3(vec); + vec[i] = 1.0f; + mul_qt_v3(rv3d->viewquat, vec); + dx = vec[0] * k; + dy = vec[1] * k; - if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1); - } + UI_ThemeColorShadeAlpha(TH_AXIS_X + i, 0, bright); + glBegin(GL_LINES); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); + glEnd(); - glEnable(GL_BLEND); - - /* Z */ - vec[2] = 1; - vec[1] = vec[0] = 0; - mul_qt_v3(rv3d->viewquat, vec); - dx = vec[0] * k; - dy = vec[1] * k; + if (fabsf(dx) > toll || fabsf(dy) > toll) { + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, axis_text, 1); + } - UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright); - glBegin(GL_LINES); - glVertex2f(startx, starty + ydisp); - glVertex2f(startx + dx, starty + dy + ydisp); - glEnd(); + axis_text[0]++; - if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1); + /* BLF_draw_default disables blending */ + glEnable(GL_BLEND); } /* restore line-width */ @@ -2050,7 +2019,9 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas /* lamp drawing messes with matrices, could be handled smarter... but this works */ (dob->ob->type == OB_LAMP) || (dob->type == OB_DUPLIGROUP && dob->animated) || - !(bb_tmp = BKE_object_boundbox_get(dob->ob))) + !(bb_tmp = BKE_object_boundbox_get(dob->ob)) || + draw_glsl_material(scene, dob->ob, v3d, dt) || + (base->object == OBACT && v3d->flag2 & V3D_SOLID_MATCAP)) { // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2); use_displist = false; @@ -3025,12 +2996,12 @@ static void view3d_main_area_draw_engine_info(View3D *v3d, RegionView3D *rv3d, A /* draw darkened background color. no alpha because border render does * partial redraw and will not redraw the area behind this info bar */ float alpha = 1.0f - fill_color[3]; - - if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) { - Camera *ca = v3d->camera->data; + Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); - if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT)) - alpha *= (1.0f - ca->passepartalpha); + if (camera) { + if (camera->flag & CAM_SHOWPASSEPARTOUT) { + alpha *= (1.0f - camera->passepartalpha); + } } UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 80e5d194d45..36c6df75461 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -992,15 +992,14 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event) /* switch from camera view when: */ if (vod->rv3d->persp != RV3D_PERSP) { - - if (U.uiflag & USER_AUTOPERSP) { + if (vod->rv3d->persp == RV3D_CAMOB) { + view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, vod->rv3d->lpersp); + } + else if ((U.uiflag & USER_AUTOPERSP) && RV3D_VIEW_IS_AXIS(vod->rv3d->view)) { if (!ED_view3d_camera_lock_check(vod->v3d, vod->rv3d)) { vod->rv3d->persp = RV3D_PERSP; } } - else if (vod->rv3d->persp == RV3D_CAMOB) { - view3d_persp_switch_from_camera(vod->v3d, vod->rv3d, vod->rv3d->lpersp); - } ED_region_tag_redraw(vod->ar); } @@ -2464,7 +2463,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); float min[3], max[3]; - bool change = false; + bool changed = false; if (center) { /* in 2.4x this also move the cursor to (0, 0, 0) (with shift+c). */ @@ -2479,7 +2478,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in for (base = scene->base.first; base; base = base->next) { if (BASE_VISIBLE(v3d, base)) { - change = true; + changed = true; if (skip_camera && base->object == v3d->camera) { continue; @@ -2488,7 +2487,7 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in BKE_object_minmax(base->object, min, max, false); } } - if (!change) { + if (!changed) { ED_region_tag_redraw(ar); /* TODO - should this be cancel? * I think no, because we always move the cursor, with or without @@ -3344,20 +3343,19 @@ static void axis_set_view(bContext *C, View3D *v3d, ARegion *ar, return; } - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { - - if (U.uiflag & USER_AUTOPERSP) rv3d->persp = view ? RV3D_ORTHO : RV3D_PERSP; - else if (rv3d->persp == RV3D_CAMOB) rv3d->persp = perspo; + if (U.uiflag & USER_AUTOPERSP) { + rv3d->persp = RV3D_VIEW_IS_AXIS(view) ? RV3D_ORTHO : perspo; + } + else if (rv3d->persp == RV3D_CAMOB) { + rv3d->persp = perspo; + } + if (rv3d->persp == RV3D_CAMOB && v3d->camera) { ED_view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, rv3d->ofs, new_quat, NULL, NULL, smooth_viewtx); } else { - - if (U.uiflag & USER_AUTOPERSP) rv3d->persp = view ? RV3D_ORTHO : RV3D_PERSP; - else if (rv3d->persp == RV3D_CAMOB) rv3d->persp = perspo; - ED_view3d_smooth_view(C, v3d, ar, NULL, NULL, NULL, new_quat, NULL, NULL, smooth_viewtx); @@ -3891,6 +3889,35 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) ot->flag = 0; } +static int view3d_navigate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event)) +{ + eViewNavigation_Method mode = U.navigation_mode; + + switch (mode) { + case VIEW_NAVIGATION_FLY: + WM_operator_name_call(C, "VIEW3D_OT_fly", WM_OP_INVOKE_DEFAULT, NULL); + break; + case VIEW_NAVIGATION_WALK: + default: + WM_operator_name_call(C, "VIEW3D_OT_walk", WM_OP_INVOKE_DEFAULT, NULL); + break; + } + + return OPERATOR_FINISHED; +} + +void VIEW3D_OT_navigate(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View Navigation"; + ot->description = "Interactively navigate around the scene (uses the mode (walk/fly) preference)"; + ot->idname = "VIEW3D_OT_navigate"; + + /* api callbacks */ + ot->invoke = view3d_navigate_invoke; + ot->poll = ED_operator_view3d_active; +} + /* ******************** add background image operator **************** */ @@ -4144,16 +4171,17 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2]) } } else { - const float dx = ((float)(mval[0] - (ar->winx / 2))) * zfac / (ar->winx / 2); - const float dy = ((float)(mval[1] - (ar->winy / 2))) * zfac / (ar->winy / 2); - const float fz = (rv3d->persmat[0][3] * fp[0] + - rv3d->persmat[1][3] * fp[1] + - rv3d->persmat[2][3] * fp[2] + - rv3d->persmat[3][3]) / zfac; - - fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0]; - fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1]; - fp[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy + rv3d->persinv[2][2] * fz) - rv3d->ofs[2]; + float tvec[3]; + + tvec[0] = ((float)(mval[0] - (ar->winx / 2))) * zfac / (ar->winx / 2); + tvec[1] = ((float)(mval[1] - (ar->winy / 2))) * zfac / (ar->winy / 2); + tvec[2] = (rv3d->persmat[0][3] * fp[0] + + rv3d->persmat[1][3] * fp[1] + + rv3d->persmat[2][3] * fp[2] + + rv3d->persmat[3][3]) / zfac; + + mul_mat3_m4_v3(rv3d->persinv, tvec); + sub_v3_v3v3(fp, tvec, rv3d->ofs); } } diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 373e57d5708..5f8962a4e90 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -28,35 +28,29 @@ //#define NDOF_FLY_DEBUG //#define NDOF_FLY_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */ -#include "DNA_anim_types.h" -#include "DNA_scene_types.h" + #include "DNA_object_types.h" -#include "DNA_camera_types.h" #include "MEM_guardedalloc.h" #include "BLI_math.h" #include "BLI_blenlib.h" -#include "BLI_utildefines.h" #include "BKE_context.h" -#include "BKE_object.h" #include "BKE_report.h" -#include "BKE_depsgraph.h" /* for fly mode updating */ - #include "BIF_gl.h" #include "WM_api.h" #include "WM_types.h" -#include "ED_keyframing.h" #include "ED_screen.h" #include "ED_space_api.h" #include "PIL_time.h" /* smoothview */ #include "view3d_intern.h" /* own include */ + /* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ enum { FLY_MODAL_CANCEL = 1, @@ -194,6 +188,8 @@ typedef struct FlyInfo { bool use_freelook; int mval[2]; /* latest 2D mouse values */ + int center_mval[2]; /* center mouse values */ + float width, height; /* camera viewport dimensions */ wmNDOFMotionData *ndof; /* latest 3D mouse values */ /* fly state state */ @@ -205,24 +201,6 @@ typedef struct FlyInfo { float xlock_momentum, zlock_momentum; /* nicer dynamics */ float grid; /* world scale 1.0 default */ - /* root most parent */ - Object *root_parent; - - /* backup values */ - float dist_backup; /* backup the views distance since we use a zero dist for fly mode */ - float ofs_backup[3]; /* backup the views offset in case the user cancels flying in non camera mode */ - - /* backup the views quat in case the user cancels flying in non camera mode. - * (quat for view, eul for camera) */ - float rot_backup[4]; - short persp_backup; /* remember if were ortho or not, only used for restoring the view if it was a ortho view */ - - /* are we flying an ortho camera in perspective view, - * which was originally in ortho view? - * could probably figure it out but better be explicit */ - bool is_ortho_cam; - void *obtfm; /* backup the objects transform */ - /* compare between last state */ double time_lastwheel; /* used to accelerate when using the mousewheel a lot */ double time_lastdraw; /* time between draws */ @@ -232,23 +210,34 @@ typedef struct FlyInfo { /* use for some lag */ float dvec_prev[3]; /* old for some lag */ - /* for parenting calculation */ - float view_mat_prev[4][4]; + struct View3DCameraControl *v3d_camera_control; } FlyInfo; static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { FlyInfo *fly = arg; + rctf viewborder; + int xoff, yoff; + float x1, x2, y1, y2; + + if (fly->scene->camera) { + ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false); + xoff = viewborder.xmin; + yoff = viewborder.ymin; + } + else { + xoff = 0; + yoff = 0; + } /* draws 4 edge brackets that frame the safe area where the * mouse can move during fly mode without spinning the view */ - float x1, x2, y1, y2; - x1 = 0.45f * (float)fly->ar->winx; - y1 = 0.45f * (float)fly->ar->winy; - x2 = 0.55f * (float)fly->ar->winx; - y2 = 0.55f * (float)fly->ar->winy; + x1 = xoff + 0.45f * fly->width; + y1 = yoff + 0.45f * fly->height; + x2 = xoff + 0.55f * fly->width; + y2 = yoff + 0.55f * fly->height; cpack(0); glBegin(GL_LINES); @@ -283,13 +272,17 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar), } /* FlyInfo->state */ -#define FLY_RUNNING 0 -#define FLY_CANCEL 1 -#define FLY_CONFIRM 2 +enum { + FLY_RUNNING = 0, + FLY_CANCEL = 1, + FLY_CONFIRM = 2, +}; static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event) { wmWindow *win = CTX_wm_window(C); + rctf viewborder; + float upvec[3]; /* tmp */ float mat[3][3]; @@ -348,89 +341,48 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL); - fly->rv3d->rflag |= RV3D_NAVIGATING; /* so we draw the corner margins */ + fly->rv3d->rflag |= RV3D_NAVIGATING; /* detect whether to start with Z locking */ - upvec[0] = 1.0f; - upvec[1] = 0.0f; - upvec[2] = 0.0f; + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); copy_m3_m4(mat, fly->rv3d->viewinv); mul_m3_v3(mat, upvec); if (fabsf(upvec[2]) < 0.1f) { fly->zlock = FLY_AXISLOCK_STATE_IDLE; } - upvec[0] = 0; - upvec[1] = 0; - upvec[2] = 0; - fly->persp_backup = fly->rv3d->persp; - fly->dist_backup = fly->rv3d->dist; + fly->v3d_camera_control = ED_view3d_cameracontrol_aquire( + fly->scene, fly->v3d, fly->rv3d, + (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); - /* check for flying ortho camera - which we cant support well - * we _could_ also check for an ortho camera but this is easier */ - if ((fly->rv3d->persp == RV3D_CAMOB) && - (fly->rv3d->is_persp == false)) - { - ((Camera *)fly->v3d->camera->data)->type = CAM_PERSP; - fly->is_ortho_cam = true; - } - - if (fly->rv3d->persp == RV3D_CAMOB) { - Object *ob_back; - if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (fly->root_parent = fly->v3d->camera->parent)) { - while (fly->root_parent->parent) - fly->root_parent = fly->root_parent->parent; - ob_back = fly->root_parent; - } - else { - ob_back = fly->v3d->camera; - } - - /* store the original camera loc and rot */ - fly->obtfm = BKE_object_tfm_backup(ob_back); + /* calculate center */ + if (fly->scene->camera) { + ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false); - BKE_object_where_is_calc(fly->scene, fly->v3d->camera); - negate_v3_v3(fly->rv3d->ofs, fly->v3d->camera->obmat[3]); + fly->width = BLI_rctf_size_x(&viewborder); + fly->height = BLI_rctf_size_y(&viewborder); - fly->rv3d->dist = 0.0; + fly->center_mval[0] = viewborder.xmin + fly->width / 2; + fly->center_mval[1] = viewborder.ymin + fly->height / 2; } else { - /* perspective or ortho */ - if (fly->rv3d->persp == RV3D_ORTHO) - fly->rv3d->persp = RV3D_PERSP; /* if ortho projection, make perspective */ - - copy_qt_qt(fly->rot_backup, fly->rv3d->viewquat); - copy_v3_v3(fly->ofs_backup, fly->rv3d->ofs); - - /* the dist defines a vector that is infront of the offset - * to rotate the view about. - * this is no good for fly mode because we - * want to rotate about the viewers center. - * but to correct the dist removal we must - * alter offset so the view doesn't jump. */ - - fly->rv3d->dist = 0.0f; - - upvec[2] = fly->dist_backup; /* x and y are 0 */ - mul_m3_v3(mat, upvec); - sub_v3_v3(fly->rv3d->ofs, upvec); - /* Done with correcting for the dist */ - } + fly->width = fly->ar->winx; + fly->height = fly->ar->winy; - ED_view3d_to_m4(fly->view_mat_prev, fly->rv3d->ofs, fly->rv3d->viewquat, fly->rv3d->dist); + fly->center_mval[0] = fly->width / 2; + fly->center_mval[1] = fly->height / 2; + } /* center the mouse, probably the UI mafia are against this but without its quite annoying */ - WM_cursor_warp(win, fly->ar->winrct.xmin + fly->ar->winx / 2, fly->ar->winrct.ymin + fly->ar->winy / 2); + WM_cursor_warp(win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]); return 1; } static int flyEnd(bContext *C, FlyInfo *fly) { - RegionView3D *rv3d = fly->rv3d; - View3D *v3d = fly->v3d; - - float upvec[3]; + wmWindow *win; + RegionView3D *rv3d; if (fly->state == FLY_RUNNING) return OPERATOR_RUNNING_MODAL; @@ -439,58 +391,17 @@ static int flyEnd(bContext *C, FlyInfo *fly) puts("\n-- fly end --"); #endif - WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer); - - ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); - - rv3d->dist = fly->dist_backup; - if (fly->state == FLY_CANCEL) { - /* Revert to original view? */ - if (fly->persp_backup == RV3D_CAMOB) { /* a camera view */ - Object *ob_back; - ob_back = (fly->root_parent) ? fly->root_parent : fly->v3d->camera; + win = CTX_wm_window(C); + rv3d = fly->rv3d; - /* store the original camera loc and rot */ - BKE_object_tfm_restore(ob_back, fly->obtfm); + WM_event_remove_timer(CTX_wm_manager(C), win, fly->timer); - DAG_id_tag_update(&ob_back->id, OB_RECALC_OB); - } - else { - /* Non Camera we need to reset the view back to the original location bacause the user canceled*/ - copy_qt_qt(rv3d->viewquat, fly->rot_backup); - rv3d->persp = fly->persp_backup; - } - /* always, is set to zero otherwise */ - copy_v3_v3(rv3d->ofs, fly->ofs_backup); - } - else if (fly->persp_backup == RV3D_CAMOB) { /* camera */ - DAG_id_tag_update(fly->root_parent ? &fly->root_parent->id : &v3d->camera->id, OB_RECALC_OB); - - /* always, is set to zero otherwise */ - copy_v3_v3(rv3d->ofs, fly->ofs_backup); - } - else { /* not camera */ - - /* Apply the fly mode view */ - /* restore the dist */ - float mat[3][3]; - upvec[0] = upvec[1] = 0; - upvec[2] = fly->dist_backup; /* x and y are 0 */ - copy_m3_m4(mat, rv3d->viewinv); - mul_m3_v3(mat, upvec); - add_v3_v3(rv3d->ofs, upvec); - /* Done with correcting for the dist */ - } + ED_region_draw_cb_exit(fly->ar->type, fly->draw_handle_pixel); - if (fly->is_ortho_cam) { - ((Camera *)fly->v3d->camera->data)->type = CAM_ORTHO; - } + ED_view3d_cameracontrol_release(fly->v3d_camera_control, fly->state == FLY_CANCEL); rv3d->rflag &= ~RV3D_NAVIGATING; -//XXX2.5 BIF_view3d_previewrender_signal(fly->sa, PR_DBASE|PR_DISPRECT); /* not working at the moment not sure why */ - if (fly->obtfm) - MEM_freeN(fly->obtfm); if (fly->ndof) MEM_freeN(fly->ndof); @@ -633,7 +544,6 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event) fly->pan_view = true; break; case FLY_MODAL_PAN_DISABLE: -//XXX2.5 WM_cursor_warp(CTX_wm_window(C), cent_orig[0], cent_orig[1]); fly->pan_view = false; break; @@ -739,86 +649,10 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event) } } -static void flyMoveCamera(bContext *C, RegionView3D *rv3d, FlyInfo *fly, - const bool do_rotate, const bool do_translate) +static void flyMoveCamera(bContext *C, FlyInfo *fly, + const bool do_rotate, const bool do_translate) { - /* we are in camera view so apply the view ofs and quat to the view matrix and set the camera to the view */ - - View3D *v3d = fly->v3d; - Scene *scene = fly->scene; - ID *id_key; - - /* transform the parent or the camera? */ - if (fly->root_parent) { - Object *ob_update; - - float view_mat[4][4]; - float prev_view_imat[4][4]; - float diff_mat[4][4]; - float parent_mat[4][4]; - - invert_m4_m4(prev_view_imat, fly->view_mat_prev); - ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); - mul_m4_m4m4(diff_mat, view_mat, prev_view_imat); - mul_m4_m4m4(parent_mat, diff_mat, fly->root_parent->obmat); - - BKE_object_apply_mat4(fly->root_parent, parent_mat, true, false); - - // BKE_object_where_is_calc(scene, fly->root_parent); - - ob_update = v3d->camera->parent; - while (ob_update) { - DAG_id_tag_update(&ob_update->id, OB_RECALC_OB); - ob_update = ob_update->parent; - } - - copy_m4_m4(fly->view_mat_prev, view_mat); - - id_key = &fly->root_parent->id; - } - else { - float view_mat[4][4]; - float size_mat[4][4]; - float size_back[3]; - - /* even though we handle the size matrix, this still changes over time */ - copy_v3_v3(size_back, v3d->camera->size); - - ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist); - size_to_mat4(size_mat, v3d->camera->size); - mul_m4_m4m4(view_mat, view_mat, size_mat); - - BKE_object_apply_mat4(v3d->camera, view_mat, true, true); - - copy_v3_v3(v3d->camera->size, size_back); - - id_key = &v3d->camera->id; - } - - /* record the motion */ - if (autokeyframe_cfra_can_key(scene, id_key)) { - ListBase dsources = {NULL, NULL}; - - /* add datasource override for the camera object */ - ANIM_relative_keyingset_add_source(&dsources, id_key, NULL, NULL); - - /* insert keyframes - * 1) on the first frame - * 2) on each subsequent frame - * TODO: need to check in future that frame changed before doing this - */ - if (do_rotate) { - KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_ROTATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - if (do_translate) { - KeyingSet *ks = ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_LOCATION_ID); - ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA); - } - - /* free temp data */ - BLI_freelistN(&dsources); - } + ED_view3d_cameracontrol_update(fly->v3d_camera_control, true, C, do_rotate, do_translate); } static int flyApply(bContext *C, FlyInfo *fly) @@ -832,7 +666,6 @@ static int flyApply(bContext *C, FlyInfo *fly) * a fly loop where the user can move move the view as if they are flying */ RegionView3D *rv3d = fly->rv3d; - ARegion *ar = fly->ar; float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ float dvec[3] = {0, 0, 0}; /* this is the direction thast added to the view offset per redraw */ @@ -843,8 +676,6 @@ static int flyApply(bContext *C, FlyInfo *fly) float moffset[2]; /* mouse offset from the views center */ float tmp_quat[4]; /* used for rotating the view */ -// int cent_orig[2], /* view center */ -//XXX- can avoid using // cent[2], /* view center modified */ int xmargin, ymargin; /* x and y margin are define the safe area where the mouses movement wont rotate the view */ #ifdef NDOF_FLY_DEBUG @@ -854,18 +685,14 @@ static int flyApply(bContext *C, FlyInfo *fly) } #endif - xmargin = ar->winx / 20.0f; - ymargin = ar->winy / 20.0f; - - // UNUSED - // cent_orig[0] = ar->winrct.xmin + ar->winx / 2; - // cent_orig[1] = ar->winrct.ymin + ar->winy / 2; + xmargin = fly->width / 20.0f; + ymargin = fly->height / 20.0f; { /* mouse offset from the center */ - moffset[0] = fly->mval[0] - ar->winx / 2; - moffset[1] = fly->mval[1] - ar->winy / 2; + moffset[0] = fly->mval[0] - fly->center_mval[0]; + moffset[1] = fly->mval[1] - fly->center_mval[1]; /* enforce a view margin */ if (moffset[0] > xmargin) moffset[0] -= xmargin; @@ -883,12 +710,12 @@ static int flyApply(bContext *C, FlyInfo *fly) * the mouse moves isn't linear */ if (moffset[0]) { - moffset[0] /= ar->winx - (xmargin * 2); + moffset[0] /= fly->width - (xmargin * 2); moffset[0] *= fabsf(moffset[0]); } if (moffset[1]) { - moffset[1] /= ar->winy - (ymargin * 2); + moffset[1] /= fly->height - (ymargin * 2); moffset[1] *= fabsf(moffset[1]); } @@ -923,9 +750,7 @@ static int flyApply(bContext *C, FlyInfo *fly) if (fly->pan_view == true) { /* pan only */ - dvec_tmp[0] = -moffset[0]; - dvec_tmp[1] = -moffset[1]; - dvec_tmp[2] = 0; + copy_v3_fl3(dvec_tmp, -moffset[0], -moffset[1], 0.0f); if (fly->use_precision) { dvec_tmp[0] *= 0.1f; @@ -941,9 +766,7 @@ static int flyApply(bContext *C, FlyInfo *fly) /* rotate about the X axis- look up/down */ if (moffset[1]) { - upvec[0] = 1; - upvec[1] = 0; - upvec[2] = 0; + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); mul_m3_v3(mat, upvec); /* Rotate about the relative up vec */ axis_angle_to_quat(tmp_quat, upvec, (float)moffset[1] * time_redraw * -FLY_ROTATE_FAC); @@ -960,9 +783,7 @@ static int flyApply(bContext *C, FlyInfo *fly) if (moffset[0]) { /* if we're upside down invert the moffset */ - upvec[0] = 0.0f; - upvec[1] = 1.0f; - upvec[2] = 0.0f; + copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f); mul_m3_v3(mat, upvec); if (upvec[2] < 0.0f) @@ -970,14 +791,10 @@ static int flyApply(bContext *C, FlyInfo *fly) /* make the lock vectors */ if (fly->zlock) { - upvec[0] = 0.0f; - upvec[1] = 0.0f; - upvec[2] = 1.0f; + copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); } else { - upvec[0] = 0.0f; - upvec[1] = 1.0f; - upvec[2] = 0.0f; + copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f); mul_m3_v3(mat, upvec); } @@ -992,18 +809,14 @@ static int flyApply(bContext *C, FlyInfo *fly) } if (fly->zlock == FLY_AXISLOCK_STATE_ACTIVE) { - upvec[0] = 1.0f; - upvec[1] = 0.0f; - upvec[2] = 0.0f; + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); mul_m3_v3(mat, upvec); /* make sure we have some z rolling */ if (fabsf(upvec[2]) > 0.00001f) { roll = upvec[2] * 5.0f; - upvec[0] = 0.0f; /* rotate the view about this axis */ - upvec[1] = 0.0f; - upvec[2] = 1.0f; - + /* rotate the view about this axis */ + copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); mul_m3_v3(mat, upvec); /* Rotate about the relative up vec */ axis_angle_to_quat(tmp_quat, upvec, @@ -1020,18 +833,13 @@ static int flyApply(bContext *C, FlyInfo *fly) /* only apply xcorrect when mouse isn't applying x rot */ if (fly->xlock == FLY_AXISLOCK_STATE_ACTIVE && moffset[1] == 0) { - upvec[0] = 0; - upvec[1] = 0; - upvec[2] = 1; + copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); mul_m3_v3(mat, upvec); /* make sure we have some z rolling */ if (fabsf(upvec[2]) > 0.00001f) { roll = upvec[2] * -5.0f; - - upvec[0] = 1.0f; /* rotate the view about this axis */ - upvec[1] = 0.0f; - upvec[2] = 0.0f; - + /* rotate the view about this axis */ + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); mul_m3_v3(mat, upvec); /* Rotate about the relative up vec */ @@ -1073,7 +881,7 @@ static int flyApply(bContext *C, FlyInfo *fly) interp_v3_v3v3(dvec, dvec_tmp, fly->dvec_prev, (1.0f / (1.0f + (time_redraw * FLY_SMOOTH_FAC)))); if (rv3d->persp == RV3D_CAMOB) { - Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0; if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0; if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0; @@ -1086,7 +894,7 @@ static int flyApply(bContext *C, FlyInfo *fly) (fly->zlock != FLY_AXISLOCK_STATE_OFF) || ((moffset[0] || moffset[1]) && !fly->pan_view)); const bool do_translate = (fly->speed != 0.0f || fly->pan_view); - flyMoveCamera(C, rv3d, fly, do_rotate, do_translate); + flyMoveCamera(C, fly, do_rotate, do_translate); } } @@ -1149,7 +957,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) if (rv3d->persp == RV3D_CAMOB) { /* respect camera position locks */ - Object *lock_ob = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *lock_ob = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f; if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f; if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f; @@ -1223,7 +1031,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly) fly->redraw = true; if (rv3d->persp == RV3D_CAMOB) { - flyMoveCamera(C, rv3d, fly, do_rotate, do_translate); + flyMoveCamera(C, fly, do_rotate, do_translate); } } @@ -1269,7 +1077,7 @@ static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event) bool do_draw = false; FlyInfo *fly = op->customdata; RegionView3D *rv3d = fly->rv3d; - Object *fly_object = fly->root_parent ? fly->root_parent : fly->v3d->camera; + Object *fly_object = ED_view3d_cameracontrol_object_get(fly->v3d_camera_control); fly->redraw = 0; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index a496bbba72f..fae7804f31b 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -92,6 +92,7 @@ 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_navigate(struct wmOperatorType *ot); void VIEW3D_OT_background_image_add(struct wmOperatorType *ot); void VIEW3D_OT_background_image_remove(struct wmOperatorType *ot); void VIEW3D_OT_view_orbit(struct wmOperatorType *ot); @@ -112,6 +113,9 @@ float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]); void view3d_keymap(struct wmKeyConfig *keyconf); void VIEW3D_OT_fly(struct wmOperatorType *ot); +/* view3d_walk.c */ +void VIEW3D_OT_walk(struct wmOperatorType *ot); + /* view3d_ruler.c */ void VIEW3D_OT_ruler(struct wmOperatorType *ot); @@ -195,6 +199,7 @@ void setwinmatrixview3d(ARegion *ar, View3D *v3d, rctf *rect); void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d); void fly_modal_keymap(struct wmKeyConfig *keyconf); +void walk_modal_keymap(struct wmKeyConfig *keyconf); void viewrotate_modal_keymap(struct wmKeyConfig *keyconf); void viewmove_modal_keymap(struct wmKeyConfig *keyconf); void viewzoom_modal_keymap(struct wmKeyConfig *keyconf); @@ -204,6 +209,20 @@ void viewdolly_modal_keymap(struct wmKeyConfig *keyconf); void VIEW3D_OT_properties(struct wmOperatorType *ot); void view3d_buttons_register(struct ARegionType *art); +/* view3d_camera_control.c */ +struct View3DCameraControl *ED_view3d_cameracontrol_aquire( + Scene *scene, View3D *v3d, RegionView3D *rv3d, + const bool use_parent_root); +void ED_view3d_cameracontrol_update( + struct View3DCameraControl *vctrl, + const bool use_autokey, + struct bContext *C, const bool do_rotate, const bool do_translate); +void ED_view3d_cameracontrol_release( + struct View3DCameraControl *vctrl, + const bool restore); +Object *ED_view3d_cameracontrol_object_get( + struct View3DCameraControl *vctrl); + /* view3d_toolbar.c */ void VIEW3D_OT_toolshelf(struct wmOperatorType *ot); void view3d_toolshelf_register(struct ARegionType *art); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index dec9085baeb..12405150267 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -46,6 +46,7 @@ #include "BKE_blender.h" #include "BKE_context.h" #include "BKE_main.h" +#include "BKE_report.h" #include "RNA_access.h" @@ -76,6 +77,8 @@ static int view3d_copybuffer_exec(bContext *C, wmOperator *op) BLI_make_file_string("/", str, BLI_temporary_dir(), "copybuffer.blend"); BKE_copybuffer_save(str, op->reports); + BKE_report(op->reports, RPT_INFO, "Copied selected objects to buffer"); + return OPERATOR_FINISHED; } @@ -88,7 +91,6 @@ static void VIEW3D_OT_copybuffer(wmOperatorType *ot) ot->description = "Selected objects are saved in a temp file"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = view3d_copybuffer_exec; ot->poll = ED_operator_view3d_active; } @@ -102,6 +104,8 @@ static int view3d_pastebuffer_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_WINDOW, NULL); + BKE_report(op->reports, RPT_INFO, "Objects pasted from buffer"); + return OPERATOR_FINISHED; } @@ -114,7 +118,6 @@ static void VIEW3D_OT_pastebuffer(wmOperatorType *ot) ot->description = "Contents of copy buffer gets pasted"; /* api callbacks */ - ot->invoke = WM_operator_confirm; ot->exec = view3d_pastebuffer_exec; ot->poll = ED_operator_view3d_active; @@ -169,6 +172,8 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_localview); WM_operatortype_append(VIEW3D_OT_game_start); WM_operatortype_append(VIEW3D_OT_fly); + WM_operatortype_append(VIEW3D_OT_walk); + WM_operatortype_append(VIEW3D_OT_navigate); WM_operatortype_append(VIEW3D_OT_ruler); WM_operatortype_append(VIEW3D_OT_layers); WM_operatortype_append(VIEW3D_OT_copybuffer); @@ -221,7 +226,7 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_fly", FKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_verify_item(keymap, "VIEW3D_OT_navigate", FKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_smoothview", TIMER1, KM_ANY, KM_ANY, 0); @@ -501,6 +506,7 @@ void view3d_keymap(wmKeyConfig *keyconf) transform_keymap_for_space(keyconf, keymap, SPACE_VIEW3D); fly_modal_keymap(keyconf); + walk_modal_keymap(keyconf); viewrotate_modal_keymap(keyconf); viewmove_modal_keymap(keyconf); viewzoom_modal_keymap(keyconf); diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c index 288ada3f852..6aa34baeac6 100644 --- a/source/blender/editors/space_view3d/view3d_ruler.c +++ b/source/blender/editors/space_view3d/view3d_ruler.c @@ -335,7 +335,7 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) bGPDstroke *gps; RulerItem *ruler_item; const char *ruler_name = RULER_ID; - bool change = false; + bool changed = false; if (scene->gpd == NULL) { scene->gpd = gpencil_data_addnew("GPencil"); @@ -377,16 +377,16 @@ static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info) } gps->flag = GP_STROKE_3DSPACE; BLI_addtail(&gpf->strokes, gps); - change = true; + changed = true; } - return change; + return changed; } static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info) { Scene *scene = CTX_data_scene(C); - bool change = false; + bool changed = false; if (scene->gpd) { bGPDlayer *gpl; @@ -407,7 +407,7 @@ static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info) pt++; } ruler_item->flag |= RULERITEM_USE_ANGLE; - change = true; + changed = true; } else if (gps->totpoints == 2) { RulerItem *ruler_item = ruler_item_add(ruler_info); @@ -415,14 +415,14 @@ static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info) copy_v3_v3(ruler_item->co[j], &pt->x); pt++; } - change = true; + changed = true; } } } } } - return change; + return changed; } /* -------------------------------------------------------------------- */ @@ -541,7 +541,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); - BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]); + BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]); pos[0] = co_ss[1][0] + (cap_size * 2.0f); pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f); @@ -627,7 +627,7 @@ static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *a ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec); - BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]); + BLF_width_and_height(blf_mono_font, numstr, sizeof(numstr), &numstr_size[0], &numstr_size[1]); mid_v2_v2v2(pos, co_ss[0], co_ss[2]); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index a6ef70a5e33..a15ecb1dc1c 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -236,7 +236,7 @@ typedef struct LassoSelectUserData { /* runtime */ int pass; bool is_done; - bool is_change; + bool is_changed; } LassoSelectUserData; static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, @@ -256,7 +256,7 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, /* runtime */ r_data->pass = 0; r_data->is_done = false; - r_data->is_change = false; + r_data->is_changed = false; } static int view3d_selectable_data(bContext *C) @@ -357,9 +357,9 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann { if (data->select) pchan->bone->flag |= BONE_SELECTED; else pchan->bone->flag &= ~BONE_SELECTED; - data->is_change = true; + data->is_changed = true; } - data->is_change |= is_point_done; + data->is_changed |= is_point_done; } } static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, const bool select) @@ -383,7 +383,7 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.is_change) { + if (data.is_changed) { bArmature *arm = ob->data; if (arm->flag & ARM_HAS_VIZ_DEPS) { /* mask modifier ('armature' mode), etc. */ @@ -647,10 +647,10 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo { if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - data->is_change = true; + data->is_changed = true; } - data->is_change |= is_point_done; + data->is_changed |= is_point_done; } } @@ -670,7 +670,7 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.is_change) { + if (data.is_changed) { bArmature *arm = vc->obedit->data; ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); @@ -687,7 +687,7 @@ static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; - data->is_change = true; + data->is_changed = true; } } static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select) @@ -1003,7 +1003,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) { const int name_index = RNA_enum_get(op->ptr, "name"); const bool toggle = RNA_boolean_get(op->ptr, "toggle"); - bool change = false; + bool changed = false; const char *name = object_mouse_select_menu_data[name_index].idname; if (!toggle) { @@ -1011,7 +1011,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) { if (base->flag & SELECT) { ED_base_object_select(base, BA_DESELECT); - change = true; + changed = true; } } CTX_DATA_END; @@ -1023,7 +1023,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) if (STREQ(name, base->object->id.name + 2)) { ED_base_object_activate(C, base); ED_base_object_select(base, BA_SELECT); - change = true; + changed = true; } } CTX_DATA_END; @@ -1032,7 +1032,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op) memset(object_mouse_select_menu_data, 0, sizeof(object_mouse_select_menu_data)); /* undo? */ - if (change) { + if (changed) { WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, CTX_data_scene(C)); return OPERATOR_FINISHED; } @@ -1454,7 +1454,7 @@ static bool mouse_select(bContext *C, const int mval[2], if (basact->object->type == OB_CAMERA) { if (BASACT == basact) { int i, hitresult; - int changed = 0; + bool changed = false; for (i = 0; i < hits; i++) { hitresult = buffer[3 + (i * 4)]; @@ -1476,7 +1476,7 @@ static bool mouse_select(bContext *C, const int mval[2], track = BKE_tracking_track_get_indexed(&clip->tracking, hitresult >> 16, &tracksbase); if (TRACK_SELECTED(track) && extend) { - changed = 0; + changed = false; BKE_tracking_track_deselect(track, TRACK_AREA_ALL); } else { @@ -1487,7 +1487,7 @@ static bool mouse_select(bContext *C, const int mval[2], BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, extend); if (oldsel != (TRACK_SELECTED(track) ? 1 : 0)) - changed = 1; + changed = true; } basact->flag |= SELECT; @@ -1593,7 +1593,7 @@ typedef struct BoxSelectUserData { /* runtime */ int pass; bool is_done; - bool is_change; + bool is_changed; } BoxSelectUserData; static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, @@ -1610,7 +1610,7 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, /* runtime */ r_data->pass = 0; r_data->is_done = false; - r_data->is_change = false; + r_data->is_changed = false; } bool edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]) @@ -2320,7 +2320,7 @@ typedef struct CircleSelectUserData { float radius_squared; /* runtime */ - bool is_change; + bool is_changed; } CircleSelectUserData; static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, @@ -2336,7 +2336,7 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->radius_squared = rad * rad; /* runtime */ - r_data->is_change = false; + r_data->is_changed = false; } static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) @@ -2579,10 +2579,10 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan { if (data->select) pchan->bone->flag |= BONE_SELECTED; else pchan->bone->flag &= ~BONE_SELECTED; - data->is_change = true; + data->is_changed = true; } - data->is_change |= is_point_done; + data->is_changed |= is_point_done; } } static void pose_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) @@ -2595,7 +2595,7 @@ static void pose_circle_select(ViewContext *vc, const bool select, const int mva pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.is_change) { + if (data.is_changed) { bArmature *arm = vc->obact->data; WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obact); @@ -2665,10 +2665,10 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB { if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - data->is_change = true; + data->is_changed = true; } - data->is_change |= is_point_done; + data->is_changed |= is_point_done; } } static void armature_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) @@ -2682,7 +2682,7 @@ static void armature_circle_select(ViewContext *vc, const bool select, const int armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.is_change) { + if (data.is_changed) { ED_armature_sync_selection(arm->edbo); ED_armature_validate_active(arm); WM_main_add_notifier(NC_OBJECT | ND_BONE_SELECT, vc->obedit); @@ -2696,7 +2696,7 @@ static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; - data->is_change = true; + data->is_changed = true; } } static void mball_circle_select(ViewContext *vc, const bool select, const int mval[2], float rad) @@ -2741,7 +2741,7 @@ static bool object_circle_select(ViewContext *vc, const bool select, const int m Scene *scene = vc->scene; const float radius_squared = rad * rad; const float mval_fl[2] = {mval[0], mval[1]}; - bool is_change = false; + bool changed = false; const int select_flag = select ? SELECT : 0; @@ -2754,13 +2754,13 @@ static bool object_circle_select(ViewContext *vc, const bool select, const int m { if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT); - is_change = true; + changed = true; } } } } - return is_change; + return changed; } /* not a real operator, only for circle test */ diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 25458613842..3486e930466 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -692,14 +692,14 @@ bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3]) /* metaballs are an exception */ if (obedit->type == OB_MBALL) { float ob_min[3], ob_max[3]; - bool change; + bool changed; - change = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT); - if (change) { + changed = BKE_mball_minmax_ex(obedit->data, ob_min, ob_max, obedit->obmat, SELECT); + if (changed) { minmax_v3v3_v3(min, max, ob_min); minmax_v3v3_v3(min, max, ob_max); } - return change; + return changed; } if (ED_transverts_check_obedit(obedit)) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index e321e7c9c4b..d81ab0319e6 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -110,6 +110,16 @@ float *ED_view3d_cursor3d_get(Scene *scene, View3D *v3d) else return scene->cursor; } +Camera *ED_view3d_camera_data_get(View3D *v3d, RegionView3D *rv3d) +{ + /* establish the camera object, so we can default to view mapping if anything is wrong with it */ + if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) { + return v3d->camera->data; + } + else { + return NULL; + } +} /* ****************** smooth view operator ****************** */ /* This operator is one of the 'timer refresh' ones like animation playback */ @@ -711,6 +721,25 @@ bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy return params.is_ortho; } +/** + * Use instead of: ``bglPolygonOffset(rv3d->dist, ...)`` see bug [#37727] + */ +void ED_view3d_polygon_offset(const RegionView3D *rv3d, float dist) +{ + float viewdist = rv3d->dist; + + /* special exception for ortho camera (viewdist isnt used for perspective cameras) */ + if (dist != 0.0f) { + if (rv3d->persp == RV3D_CAMOB) { + if (rv3d->is_persp == false) { + viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1])); + } + } + } + + bglPolygonOffset(viewdist, dist); +} + /*! * \param rect for picking, NULL not to use. */ @@ -1268,16 +1297,16 @@ static int localview_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = CTX_wm_view3d(C); - bool change; + bool changed; if (v3d->localvd) { - change = view3d_localview_exit(bmain, scene, sa); + changed = view3d_localview_exit(bmain, scene, sa); } else { - change = view3d_localview_init(bmain, scene, sa, op->reports); + changed = view3d_localview_init(bmain, scene, sa, op->reports); } - if (change) { + if (changed) { DAG_id_type_tag(bmain, ID_OB); ED_area_tag_redraw(CTX_wm_area(C)); diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c new file mode 100644 index 00000000000..26f942b3ecd --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -0,0 +1,1419 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Dalai Felinto, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_walk.c + * \ingroup spview3d + */ + +/* defines VIEW3D_OT_navigate - walk modal operator */ + +//#define NDOF_WALK_DEBUG +//#define NDOF_WALK_DRAW_TOOMUCH /* is this needed for ndof? - commented so redraw doesnt thrash - campbell */ +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_camera_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_report.h" + +#include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_space_api.h" +#include "ED_transform.h" + +#include "PIL_time.h" /* smoothview */ + +#include "view3d_intern.h" /* own include */ + +#define EARTH_GRAVITY 9.80668f /* m/s2 */ + +/* prototypes */ +static float getVelocityZeroTime(float velocity); + +/* NOTE: these defines are saved in keymap files, do not change values but just add new ones */ +enum { + WALK_MODAL_CANCEL = 1, + WALK_MODAL_CONFIRM, + WALK_MODAL_DIR_FORWARD, + WALK_MODAL_DIR_FORWARD_STOP, + WALK_MODAL_DIR_BACKWARD, + WALK_MODAL_DIR_BACKWARD_STOP, + WALK_MODAL_DIR_LEFT, + WALK_MODAL_DIR_LEFT_STOP, + WALK_MODAL_DIR_RIGHT, + WALK_MODAL_DIR_RIGHT_STOP, + WALK_MODAL_DIR_UP, + WALK_MODAL_DIR_UP_STOP, + WALK_MODAL_DIR_DOWN, + WALK_MODAL_DIR_DOWN_STOP, + WALK_MODAL_FAST_ENABLE, + WALK_MODAL_FAST_DISABLE, + WALK_MODAL_SLOW_ENABLE, + WALK_MODAL_SLOW_DISABLE, + WALK_MODAL_JUMP, + WALK_MODAL_JUMP_STOP, + WALK_MODAL_TELEPORT, + WALK_MODAL_TOGGLE, + WALK_MODAL_ACCELERATE, + WALK_MODAL_DECELERATE, +}; + +enum { + WALK_BIT_FORWARD = 1 << 0, + WALK_BIT_BACKWARD = 1 << 1, + WALK_BIT_LEFT = 1 << 2, + WALK_BIT_RIGHT = 1 << 3, + WALK_BIT_UP = 1 << 4, + WALK_BIT_DOWN = 1 << 5, +}; + +typedef enum eWalkTeleportState { + WALK_TELEPORT_STATE_OFF = 0, + WALK_TELEPORT_STATE_ON, +} eWalkTeleportState; + +typedef enum eWalkMethod { + WALK_MODE_FREE = 0, + WALK_MODE_GRAVITY, +} eWalkMethod; + +typedef enum eWalkGravityState { + WALK_GRAVITY_STATE_OFF = 0, + WALK_GRAVITY_STATE_JUMP, + WALK_GRAVITY_STATE_START, + WALK_GRAVITY_STATE_ON, +} eWalkGravityState; + +/* called in transform_ops.c, on each regeneration of keymaps */ +void walk_modal_keymap(wmKeyConfig *keyconf) +{ + static EnumPropertyItem modal_items[] = { + {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, + {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, + + {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, + {WALK_MODAL_DECELERATE, "DECELERATE", 0, "Decelerate", ""}, + + {WALK_MODAL_DIR_FORWARD, "FORWARD", 0, "Move Forward", ""}, + {WALK_MODAL_DIR_BACKWARD, "BACKWARD", 0, "Move Backward", ""}, + {WALK_MODAL_DIR_LEFT, "LEFT", 0, "Move Left (Strafe)", ""}, + {WALK_MODAL_DIR_RIGHT, "RIGHT", 0, "Move Right (Strafe)", ""}, + {WALK_MODAL_DIR_UP, "UP", 0, "Move Up", ""}, + {WALK_MODAL_DIR_DOWN, "DOWN", 0, "Move Down", ""}, + + {WALK_MODAL_DIR_FORWARD_STOP, "FORWARD_STOP", 0, "Stop Move Forward", ""}, + {WALK_MODAL_DIR_BACKWARD_STOP, "BACKWARD_STOP", 0, "Stop Mode Backward", ""}, + {WALK_MODAL_DIR_LEFT_STOP, "LEFT_STOP", 0, "Stop Move Left", ""}, + {WALK_MODAL_DIR_RIGHT_STOP, "RIGHT_STOP", 0, "Stop Mode Right", ""}, + {WALK_MODAL_DIR_UP_STOP, "UP_STOP", 0, "Stop Move Up", ""}, + {WALK_MODAL_DIR_DOWN_STOP, "DOWN_STOP", 0, "Stop Mode Down", ""}, + + {WALK_MODAL_TELEPORT, "TELEPORT", 0, "Teleport", "Move forward a few units at once"}, + + {WALK_MODAL_FAST_ENABLE, "FAST_ENABLE", 0, "Fast Enable", "Move faster (walk or fly)"}, + {WALK_MODAL_FAST_DISABLE, "FAST_DISABLE", 0, "Fast Disable", "Resume regular speed"}, + + {WALK_MODAL_SLOW_ENABLE, "SLOW_ENABLE", 0, "Slow Enable", "Move slower (walk or fly)"}, + {WALK_MODAL_SLOW_DISABLE, "SLOW_DISABLE", 0, "Slow Disable", "Resume regular speed"}, + + {WALK_MODAL_JUMP, "JUMP", 0, "Jump", "Jump when in walk mode"}, + {WALK_MODAL_JUMP_STOP, "JUMP_STOP", 0, "Jump Stop", "Stop pushing jump"}, + + {0, NULL, 0, NULL, NULL}}; + + wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Walk Modal"); + + /* this function is called for each spacetype, only needs to add map once */ + if (keymap && keymap->modal_items) + return; + + keymap = WM_modalkeymap_add(keyconf, "View3D Walk Modal", modal_items); + + /* items for modal map */ + WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_CANCEL); + WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_ANY, KM_ANY, 0, WALK_MODAL_CANCEL); + + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_ANY, KM_ANY, 0, WALK_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, RETKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_CONFIRM); + WM_modalkeymap_add_item(keymap, PADENTER, KM_PRESS, KM_ANY, 0, WALK_MODAL_CONFIRM); + + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_FAST_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTSHIFTKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_FAST_DISABLE); + + WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_SLOW_ENABLE); + WM_modalkeymap_add_item(keymap, LEFTALTKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_SLOW_DISABLE); + + /* WASD */ + WM_modalkeymap_add_item(keymap, WKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_FORWARD); + WM_modalkeymap_add_item(keymap, SKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_BACKWARD); + WM_modalkeymap_add_item(keymap, AKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_LEFT); + WM_modalkeymap_add_item(keymap, DKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_RIGHT); + WM_modalkeymap_add_item(keymap, EKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_UP); + WM_modalkeymap_add_item(keymap, QKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_DIR_DOWN); + + WM_modalkeymap_add_item(keymap, WKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_FORWARD_STOP); + WM_modalkeymap_add_item(keymap, SKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_BACKWARD_STOP); + WM_modalkeymap_add_item(keymap, AKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_LEFT_STOP); + WM_modalkeymap_add_item(keymap, DKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_RIGHT_STOP); + WM_modalkeymap_add_item(keymap, EKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_UP_STOP); + WM_modalkeymap_add_item(keymap, QKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_DOWN_STOP); + + WM_modalkeymap_add_item(keymap, UPARROWKEY, KM_PRESS, 0, 0, WALK_MODAL_DIR_FORWARD); + WM_modalkeymap_add_item(keymap, DOWNARROWKEY, KM_PRESS, 0, 0, WALK_MODAL_DIR_BACKWARD); + WM_modalkeymap_add_item(keymap, LEFTARROWKEY, KM_PRESS, 0, 0, WALK_MODAL_DIR_LEFT); + WM_modalkeymap_add_item(keymap, RIGHTARROWKEY, KM_PRESS, 0, 0, WALK_MODAL_DIR_RIGHT); + + WM_modalkeymap_add_item(keymap, UPARROWKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_FORWARD_STOP); + WM_modalkeymap_add_item(keymap, DOWNARROWKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_BACKWARD_STOP); + WM_modalkeymap_add_item(keymap, LEFTARROWKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_LEFT_STOP); + WM_modalkeymap_add_item(keymap, RIGHTARROWKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_DIR_RIGHT_STOP); + + WM_modalkeymap_add_item(keymap, TABKEY, KM_PRESS, 0, 0, WALK_MODAL_TOGGLE); + WM_modalkeymap_add_item(keymap, GKEY, KM_PRESS, 0, 0, WALK_MODAL_TOGGLE); + + WM_modalkeymap_add_item(keymap, VKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_JUMP); + WM_modalkeymap_add_item(keymap, VKEY, KM_RELEASE, KM_ANY, 0, WALK_MODAL_JUMP_STOP); + + WM_modalkeymap_add_item(keymap, SPACEKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_TELEPORT); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_ANY, KM_ANY, 0, WALK_MODAL_TELEPORT); + + WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, KM_ANY, 0, WALK_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, KM_ANY, 0, WALK_MODAL_DECELERATE); + WM_modalkeymap_add_item(keymap, WHEELUPMOUSE, KM_PRESS, KM_ANY, 0, WALK_MODAL_ACCELERATE); + WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, KM_ANY, 0, WALK_MODAL_DECELERATE); + + /* assign map to operators */ + WM_modalkeymap_assign(keymap, "VIEW3D_OT_walk"); +} + + +typedef struct WalkTeleport +{ + eWalkTeleportState state; + float duration; /* from user preferences */ + float origin[3]; + float direction[3]; + double initial_time; + eWalkMethod navigation_mode; /* teleport always set FREE mode on */ + +} WalkTeleport; + +typedef struct WalkInfo { + /* context stuff */ + RegionView3D *rv3d; + View3D *v3d; + ARegion *ar; + Scene *scene; + + wmTimer *timer; /* needed for redraws */ + + short state; + bool redraw; + + int prev_mval[2]; /* previous 2D mouse values */ + int center_mval[2]; /* center mouse values */ + int moffset[2]; + wmNDOFMotionData *ndof; /* latest 3D mouse values */ + + /* walk state state */ + float base_speed; /* the base speed without run/slow down modifications */ + float speed; /* the speed the view is moving per redraw */ + float grid; /* world scale 1.0 default */ + + /* compare between last state */ + double time_lastdraw; /* time between draws */ + + void *draw_handle_pixel; + + /* use for some lag */ + float dvec_prev[3]; /* old for some lag */ + + /* walk/fly */ + eWalkMethod navigation_mode; + + /* teleport */ + WalkTeleport teleport; + + /* look speed factor - user preferences */ + float mouse_speed; + + /* speed adjustments */ + bool is_fast; + bool is_slow; + + /* mouse reverse */ + bool is_reversed; + + /* gravity system */ + eWalkGravityState gravity; + + /* height to use in walk mode */ + float view_height; + + /* counting system to allow movement to continue if a direction (WASD) key is still pressed */ + int active_directions; + + float speed_jump; + float jump_height; /* maximum jump height */ + float speed_factor; /* to use for fast/slow speeds */ + + struct View3DCameraControl *v3d_camera_control; + +} WalkInfo; + +static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) +{ + /* draws an aim/cross in the center */ + WalkInfo *walk = arg; + + const int outter_length = 24; + const int inner_length = 14; + int xoff, yoff; + rctf viewborder; + + if (walk->scene->camera) { + ED_view3d_calc_camera_border(walk->scene, ar, walk->v3d, walk->rv3d, &viewborder, false); + xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f; + yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f; + } + else { + xoff = walk->ar->winx / 2; + yoff = walk->ar->winy / 2; + } + + cpack(0); + + glBegin(GL_LINES); + /* North */ + glVertex2i(xoff, yoff + inner_length); + glVertex2i(xoff, yoff + outter_length); + + /* East */ + glVertex2i(xoff + inner_length, yoff); + glVertex2i(xoff + outter_length, yoff); + + /* South */ + glVertex2i(xoff, yoff - inner_length); + glVertex2i(xoff, yoff - outter_length); + + /* West */ + glVertex2i(xoff - inner_length, yoff); + glVertex2i(xoff - outter_length, yoff); + glEnd(); + + /* XXX print shortcuts for modal options, and current values */ +} + +static void walk_navigation_mode_set(WalkInfo *walk, eWalkMethod mode) +{ + if (mode == WALK_MODE_FREE) { + walk->navigation_mode = WALK_MODE_FREE; + walk->gravity = WALK_GRAVITY_STATE_OFF; + } + else { /* WALK_MODE_GRAVITY */ + walk->navigation_mode = WALK_MODE_GRAVITY; + walk->gravity = WALK_GRAVITY_STATE_START; + } +} + +/** + * \param ray_distance Distance to the hit point + */ +static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, float dvec[3], float *ray_distance) +{ + float dummy_dist_px = 0; + float ray_normal[3] = {0, 0, -1}; /* down */ + float ray_start[3]; + float r_location[3]; + float r_normal[3]; + float dvec_tmp[3]; + bool ret; + + *ray_distance = TRANSFORM_DIST_MAX_RAY; + + copy_v3_v3(ray_start, rv3d->viewinv[3]); + + if (dvec) { + mul_v3_v3fl(dvec_tmp, dvec, walk->grid); + add_v3_v3(ray_start, dvec_tmp); + } + + ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, + NULL, NULL, + ray_start, ray_normal, ray_distance, + NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); + + /* artifically scale the distance to the scene size */ + *ray_distance /= walk->grid; + return ret; +} + +/** + * \param ray_distance Distance to the hit point + * \param r_location Location of the hit point + * \param r_normal Normal of the hit surface, transformed to always face the camera + */ +static bool walk_ray_cast(bContext *C, RegionView3D *rv3d, WalkInfo *walk, float r_location[3], float r_normal[3], float *ray_distance) +{ + float dummy_dist_px = 0; + float ray_normal[3] = {0, 0, 1}; /* forward */ + float ray_start[3]; + float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ + bool ret; + + *ray_distance = TRANSFORM_DIST_MAX_RAY; + + copy_v3_v3(ray_start, rv3d->viewinv[3]); + copy_m3_m4(mat, rv3d->viewinv); + + mul_m3_v3(mat, ray_normal); + + mul_v3_fl(ray_normal, -1); + normalize_v3(ray_normal); + + ret = snapObjectsRayEx(CTX_data_scene(C), NULL, NULL, NULL, NULL, SCE_SNAP_MODE_FACE, + NULL, NULL, + ray_start, ray_normal, ray_distance, + NULL, &dummy_dist_px, r_location, r_normal, SNAP_ALL); + + + /* dot is positive if both rays are facing the same direction */ + if (dot_v3v3(ray_normal, r_normal) > 0) { + copy_v3_fl3(r_normal, -r_normal[0], -r_normal[1], -r_normal[2]); + } + + /* artifically scale the distance to the scene size */ + *ray_distance /= walk->grid; + + return ret; +} + +/* WalkInfo->state */ +enum { + WALK_RUNNING = 0, + WALK_CANCEL = 1, + WALK_CONFIRM = 2, +}; + +/* keep the previous speed until user changes userpreferences */ +static float base_speed = -1.f; +static float userdef_speed = -1.f; + +static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) +{ + wmWindow *win = CTX_wm_window(C); + + walk->rv3d = CTX_wm_region_view3d(C); + walk->v3d = CTX_wm_view3d(C); + walk->ar = CTX_wm_region(C); + walk->scene = CTX_data_scene(C); + +#ifdef NDOF_WALK_DEBUG + puts("\n-- walk begin --"); +#endif + + /* sanity check: for rare but possible case (if lib-linking the camera fails) */ + if ((walk->rv3d->persp == RV3D_CAMOB) && (walk->v3d->camera == NULL)) { + walk->rv3d->persp = RV3D_PERSP; + } + + if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->id.lib) { + BKE_report(op->reports, RPT_ERROR, "Cannot navigate a camera from an external library"); + return false; + } + + if (ED_view3d_offset_lock_check(walk->v3d, walk->rv3d)) { + BKE_report(op->reports, RPT_ERROR, "Cannot navigate when the view offset is locked"); + return false; + } + + if (walk->rv3d->persp == RV3D_CAMOB && walk->v3d->camera->constraints.first) { + BKE_report(op->reports, RPT_ERROR, "Cannot navigate an object with constraints"); + return false; + } + + walk->state = WALK_RUNNING; + + if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) { + base_speed = U.walk_navigation.walk_speed; + userdef_speed = U.walk_navigation.walk_speed; + } + + walk->speed = 0.0f; + walk->is_fast = false; + walk->is_slow = false; + walk->grid = 1.f / walk->scene->unit.scale_length; + + /* user preference settings */ + walk->teleport.duration = U.walk_navigation.teleport_time; + walk->mouse_speed = U.walk_navigation.mouse_speed; + + if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) + walk_navigation_mode_set(walk, WALK_MODE_GRAVITY); + else + walk_navigation_mode_set(walk, WALK_MODE_FREE); + + walk->view_height = U.walk_navigation.view_height; + walk->jump_height = U.walk_navigation.jump_height; + walk->speed = U.walk_navigation.walk_speed; + walk->speed_factor = U.walk_navigation.walk_speed_factor; + + walk->gravity = WALK_GRAVITY_STATE_OFF; + + walk->is_reversed = ((U.walk_navigation.flag & USER_WALK_MOUSE_REVERSE) != 0); + + walk->active_directions = 0; + +#ifdef NDOF_WALK_DRAW_TOOMUCH + walk->redraw = 1; +#endif + zero_v3(walk->dvec_prev); + + walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); + + walk->ndof = NULL; + + walk->time_lastdraw = PIL_check_seconds_timer(); + + walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL); + + walk->rv3d->rflag |= RV3D_NAVIGATING; + + + walk->v3d_camera_control = ED_view3d_cameracontrol_aquire( + walk->scene, walk->v3d, walk->rv3d, + (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); + + /* center the mouse */ + walk->center_mval[0] = walk->ar->winx * 0.5f; + walk->center_mval[1] = walk->ar->winy * 0.5f; + + copy_v2_v2_int(walk->prev_mval, walk->center_mval); + + WM_cursor_warp(CTX_wm_window(C), + walk->ar->winrct.xmin + walk->center_mval[0], + walk->ar->winrct.ymin + walk->center_mval[1]); + + /* remove the mouse cursor temporarily */ + WM_cursor_modal_set(win, CURSOR_NONE); + + return 1; +} + +static int walkEnd(bContext *C, WalkInfo *walk) +{ + wmWindow *win; + RegionView3D *rv3d; + + if (walk->state == WALK_RUNNING) + return OPERATOR_RUNNING_MODAL; + +#ifdef NDOF_WALK_DEBUG + puts("\n-- walk end --"); +#endif + + win = CTX_wm_window(C); + rv3d = walk->rv3d; + + WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer); + + ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel); + + ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL); + + rv3d->rflag &= ~RV3D_NAVIGATING; + + if (walk->ndof) + MEM_freeN(walk->ndof); + + /* restore the cursor */ + WM_cursor_modal_restore(win); + + /* center the mouse */ + WM_cursor_warp(win, + walk->ar->winrct.xmin + walk->center_mval[0], + walk->ar->winrct.ymin + walk->center_mval[1]); + + if (walk->state == WALK_CONFIRM) { + MEM_freeN(walk); + return OPERATOR_FINISHED; + } + + MEM_freeN(walk); + return OPERATOR_CANCELLED; +} + +static bool wm_event_is_last_mousemove(const wmEvent *event) +{ + while ((event = event->next)) { + if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + return false; + } + } + return true; +} + +static void walkEvent(bContext *C, wmOperator *UNUSED(op), WalkInfo *walk, const wmEvent *event) +{ + if (event->type == TIMER && event->customdata == walk->timer) { + walk->redraw = true; + } + else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { + + walk->moffset[0] += event->mval[0] - walk->prev_mval[0]; + walk->moffset[1] += event->mval[1] - walk->prev_mval[1]; + + copy_v2_v2_int(walk->prev_mval, event->mval); + + if ((walk->center_mval[0] != event->mval[0]) || + (walk->center_mval[1] != event->mval[1])) + { + walk->redraw = true; + + if (wm_event_is_last_mousemove(event)) { + wmWindow *win = CTX_wm_window(C); + +#ifdef __APPLE__ + if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) || + (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2)) +#endif + { + WM_cursor_warp(win, + walk->ar->winrct.xmin + walk->center_mval[0], + walk->ar->winrct.ymin + walk->center_mval[1]); + copy_v2_v2_int(walk->prev_mval, walk->center_mval); + } + } + } + } + else if (event->type == NDOF_MOTION) { + /* do these automagically get delivered? yes. */ + // puts("ndof motion detected in walk mode!"); + // static const char *tag_name = "3D mouse position"; + + wmNDOFMotionData *incoming_ndof = (wmNDOFMotionData *)event->customdata; + switch (incoming_ndof->progress) { + case P_STARTING: + /* start keeping track of 3D mouse position */ +#ifdef NDOF_WALK_DEBUG + puts("start keeping track of 3D mouse position"); +#endif + /* fall-through */ + case P_IN_PROGRESS: + /* update 3D mouse position */ +#ifdef NDOF_WALK_DEBUG + putchar('.'); fflush(stdout); +#endif + if (walk->ndof == NULL) { + // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name); + walk->ndof = MEM_dupallocN(incoming_ndof); + // walk->ndof = malloc(sizeof(wmNDOFMotionData)); + } + else { + memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData)); + } + break; + case P_FINISHING: + /* stop keeping track of 3D mouse position */ +#ifdef NDOF_WALK_DEBUG + puts("stop keeping track of 3D mouse position"); +#endif + if (walk->ndof) { + MEM_freeN(walk->ndof); + // free(walk->ndof); + walk->ndof = NULL; + } + + /* update the time else the view will jump when 2D mouse/timer resume */ + walk->time_lastdraw = PIL_check_seconds_timer(); + + break; + default: + break; /* should always be one of the above 3 */ + } + } + /* handle modal keymap first */ + else if (event->type == EVT_MODAL_MAP) { + switch (event->val) { + case WALK_MODAL_CANCEL: + walk->state = WALK_CANCEL; + break; + case WALK_MODAL_CONFIRM: + walk->state = WALK_CONFIRM; + break; + + case WALK_MODAL_ACCELERATE: + base_speed *= 1.0f + (walk->is_slow ? 0.01f : 0.1f); + break; + case WALK_MODAL_DECELERATE: + base_speed /= 1.0f + (walk->is_slow ? 0.01f : 0.1f); + break; + + /* implement WASD keys */ + case WALK_MODAL_DIR_FORWARD: + walk->active_directions |= WALK_BIT_FORWARD; + break; + case WALK_MODAL_DIR_BACKWARD: + walk->active_directions |= WALK_BIT_BACKWARD; + break; + case WALK_MODAL_DIR_LEFT: + walk->active_directions |= WALK_BIT_LEFT; + break; + case WALK_MODAL_DIR_RIGHT: + walk->active_directions |= WALK_BIT_RIGHT; + break; + case WALK_MODAL_DIR_UP: + walk->active_directions |= WALK_BIT_UP; + break; + case WALK_MODAL_DIR_DOWN: + walk->active_directions |= WALK_BIT_DOWN; + break; + + case WALK_MODAL_DIR_FORWARD_STOP: + walk->active_directions &= ~WALK_BIT_FORWARD; + break; + case WALK_MODAL_DIR_BACKWARD_STOP: + walk->active_directions &= ~WALK_BIT_BACKWARD; + break; + case WALK_MODAL_DIR_LEFT_STOP: + walk->active_directions &= ~WALK_BIT_LEFT; + break; + case WALK_MODAL_DIR_RIGHT_STOP: + walk->active_directions &= ~WALK_BIT_RIGHT; + break; + case WALK_MODAL_DIR_UP_STOP: + walk->active_directions &= ~WALK_BIT_UP; + break; + case WALK_MODAL_DIR_DOWN_STOP: + walk->active_directions &= ~WALK_BIT_DOWN; + break; + + case WALK_MODAL_FAST_ENABLE: + walk->is_fast = true; + break; + case WALK_MODAL_FAST_DISABLE: + walk->is_fast = false; + break; + case WALK_MODAL_SLOW_ENABLE: + walk->is_slow = true; + break; + case WALK_MODAL_SLOW_DISABLE: + walk->is_slow = false; + break; + +#define JUMP_SPEED_MIN 1.0f +#define JUMP_TIME_MAX 0.2f /* s */ +#define JUMP_SPEED_MAX sqrtf(2.0f * EARTH_GRAVITY * walk->jump_height) + + case WALK_MODAL_JUMP_STOP: + if (walk->gravity == WALK_GRAVITY_STATE_JUMP) { + float t; + + /* delta time */ + t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time); + + /* reduce the veolocity, if JUMP wasn't hold for long enough */ + t = min_ff(t, JUMP_TIME_MAX); + walk->speed_jump = JUMP_SPEED_MIN + t * (JUMP_SPEED_MAX - JUMP_SPEED_MIN) / JUMP_TIME_MAX; + + /* when jumping, duration is how long it takes before we start going down */ + walk->teleport.duration = getVelocityZeroTime(walk->speed_jump); + + /* no more increase of jump speed */ + walk->gravity = WALK_GRAVITY_STATE_ON; + } + break; + case WALK_MODAL_JUMP: + if ((walk->navigation_mode == WALK_MODE_GRAVITY) && + (walk->gravity == WALK_GRAVITY_STATE_OFF) && + (walk->teleport.state == WALK_TELEPORT_STATE_OFF)) + { + /* no need to check for ground, + * walk->gravity wouldn't be off + * if we were over a hole */ + walk->gravity = WALK_GRAVITY_STATE_JUMP; + walk->speed_jump = JUMP_SPEED_MAX; + + walk->teleport.initial_time = PIL_check_seconds_timer(); + copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]); + + /* using previous vec because WASD keys are not called when SPACE is */ + copy_v2_v2(walk->teleport.direction, walk->dvec_prev); + + /* when jumping, duration is how long it takes before we start going down */ + walk->teleport.duration = getVelocityZeroTime(walk->speed_jump); + } + + break; + + case WALK_MODAL_TELEPORT: + { + float loc[3], nor[3]; + float distance; + bool ret = walk_ray_cast(C, walk->rv3d, walk, loc, nor, &distance); + + /* in case we are teleporting middle way from a jump */ + walk->speed_jump = 0.0f; + + if (ret) { + WalkTeleport *teleport = &walk->teleport; + teleport->state = WALK_TELEPORT_STATE_ON; + teleport->initial_time = PIL_check_seconds_timer(); + teleport->duration = U.walk_navigation.teleport_time; + + teleport->navigation_mode = walk->navigation_mode; + walk_navigation_mode_set(walk, WALK_MODE_FREE); + + copy_v3_v3(teleport->origin, walk->rv3d->viewinv[3]); + + /* stop the camera from a distance (camera height) */ + normalize_v3(nor); + mul_v3_fl(nor, walk->view_height); + add_v3_v3(loc, nor); + + sub_v3_v3v3(teleport->direction, loc, teleport->origin); + } + else { + walk->teleport.state = WALK_TELEPORT_STATE_OFF; + } + break; + } + +#undef JUMP_SPEED_MAX +#undef JUMP_TIME_MAX +#undef JUMP_SPEED_MIN + + case WALK_MODAL_TOGGLE: + if (walk->navigation_mode == WALK_MODE_GRAVITY) { + walk_navigation_mode_set(walk, WALK_MODE_FREE); + } + else { /* WALK_MODE_FREE */ + walk_navigation_mode_set(walk, WALK_MODE_GRAVITY); + } + break; + } + } +} + +static void walkMoveCamera(bContext *C, WalkInfo *walk, + const bool do_rotate, const bool do_translate) +{ + ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate); +} + +static float getFreeFallDistance(const float time) +{ + return EARTH_GRAVITY * (time * time) * 0.5f; +} + +static float getVelocityZeroTime(float velocity) +{ + return velocity / EARTH_GRAVITY; +} + +static int walkApply(bContext *C, WalkInfo *walk) +{ +#define WALK_ROTATE_FAC 2.2f /* more is faster */ +#define WALK_TOP_LIMIT DEG2RADF(85.0f) +#define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f) +#define WALK_MOVE_SPEED base_speed +#define WALK_BOOST_FACTOR ((void)0, walk->speed_factor) + + /* walk mode - Ctrl+Shift+F + * a walk loop where the user can move move the view as if they are in a walk game + */ + RegionView3D *rv3d = walk->rv3d; + ARegion *ar = walk->ar; + + float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ + float dvec[3] = {0.0f, 0.0f, 0.0f}; /* this is the direction that's added to the view offset per redraw */ + + /* Camera Uprighting variables */ + float upvec[3] = {0.0f, 0.0f, 0.0f}; /* stores the view's up vector */ + + int moffset[2]; /* mouse offset from the views center */ + float tmp_quat[4]; /* used for rotating the view */ + +#ifdef NDOF_WALK_DEBUG + { + static unsigned int iteration = 1; + printf("walk timer %d\n", iteration++); + } +#endif + + { + /* mouse offset from the center */ + copy_v2_v2_int(moffset, walk->moffset); + + /* apply moffset so we can re-accumulate */ + walk->moffset[0] = 0; + walk->moffset[1] = 0; + + /* revert mouse */ + if (walk->is_reversed) { + moffset[1] = -moffset[1]; + } + + /* Should we redraw? */ + if ((walk->active_directions) || + moffset[0] || moffset[1] || + walk->teleport.state == WALK_TELEPORT_STATE_ON || + walk->gravity != WALK_GRAVITY_STATE_OFF) + { + float dvec_tmp[3]; + + /* time how fast it takes for us to redraw, + * this is so simple scenes don't walk too fast */ + double time_current; + float time_redraw; +#ifdef NDOF_WALK_DRAW_TOOMUCH + walk->redraw = 1; +#endif + time_current = PIL_check_seconds_timer(); + time_redraw = (float)(time_current - walk->time_lastdraw); + + walk->time_lastdraw = time_current; + + /* base speed in m/s */ + walk->speed = WALK_MOVE_SPEED; + + if (walk->is_fast) { + walk->speed *= WALK_BOOST_FACTOR; + } + else if (walk->is_slow) { + walk->speed *= 1.0f / WALK_BOOST_FACTOR; + } + + copy_m3_m4(mat, rv3d->viewinv); + + { + /* rotate about the X axis- look up/down */ + if (moffset[1]) { + float angle; + float y; + + /* relative offset */ + y = (float) moffset[1] / ar->winy; + + /* speed factor */ + y *= WALK_ROTATE_FAC; + + /* user adjustement factor */ + y *= walk->mouse_speed; + + /* clamp the angle limits */ + /* it ranges from 90.0f to -90.0f */ + angle = -asin(rv3d->viewmat[2][2]); + + if (angle > WALK_TOP_LIMIT && y > 0.0f) + y = 0.0f; + + else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) + y = 0.0f; + + copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); + mul_m3_v3(mat, upvec); + /* Rotate about the relative up vec */ + axis_angle_to_quat(tmp_quat, upvec, -y); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + } + + /* rotate about the Y axis- look left/right */ + if (moffset[0]) { + float x; + + /* if we're upside down invert the moffset */ + copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f); + mul_m3_v3(mat, upvec); + + if (upvec[2] < 0.0f) + moffset[0] = -moffset[0]; + + /* relative offset */ + x = (float) moffset[0] / ar->winx; + + /* speed factor */ + x *= WALK_ROTATE_FAC; + + /* user adjustement factor */ + x *= walk->mouse_speed; + + copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); + + /* Rotate about the relative up vec */ + axis_angle_to_quat(tmp_quat, upvec, x); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); + } + } + + /* WASD - 'move' translation code */ + if ((walk->active_directions) && + (walk->gravity == WALK_GRAVITY_STATE_OFF)) + { + + short direction; + zero_v3(dvec); + + if ((walk->active_directions & WALK_BIT_FORWARD) || + (walk->active_directions & WALK_BIT_BACKWARD)) + { + + direction = 0; + + if ((walk->active_directions & WALK_BIT_FORWARD)) + direction += 1; + + if ((walk->active_directions & WALK_BIT_BACKWARD)) + direction -= 1; + + copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction); + mul_m3_v3(mat, dvec_tmp); + + if (walk->navigation_mode == WALK_MODE_GRAVITY) { + dvec_tmp[2] = 0.0f; + } + + normalize_v3(dvec_tmp); + add_v3_v3(dvec, dvec_tmp); + + } + + if ((walk->active_directions & WALK_BIT_LEFT) || + (walk->active_directions & WALK_BIT_RIGHT)) + { + + direction = 0; + + if ((walk->active_directions & WALK_BIT_LEFT)) + direction += 1; + + if ((walk->active_directions & WALK_BIT_RIGHT)) + direction -= 1; + + dvec_tmp[0] = direction * rv3d->viewinv[0][0]; + dvec_tmp[1] = direction * rv3d->viewinv[0][1]; + dvec_tmp[2] = 0.0f; + + normalize_v3(dvec_tmp); + add_v3_v3(dvec, dvec_tmp); + + } + + if ((walk->active_directions & WALK_BIT_UP) || + (walk->active_directions & WALK_BIT_DOWN)) + { + + if (walk->navigation_mode == WALK_MODE_FREE) { + + direction = 0; + + if ((walk->active_directions & WALK_BIT_UP)) + direction -= 1; + + if ((walk->active_directions & WALK_BIT_DOWN)) + direction = 1; + + copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction); + add_v3_v3(dvec, dvec_tmp); + } + } + + /* apply movement */ + mul_v3_fl(dvec, walk->speed * time_redraw); + } + + /* stick to the floor */ + if (walk->navigation_mode == WALK_MODE_GRAVITY && + ELEM(walk->gravity, + WALK_GRAVITY_STATE_OFF, + WALK_GRAVITY_STATE_START)) + { + + bool ret; + float ray_distance; + float difference = -100.0f; + float fall_distance; + + ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance); + + if (ret) { + difference = walk->view_height - ray_distance; + } + + /* the distance we would fall naturally smoothly enough that we + can manually drop the object without activating gravity */ + fall_distance = time_redraw * walk->speed * WALK_BOOST_FACTOR; + + if (fabsf(difference) < fall_distance) { + /* slope/stairs */ + dvec[2] -= difference; + + /* in case we switched from FREE to GRAVITY too close to the ground */ + if (walk->gravity == WALK_GRAVITY_STATE_START) + walk->gravity = WALK_GRAVITY_STATE_OFF; + } + else { + /* hijack the teleport variables */ + walk->teleport.initial_time = PIL_check_seconds_timer(); + walk->gravity = WALK_GRAVITY_STATE_ON; + walk->teleport.duration = 0.0f; + + copy_v3_v3(walk->teleport.origin, walk->rv3d->viewinv[3]); + copy_v2_v2(walk->teleport.direction, dvec); + + } + } + + /* Falling or jumping) */ + if (ELEM(walk->gravity, WALK_GRAVITY_STATE_ON, WALK_GRAVITY_STATE_JUMP)) { + float t; + float z_old, z_new; + bool ret; + float ray_distance, difference = -100.0f; + + /* delta time */ + t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time); + + /* keep moving if we were moving */ + copy_v2_v2(dvec, walk->teleport.direction); + + z_old = walk->rv3d->viewinv[3][2]; + z_new = walk->teleport.origin[2] - getFreeFallDistance(t) * walk->grid; + + /* jump */ + z_new += t * walk->speed_jump * walk->grid; + + dvec[2] = z_old - z_new; + + /* duration is the jump duration */ + if (t > walk->teleport.duration) { + /* check to see if we are landing */ + ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance); + + if (ret) { + difference = walk->view_height - ray_distance; + } + + if (ray_distance < walk->view_height) { + /* quit falling */ + dvec[2] -= difference; + walk->gravity = WALK_GRAVITY_STATE_OFF; + walk->speed_jump = 0.0f; + } + } + } + + /* Teleport */ + else if (walk->teleport.state == WALK_TELEPORT_STATE_ON) { + float t; /* factor */ + float new_loc[3]; + float cur_loc[3]; + + /* linear interpolation */ + t = (float)(PIL_check_seconds_timer() - walk->teleport.initial_time); + t /= walk->teleport.duration; + + /* clamp so we don't go past our limit */ + if (t >= 1.0f) { + t = 1.0f; + walk->teleport.state = WALK_TELEPORT_STATE_OFF; + walk_navigation_mode_set(walk, walk->teleport.navigation_mode); + } + + mul_v3_v3fl(new_loc, walk->teleport.direction, t); + add_v3_v3(new_loc, walk->teleport.origin); + + copy_v3_v3(cur_loc, walk->rv3d->viewinv[3]); + sub_v3_v3v3(dvec, cur_loc, new_loc); + } + + if (rv3d->persp == RV3D_CAMOB) { + Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); + if (lock_ob->protectflag & OB_LOCK_LOCX) dvec[0] = 0.0f; + if (lock_ob->protectflag & OB_LOCK_LOCY) dvec[1] = 0.0f; + if (lock_ob->protectflag & OB_LOCK_LOCZ) dvec[2] = 0.0f; + } + + /* scale the movement to the scene size */ + mul_v3_v3fl(dvec_tmp, dvec, walk->grid); + add_v3_v3(rv3d->ofs, dvec_tmp); + + if (rv3d->persp == RV3D_CAMOB) { + const bool do_rotate = (moffset[0] || moffset[1]); + const bool do_translate = (walk->speed != 0.0f); + walkMoveCamera(C, walk, do_rotate, do_translate); + } + } + else { + /* we're not redrawing but we need to update the time else the view will jump */ + walk->time_lastdraw = PIL_check_seconds_timer(); + } + /* end drawing */ + copy_v3_v3(walk->dvec_prev, dvec); + } + + return OPERATOR_FINISHED; +#undef WALK_ROTATE_FAC +#undef WALK_ZUP_CORRECT_FAC +#undef WALK_ZUP_CORRECT_ACCEL +#undef WALK_SMOOTH_FAC +#undef WALK_TOP_LIMIT +#undef WALK_BOTTOM_LIMIT +#undef WALK_MOVE_SPEED +#undef WALK_BOOST_FACTOR +} + +static int walkApply_ndof(bContext *C, WalkInfo *walk) +{ + /* shorthand for oft-used variables */ + wmNDOFMotionData *ndof = walk->ndof; + const float dt = ndof->dt; + RegionView3D *rv3d = walk->rv3d; + const int flag = U.ndof_flag; + +#if 0 + bool do_rotate = (flag & NDOF_SHOULD_ROTATE) && (walk->pan_view == false); + bool do_translate = (flag & (NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM)) != 0; +#endif + + bool do_rotate = false; + bool do_translate = true; + + float view_inv[4]; + invert_qt_qt(view_inv, rv3d->viewquat); + + rv3d->rot_angle = 0.0f; /* disable onscreen rotation doo-dad */ + + if (do_translate) { + const float forward_sensitivity = 1.0f; + const float vertical_sensitivity = 0.4f; + const float lateral_sensitivity = 0.6f; + + float speed = 10.0f; /* blender units per second */ + /* ^^ this is ok for default cube scene, but should scale with.. something */ + + float trans[3] = {lateral_sensitivity * ndof->tvec[0], + vertical_sensitivity * ndof->tvec[1], + forward_sensitivity * ndof->tvec[2]}; + + if (walk->is_slow) + speed *= 0.2f; + + mul_v3_fl(trans, speed * dt); + + /* transform motion from view to world coordinates */ + mul_qt_v3(view_inv, trans); + + if (flag & NDOF_FLY_HELICOPTER) { + /* replace world z component with device y (yes it makes sense) */ + trans[2] = speed * dt * vertical_sensitivity * ndof->tvec[1]; + } + + if (rv3d->persp == RV3D_CAMOB) { + /* respect camera position locks */ + Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); + if (lock_ob->protectflag & OB_LOCK_LOCX) trans[0] = 0.0f; + if (lock_ob->protectflag & OB_LOCK_LOCY) trans[1] = 0.0f; + if (lock_ob->protectflag & OB_LOCK_LOCZ) trans[2] = 0.0f; + } + + if (!is_zero_v3(trans)) { + /* move center of view opposite of hand motion (this is camera mode, not object mode) */ + sub_v3_v3(rv3d->ofs, trans); + do_translate = true; + } + else { + do_translate = false; + } + } + + if (do_rotate) { + const float turn_sensitivity = 1.0f; + + float rotation[4]; + float axis[3]; + float angle = turn_sensitivity * ndof_to_axis_angle(ndof, axis); + + if (fabsf(angle) > 0.0001f) { + do_rotate = true; + + if (walk->is_slow) + angle *= 0.2f; + + /* transform rotation axis from view to world coordinates */ + mul_qt_v3(view_inv, axis); + + /* apply rotation to view */ + axis_angle_to_quat(rotation, axis, angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation); + + if (flag & NDOF_LOCK_HORIZON) { + /* force an upright viewpoint + * TODO: make this less... sudden */ + float view_horizon[3] = {1.0f, 0.0f, 0.0f}; /* view +x */ + float view_direction[3] = {0.0f, 0.0f, -1.0f}; /* view -z (into screen) */ + + /* find new inverse since viewquat has changed */ + invert_qt_qt(view_inv, rv3d->viewquat); + /* could apply reverse rotation to existing view_inv to save a few cycles */ + + /* transform view vectors to world coordinates */ + mul_qt_v3(view_inv, view_horizon); + mul_qt_v3(view_inv, view_direction); + + + /* find difference between view & world horizons + * true horizon lives in world xy plane, so look only at difference in z */ + angle = -asinf(view_horizon[2]); + +#ifdef NDOF_WALK_DEBUG + printf("lock horizon: adjusting %.1f degrees\n\n", RAD2DEG(angle)); +#endif + + /* rotate view so view horizon = world horizon */ + axis_angle_to_quat(rotation, view_direction, angle); + mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, rotation); + } + + rv3d->view = RV3D_VIEW_USER; + } + else { + do_rotate = false; + } + } + + if (do_translate || do_rotate) { + walk->redraw = true; + + if (rv3d->persp == RV3D_CAMOB) { + walkMoveCamera(C, walk, do_rotate, do_translate); + } + } + + return OPERATOR_FINISHED; +} + +/****** walk operator ******/ +static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + RegionView3D *rv3d = CTX_wm_region_view3d(C); + WalkInfo *walk; + + if (rv3d->viewlock) + return OPERATOR_CANCELLED; + + walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation"); + + op->customdata = walk; + + if (initWalkInfo(C, walk, op) == false) { + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; + } + + walkEvent(C, op, walk, event); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static void walk_cancel(bContext *C, wmOperator *op) +{ + WalkInfo *walk = op->customdata; + + walk->state = WALK_CANCEL; + walkEnd(C, walk); + op->customdata = NULL; +} + +static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + int exit_code; + bool do_draw = false; + WalkInfo *walk = op->customdata; + RegionView3D *rv3d = walk->rv3d; + Object *walk_object = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); + + walk->redraw = false; + + walkEvent(C, op, walk, event); + + if (walk->ndof) { /* 3D mouse overrules [2D mouse + timer] */ + if (event->type == NDOF_MOTION) { + walkApply_ndof(C, walk); + } + } + else if (event->type == TIMER && event->customdata == walk->timer) { + walkApply(C, walk); + } + + do_draw |= walk->redraw; + + exit_code = walkEnd(C, walk); + + if (exit_code != OPERATOR_RUNNING_MODAL) + do_draw = true; + + if (do_draw) { + if (rv3d->persp == RV3D_CAMOB) { + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, walk_object); + } + + // puts("redraw!"); // too frequent, commented with NDOF_WALK_DRAW_TOOMUCH for now + ED_region_tag_redraw(CTX_wm_region(C)); + } + + return exit_code; +} + +void VIEW3D_OT_walk(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Walk Navigation"; + ot->description = "Interactively walk around the scene"; + ot->idname = "VIEW3D_OT_walk"; + + /* api callbacks */ + ot->invoke = walk_invoke; + ot->cancel = walk_cancel; + ot->modal = walk_modal; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_BLOCKING; +} + +#undef EARTH_GRAVITY diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2756685e9f6..2ae94fb6d5a 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1468,7 +1468,7 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], float t->mode = TFM_DUMMY; - initTransInfo(C, t, NULL, NULL); // internal data, mouse, vectors + initTransInfo(C, t, NULL, NULL); /* avoid doing connectivity lookups (when V3D_LOCAL is set) */ t->around = V3D_CENTER; @@ -1758,7 +1758,7 @@ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) ED_region_visible_rect(ar, &rect); - BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); + BLF_width_and_height_default(printable, BLF_DRAW_STR_DUMMY_MAX, &printable_size[0], &printable_size[1]); xco = rect.xmax - (int)printable_size[0] - 10; yco = rect.ymax - (int)printable_size[1] - 10; @@ -1970,9 +1970,7 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even t->launch_event = LEFTMOUSE; } - if (!initTransInfo(C, t, op, event)) { /* internal data, mouse, vectors */ - return 0; - } + initTransInfo(C, t, op, event); if (t->spacetype == SPACE_VIEW3D) { //calc_manipulator_stats(curarea); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index ab5f034c836..1e7052926b3 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -615,7 +615,7 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val /*********************** Generics ********************************/ -int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, const struct wmEvent *event); +void initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, const struct wmEvent *event); void postTrans(struct bContext *C, TransInfo *t); void resetTransModal(TransInfo *t); void resetTransRestrictions(TransInfo *t); @@ -648,8 +648,9 @@ void initTransformOrientation(struct bContext *C, TransInfo *t); bool createSpaceNormal(float mat[3][3], const float normal[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); +struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], + const char *name, const bool overwrite); +bool applyTransformOrientation(const struct bContext *C, float mat[3][3], char r_name[64]); #define ORIENTATION_NONE 0 #define ORIENTATION_NORMAL 1 @@ -657,7 +658,7 @@ void applyTransformOrientation(const struct bContext *C, float mat[3][3], char * #define ORIENTATION_EDGE 3 #define ORIENTATION_FACE 4 -int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3], int activeOnly); +int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3], const bool activeOnly); void freeEdgeSlideTempFaces(EdgeSlideData *sld); void freeEdgeSlideVerts(TransInfo *t); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 4ba87eb8c39..894145c9e9d 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -576,7 +576,15 @@ void setConstraint(TransInfo *t, float space[3][3], int mode, const char text[]) void setAxisMatrixConstraint(TransInfo *t, int mode, const char text[]) { if (t->total == 1) { - setConstraint(t, t->data->axismtx, mode, text); + float axismtx[3][3]; + if (t->flag & T_EDIT) { + mul_m3_m3m3(axismtx, t->obedit_mat, t->data->axismtx); + } + else { + copy_m3_m3(axismtx, t->data->axismtx); + } + + setConstraint(t, axismtx, mode, text); } else { BLI_strncpy(t->con.text + 1, text, sizeof(t->con.text) - 1); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 06da1edbcdc..c41b4deca31 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5071,7 +5071,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, /* get flags used for inserting keyframes */ flag = ANIM_get_keyframing_flags(scene, 1); - /* add datasource override for the camera object */ + /* add datasource override for the object */ ANIM_relative_keyingset_add_source(&dsources, id, NULL, NULL); if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (active_ks)) { @@ -5143,6 +5143,22 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, View3D *v3d, Object *ob, ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); } + /* only calculate paths if there are paths to be recalculated, + * assuming that since we've autokeyed the transforms this is + * now safe to apply... + * + * NOTE: only do this when there's context info + */ + if (C && (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) { + //ED_objects_clear_paths(C); // XXX for now, don't need to clear + ED_objects_recalculate_paths(C, scene); + + /* XXX: there's potential here for problems with unkeyed rotations/scale, + * but for now (until proper data-locality for baking operations), + * this should be a better fix for T24451 and T37755 + */ + } + /* free temp info */ BLI_freelistN(&dsources); } @@ -5787,7 +5803,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* do nothing */ } else { /* Objects */ - int i, recalcObPaths = 0; + int i; BLI_assert(t->flag & (T_OBJECT | T_TEXTURE)); @@ -5824,11 +5840,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* Set autokey if necessary */ if (!canceled) { autokeyframe_ob_cb_func(C, t->scene, (View3D *)t->view, ob, t->mode); - - /* only calculate paths if there are paths to be recalculated */ - if (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) - recalcObPaths = 1; } + /* restore rigid body transform */ if (ob->rigidbody_object && canceled) { float ctime = BKE_scene_frame_get(t->scene); @@ -5836,25 +5849,6 @@ void special_aftertrans_update(bContext *C, TransInfo *t) BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle); } } - - /* recalculate motion paths for objects (if necessary) - * NOTE: only do this when there is context info - */ - if (C && recalcObPaths) { - //ED_objects_clear_paths(C); // XXX for now, don't need to clear - ED_objects_recalculate_paths(C, t->scene); - - /* recalculating the frame positions means we loose our original transform if its not auto-keyed [#24451] - * this hack re-applies it, which is annoying, only alternatives are... - * - don't recalc paths. - * - have an BKE_object_handle_update() which gives is the new transform without touching the objects. - * - only recalc paths on auto-keying. - * - ED_objects_recalculate_paths could backup/restore transforms. - * - re-apply the transform which is simplest in this case. (2 lines below) - */ - t->redraw |= TREDRAW_HARD; - transformApply(C, t); - } } clear_trans_object_base_flags(t); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 95b6067f2c4..0ff94fb4f1c 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1029,8 +1029,12 @@ static int initTransInfo_edit_pet_to_flag(const int proportional) } } -/* the *op can be NULL */ -int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event) +/** + * Setup internal data, mouse, vectors + * + * \note \a op and \a event can be NULL + */ +void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event) { Scene *sce = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); @@ -1321,8 +1325,6 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *even setTransformViewMatrices(t); initNumInput(&t->num); - - return 1; } /* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */ diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 132a46441e6..5ac97ed4e26 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -642,8 +642,9 @@ int calc_manipulator_stats(const bContext *C) default: /* V3D_MANIP_CUSTOM */ { float mat[3][3]; - applyTransformOrientation(C, mat, NULL); - copy_m4_m3(rv3d->twmat, mat); + if (applyTransformOrientation(C, mat, NULL)) { + copy_m4_m3(rv3d->twmat, mat); + } break; } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 106024cd3e2..3a83445ba5f 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -533,7 +533,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) } } - if (flags & P_OPTIONS) { + if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) { RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space"); prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel"); RNA_def_property_flag(prop, PROP_HIDDEN); @@ -617,7 +617,7 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot) RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS); + Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_NO_TEXSPACE); } static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) @@ -703,7 +703,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) /* api callbacks */ ot->invoke = transform_invoke; - ot->exec = transform_exec; + // ot->exec = transform_exec; // unsupported ot->modal = transform_modal; ot->cancel = transform_cancel; ot->poll = ED_operator_region_view3d_active; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index cd6a2e6712e..be8bc460764 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -26,6 +26,7 @@ #include <string.h> +#include <stddef.h> #include <ctype.h> #include "MEM_guardedalloc.h" @@ -40,7 +41,9 @@ #include "DNA_view3d_types.h" #include "BLI_math.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" #include "BLI_utildefines.h" #include "BKE_action.h" @@ -49,6 +52,8 @@ #include "BKE_context.h" #include "BKE_editmesh.h" #include "BKE_report.h" +#include "BKE_main.h" +#include "BKE_screen.h" #include "BLF_translation.h" @@ -78,15 +83,7 @@ void BIF_clearTransformOrientation(bContext *C) static TransformOrientation *findOrientationName(ListBase *lb, const char *name) { - TransformOrientation *ts = NULL; - - for (ts = lb->first; ts; ts = ts->next) { - if (strncmp(ts->name, name, sizeof(ts->name) - 1) == 0) { - return ts; - } - } - - return NULL; + return BLI_findstring(lb, name, offsetof(TransformOrientation, name)); } static bool uniqueOrientationNameCheck(void *arg, const char *name) @@ -100,7 +97,8 @@ static void uniqueOrientationName(ListBase *lb, char *name) sizeof(((TransformOrientation *)NULL)->name)); } -static TransformOrientation *createViewSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite) +static TransformOrientation *createViewSpace(bContext *C, ReportList *UNUSED(reports), + const char *name, const bool overwrite) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float mat[3][3]; @@ -111,21 +109,22 @@ static TransformOrientation *createViewSpace(bContext *C, ReportList *UNUSED(rep copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); - if (!name[0]) { + if (name[0] == 0) { 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! */ - BLI_strncpy(name, v3d->camera->id.name + 2, MAX_NAME); + name = v3d->camera->id.name + 2; } else { - strcpy(name, "Custom View"); + name = "Custom View"; } } return addMatrixSpace(C, mat, name, overwrite); } -static TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), char *name, int overwrite) +static TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(reports), + const char *name, const bool overwrite) { Base *base = CTX_data_active_base(C); Object *ob; @@ -141,13 +140,14 @@ static TransformOrientation *createObjectSpace(bContext *C, ReportList *UNUSED(r /* use object name if no name is given */ if (name[0] == 0) { - BLI_strncpy(name, ob->id.name + 2, MAX_ID_NAME - 2); + name = ob->id.name + 2; } return addMatrixSpace(C, mat, name, overwrite); } -static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) +static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, + const char *name, const bool overwrite) { float mat[3][3]; float normal[3], plane[3]; @@ -160,13 +160,14 @@ static TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, c } if (name[0] == 0) { - strcpy(name, "Bone"); + name = "Bone"; } return addMatrixSpace(C, mat, name, overwrite); } -static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, char *name, int overwrite) +static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, + const char *name, const bool overwrite) { float mat[3][3]; float normal[3], plane[3]; @@ -179,14 +180,15 @@ static TransformOrientation *createCurveSpace(bContext *C, ReportList *reports, } if (name[0] == 0) { - strcpy(name, "Curve"); + name = "Curve"; } return addMatrixSpace(C, mat, name, overwrite); } -static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) +static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, + const char *name, const bool overwrite) { float mat[3][3]; float normal[3], plane[3]; @@ -202,7 +204,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, c } if (name[0] == 0) { - strcpy(name, "Vertex"); + name = "Vertex"; } break; case ORIENTATION_EDGE: @@ -212,7 +214,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, c } if (name[0] == 0) { - strcpy(name, "Edge"); + name = "Edge"; } break; case ORIENTATION_FACE: @@ -222,7 +224,7 @@ static TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, c } if (name[0] == 0) { - strcpy(name, "Face"); + name = "Face"; } break; default: @@ -288,8 +290,9 @@ bool createSpaceNormalTangent(float mat[3][3], const float normal[3], const floa return true; } -/* name must be a MAX_NAME length string! */ -void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use_view, int use, int overwrite) +void BIF_createTransformOrientation(bContext *C, ReportList *reports, + const char *name, const bool use_view, + const bool activate, const bool overwrite) { TransformOrientation *ts = NULL; @@ -315,21 +318,25 @@ void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name } } - if (use && ts != NULL) { + if (activate && ts != NULL) { BIF_selectTransformOrientation(C, ts); } } -TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) +TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], + const char *name, const bool overwrite) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts = NULL; + char name_unique[sizeof(ts->name)]; if (overwrite) { ts = findOrientationName(transform_spaces, name); } else { - uniqueOrientationName(transform_spaces, name); + BLI_strncpy(name_unique, name, sizeof(name_unique)); + uniqueOrientationName(transform_spaces, name_unique); + name = name_unique; } /* if not, create a new one */ @@ -347,29 +354,14 @@ TransformOrientation *addMatrixSpace(bContext *C, float mat[3][3], char name[], void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) { - ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int i; - - for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { - if (ts == target) { - View3D *v3d = CTX_wm_view3d(C); - if (v3d) { - int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); - - // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D - if (selected_index == i) { - v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ - } - else if (selected_index > i) { - v3d->twmode--; - } - - } + Scene *scene = CTX_data_scene(C); + ListBase *transform_spaces = &scene->transform_spaces; + const int i = BLI_findindex(transform_spaces, target); - BLI_freelinkN(transform_spaces, ts); - break; - } + if (i != -1) { + Main *bmain = CTX_data_main(C); + BKE_screen_view3d_main_twmode_remove(&bmain->screen, scene, i); + BLI_freelinkN(transform_spaces, target); } } @@ -379,36 +371,18 @@ void BIF_removeTransformOrientationIndex(bContext *C, int index) TransformOrientation *ts = BLI_findlink(transform_spaces, index); if (ts) { - View3D *v3d = CTX_wm_view3d(C); - if (v3d) { - int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); - - // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D - if (selected_index == index) { - v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ - } - else if (selected_index > index) { - v3d->twmode--; - } - - } - - BLI_freelinkN(transform_spaces, ts); + BIF_removeTransformOrientation(C, ts); } } void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - View3D *v3d = CTX_wm_view3d(C); - TransformOrientation *ts; - int i; - - for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { - if (ts == target) { - v3d->twmode = V3D_MANIP_CUSTOM + i; - break; - } + const int i = BLI_findindex(transform_spaces, target); + + if (i != -1) { + View3D *v3d = CTX_wm_view3d(C); + v3d->twmode = V3D_MANIP_CUSTOM + i; } } @@ -422,42 +396,37 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation) int BIF_countTransformOrientation(const bContext *C) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int count = 0; - - for (ts = transform_spaces->first; ts; ts = ts->next) { - count++; - } - - return count; + return BLI_countlist(transform_spaces); } -void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME]) +bool applyTransformOrientation(const bContext *C, float mat[3][3], char *r_name) { - TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); - int i; - - if (selected_index >= 0) { - for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { - if (selected_index == i) { - - if (name) { - BLI_strncpy(name, ts->name, MAX_NAME); - } - - copy_m3_m3(mat, ts->mat); - break; - } + + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; + TransformOrientation *ts = BLI_findlink(transform_spaces, selected_index); + + BLI_assert(selected_index >= 0); + + if (ts) { + if (r_name) { + BLI_strncpy(r_name, ts->name, MAX_NAME); } + + copy_m3_m3(mat, ts->mat); + return true; + } + else { + /* invalid index, can happen sometimes */ + return false; } } -static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) +static int count_bone_select(bArmature *arm, ListBase *lb, const bool do_it) { Bone *bone; - int do_next; + bool do_next; int total = 0; for (bone = lb->first; bone; bone = bone->next) { @@ -468,7 +437,9 @@ static int count_bone_select(bArmature *arm, ListBase *lb, int do_it) if (bone->flag & BONE_SELECTED) { bone->flag |= BONE_TRANSFORM; total++; - do_next = FALSE; // no transform on children if one parent bone is selected + + /* no transform on children if one parent bone is selected */ + do_next = false; } } } @@ -487,25 +458,25 @@ void initTransformOrientation(bContext *C, TransInfo *t) switch (t->current_orientation) { case V3D_MANIP_GLOBAL: unit_m3(t->spacemtx); - strcpy(t->spacename, IFACE_("global")); + BLI_strncpy(t->spacename, IFACE_("global"), sizeof(t->spacename)); break; case V3D_MANIP_GIMBAL: unit_m3(t->spacemtx); if (gimbal_axis(ob, t->spacemtx)) { - strcpy(t->spacename, IFACE_("gimbal")); + BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename)); break; } /* fall-through */ /* no gimbal fallthrough to normal */ case V3D_MANIP_NORMAL: if (obedit || (ob && ob->mode & OB_MODE_POSE)) { - strcpy(t->spacename, IFACE_("normal")); + BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename)); ED_getTransformOrientationMatrix(C, t->spacemtx, (v3d->around == V3D_ACTIVE)); break; } /* fall-through */ /* we define 'normal' as 'local' in Object mode */ case V3D_MANIP_LOCAL: - strcpy(t->spacename, IFACE_("local")); + BLI_strncpy(t->spacename, IFACE_("local"), sizeof(t->spacename)); if (ob) { copy_m3_m4(t->spacemtx, ob->obmat); @@ -522,7 +493,7 @@ void initTransformOrientation(bContext *C, TransInfo *t) RegionView3D *rv3d = t->ar->regiondata; float mat[3][3]; - strcpy(t->spacename, IFACE_("view")); + BLI_strncpy(t->spacename, IFACE_("view"), sizeof(t->spacename)); copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); copy_m3_m3(t->spacemtx, mat); @@ -532,12 +503,17 @@ void initTransformOrientation(bContext *C, TransInfo *t) } break; default: /* V3D_MANIP_CUSTOM */ - applyTransformOrientation(C, t->spacemtx, t->spacename); + if (applyTransformOrientation(C, t->spacemtx, t->spacename)) { + /* pass */ + } + else { + unit_m3(t->spacemtx); + } break; } } -int getTransformOrientation(const bContext *C, float normal[3], float plane[3], int activeOnly) +int getTransformOrientation(const bContext *C, float normal[3], float plane[3], const bool activeOnly) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -601,7 +577,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (em->bm->totvertsel == 3) { BMVert *v1 = NULL, *v2 = NULL, *v3 = NULL; BMIter iter; - float cotangent[3]; BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { @@ -612,11 +587,37 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], v2 = eve; } else { + float no_test[3]; + + float tan_a[3], tan_b[3], tan_c[3]; + float len_a, len_b, len_c; + const float *tan_best; + + v3 = eve; + sub_v3_v3v3(tan_a, v2->co, v1->co); + sub_v3_v3v3(tan_b, v3->co, v2->co); + sub_v3_v3v3(tan_c, v1->co, v3->co); + cross_v3_v3v3(normal, tan_b, tan_a); + + /* check if the normal is pointing opposite to vert normals */ + no_test[0] = v1->no[0] + v2->no[0] + v3->no[0]; + no_test[1] = v1->no[1] + v2->no[1] + v3->no[1]; + no_test[2] = v1->no[2] + v2->no[2] + v3->no[2]; + if (dot_v3v3(no_test, normal) < 0.0f) { + negate_v3(normal); + } + + /* always give the plane to the 2 most distant verts */ + len_a = len_squared_v3(tan_a); + len_b = len_squared_v3(tan_b); + len_c = len_squared_v3(tan_c); + + tan_best = MAX3_PAIR(len_a, len_b, len_c, + tan_a, tan_b, tan_c); + + copy_v3_v3(plane, tan_best); - sub_v3_v3v3(plane, v2->co, v1->co); - sub_v3_v3v3(cotangent, v3->co, v2->co); - cross_v3_v3v3(normal, cotangent, plane); break; } } @@ -663,9 +664,9 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else { v2 = eve; - copy_v3_v3(plane, v1->no); - add_v3_v3(plane, v2->no); - sub_v3_v3v3(normal, v2->co, v1->co); + copy_v3_v3(normal, v1->no); + add_v3_v3(normal, v2->no); + sub_v3_v3v3(plane, v2->co, v1->co); break; } } @@ -864,7 +865,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else { int totsel; - totsel = count_bone_select(arm, &arm->bonebase, 1); + totsel = count_bone_select(arm, &arm->bonebase, true); if (totsel) { /* use channels to get stats */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 4cda56028ca..b7dd8b7dc13 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1972,7 +1972,7 @@ static void removeDoublesPeel(ListBase *depth_peels) for (peel = depth_peels->first; peel; peel = peel->next) { DepthPeel *next_peel = peel->next; - if (next_peel && ABS(peel->depth - next_peel->depth) < 0.0015f) { + if (next_peel && fabsf(peel->depth - next_peel->depth) < 0.0015f) { peel->next = next_peel->next; if (next_peel->next) { diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 7424acd752f..0e357dc53c1 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -173,8 +173,8 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha pup = uiPupMenuBegin(C, IFACE_("Unpack File"), ICON_NONE); layout = uiPupMenuLayout(pup); - strcpy(line, IFACE_("Remove Pack")); - props_ptr = uiItemFullO_ptr(layout, ot, line, ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); + props_ptr = uiItemFullO_ptr(layout, ot, IFACE_("Remove Pack"), ICON_NONE, + NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&props_ptr, "method", PF_REMOVE); RNA_string_set(&props_ptr, "id", id_name); diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index 62d4b01cab7..45edbde7482 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -28,7 +28,6 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc - ../../../../intern/opennl/extern ) set(INC_SYS @@ -51,4 +50,11 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() +if(WITH_OPENNL) + add_definitions(-DWITH_OPENNL) + list(APPEND INC_SYS + ../../../../intern/opennl/extern + ) +endif() + blender_add_lib(bf_editor_uvedit "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index d20ef0e70e0..9be3f395fbd 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -140,8 +140,8 @@ static void draw_uvs_shadow(Object *obedit) const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - /* draws the gray mesh when painting */ - glColor3ub(112, 112, 112); + /* draws the mesh when painting */ + UI_ThemeColor(TH_UV_SHADOW); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { glBegin(GL_LINE_LOOP); @@ -694,12 +694,12 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) } glLineWidth(1); - col2[0] = col2[1] = col2[2] = 192; col2[3] = 255; - glColor4ubv((unsigned char *)col2); - + UI_GetThemeColor4ubv(TH_WIRE_EDIT, col2); + glColor4ubv((unsigned char *)col2); + if (me->drawflag & ME_DRAWEDGES) { int sel, lastsel = -1; - UI_GetThemeColor4ubv(TH_VERTEX_SELECT, col1); + UI_GetThemeColor4ubv(TH_EDGE_SELECT, col1); if (interpedges) { glShadeModel(GL_SMOOTH); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 474348e84bc..afe26ed1c4e 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -640,7 +640,7 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], BMIter iter, liter; MTexPoly *tf; MLoopUV *luv; - bool change = false; + bool changed = 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); @@ -656,12 +656,12 @@ bool ED_uvedit_minmax(Scene *scene, Image *ima, Object *obedit, float r_min[2], if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); minmax_v2v2_v2(r_min, r_max, luv->uv); - change = true; + changed = true; } } } - return change; + return changed; } static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[2]) @@ -699,22 +699,22 @@ static bool ED_uvedit_median(Scene *scene, Image *ima, Object *obedit, float co[ static bool uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], char mode) { - bool change = false; + bool changed = false; if (mode == V3D_CENTER) { /* bounding box */ float min[2], max[2]; if (ED_uvedit_minmax(scene, ima, obedit, min, max)) { mid_v2_v2v2(cent, min, max); - change = true; + changed = true; } } else { if (ED_uvedit_median(scene, ima, obedit, cent)) { - change = true; + changed = true; } } - return change; + return changed; } /************************** find nearest ****************************/ @@ -2461,7 +2461,7 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) BMIter iter, liter; MTexPoly *tf; MLoopUV *luv; - bool change = false; + bool changed = false; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); @@ -2504,11 +2504,11 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) luv->flag &= ~MLOOPUV_VERTSEL; } - change = true; + changed = true; } } - if (change) { + if (changed) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); return OPERATOR_FINISHED; } @@ -2796,7 +2796,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) MLoopUV *luv; rcti rect; rctf rectf; - bool change, pinned, select, extend; + bool changed, pinned, select, extend; const bool use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? (ts->selectmode == SCE_SELECT_FACE) : (ts->uv_selectmode == UV_SELECT_FACE); @@ -2823,7 +2823,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) /* handle face selection mode */ float cent[2]; - change = false; + changed = false; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { /* assume not touched */ @@ -2834,19 +2834,19 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) uv_poly_center(efa, cent, cd_loop_uv_offset); if (BLI_rctf_isect_pt_v(&rectf, cent)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); - change = true; + changed = true; } } } /* (de)selects all tagged faces and deals with sticky modes */ - if (change) { + if (changed) { uv_select_flush_from_tag_face(sima, scene, obedit, select); } } else { /* other selection modes */ - change = true; + changed = true; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); @@ -2871,7 +2871,7 @@ static int uv_border_select_exec(bContext *C, wmOperator *op) } } - if (change) { + if (changed) { uv_select_sync_flush(ts, em, select); if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -2947,7 +2947,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) float zoomx, zoomy, offset[2], ellipse[2]; int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); const bool select = (gesture_mode == GESTURE_MODAL_SELECT); - bool change = false; + bool changed = false; const bool use_face_center = (ts->uv_flag & UV_SYNC_SELECTION) ? (ts->selectmode == SCE_SELECT_FACE) : (ts->uv_selectmode == UV_SELECT_FACE); @@ -2971,7 +2971,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) /* do selection */ if (use_face_center) { - change = FALSE; + changed = false; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); /* assume not touched */ @@ -2980,13 +2980,13 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) uv_poly_center(efa, cent, cd_loop_uv_offset); if (uv_inside_circle(cent, offset, ellipse)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); - change = TRUE; + changed = true; } } } /* (de)selects all tagged faces and deals with sticky modes */ - if (change) { + if (changed) { uv_select_flush_from_tag_face(sima, scene, obedit, select); } } @@ -2994,12 +2994,12 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - change |= uv_select_inside_ellipse(em, scene, select, offset, ellipse, l, luv, cd_loop_uv_offset); + changed |= uv_select_inside_ellipse(em, scene, select, offset, ellipse, l, luv, cd_loop_uv_offset); } } } - if (change) { + if (changed) { uv_select_sync_flush(ts, em, select); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); @@ -3057,7 +3057,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo BMLoop *l; MTexPoly *tf; int screen_uv[2]; - bool change = false; + bool changed = false; rcti rect; BLI_lasso_boundbox(&rect, mcords, moves); @@ -3074,13 +3074,13 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); - change = true; + changed = true; } } } /* (de)selects all tagged faces and deals with sticky modes */ - if (change) { + if (changed) { uv_select_flush_from_tag_face(sima, scene, obedit, select); } } @@ -3096,7 +3096,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED)) { uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset); - change = true; + changed = true; } } } @@ -3104,7 +3104,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo } } - if (change) { + if (changed) { uv_select_sync_flush(scene->toolsettings, em, select); if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -3112,7 +3112,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo } } - return change; + return changed; } static int uv_lasso_select_exec(bContext *C, wmOperator *op) @@ -3122,14 +3122,14 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op) if (mcords) { bool select; - bool change; + bool changed; select = !RNA_boolean_get(op->ptr, "deselect"); - change = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select); + changed = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select); MEM_freeN((void *)mcords); - return change ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } return OPERATOR_PASS_THROUGH; @@ -3184,19 +3184,19 @@ static int uv_snap_cursor_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); - bool change = false; + bool changed = false; switch (RNA_enum_get(op->ptr, "target")) { case 0: uv_snap_cursor_to_pixels(sima); - change = true; + changed = true; break; case 1: - change = uv_snap_cursor_to_selection(scene, ima, obedit, sima); + changed = uv_snap_cursor_to_selection(scene, ima, obedit, sima); break; } - if (!change) + if (!changed) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, sima); @@ -3235,7 +3235,7 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons BMIter iter, liter; MTexPoly *tface; MLoopUV *luv; - bool change = false; + bool changed = 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); @@ -3249,12 +3249,12 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, cons 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, cursor); - change = true; + changed = true; } } } - return change; + return changed; } static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const float offset[2]) @@ -3265,7 +3265,7 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f BMIter iter, liter; MTexPoly *tface; MLoopUV *luv; - bool change = false; + bool changed = 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); @@ -3279,15 +3279,15 @@ static bool uv_snap_uvs_offset(Scene *scene, Image *ima, Object *obedit, const f 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; + changed = true; } } } - return change; + return changed; } -static int uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit) +static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object *obedit) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -3296,7 +3296,7 @@ static int uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object * BMIter iter, liter, lsubiter; MTexPoly *tface; MLoopUV *luv; - bool change = false; + bool changed = false; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); @@ -3335,14 +3335,14 @@ static int uv_snap_uvs_to_adjacent_unselected(Scene *scene, Image *ima, Object * if (uv_tot) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); mul_v2_v2fl(luv->uv, uv, 1.0f / (float)uv_tot); - change = true; + changed = true; } } } } } - return change; + return changed; } static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit) @@ -3356,7 +3356,7 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit MLoopUV *luv; int width = 0, height = 0; float w, h; - bool change = false; + bool changed = 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); @@ -3377,10 +3377,10 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit } } - change = true; + changed = true; } - return change; + return changed; } static int uv_snap_selection_exec(bContext *C, wmOperator *op) @@ -3389,14 +3389,14 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); Image *ima = CTX_data_edit_image(C); - bool change = false; + bool changed = false; switch (RNA_enum_get(op->ptr, "target")) { case 0: - change = uv_snap_uvs_to_pixels(sima, scene, obedit); + changed = uv_snap_uvs_to_pixels(sima, scene, obedit); break; case 1: - change = uv_snap_uvs_to_cursor(scene, ima, obedit, sima->cursor); + changed = uv_snap_uvs_to_cursor(scene, ima, obedit, sima->cursor); break; case 2: { @@ -3404,16 +3404,16 @@ static int uv_snap_selection_exec(bContext *C, wmOperator *op) 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); + changed = uv_snap_uvs_offset(scene, ima, obedit, offset); } break; } case 3: - change = uv_snap_uvs_to_adjacent_unselected(scene, ima, obedit); + changed = uv_snap_uvs_to_adjacent_unselected(scene, ima, obedit); break; } - if (!change) + if (!changed) return OPERATOR_CANCELLED; uvedit_live_unwrap_update(sima, scene, obedit); diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 2d33a2d3937..e5c3510db4b 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -35,8 +35,6 @@ #include "BLI_boxpack2d.h" #include "BLI_convexhull2d.h" -#include "ONL_opennl.h" - #include "uvedit_intern.h" #include "uvedit_parametrizer.h" @@ -47,6 +45,10 @@ #include "BLI_sys_types.h" /* for intptr_t support */ +#ifdef WITH_OPENNL + +#include "ONL_opennl.h" + /* Utils */ #if 0 @@ -4715,3 +4717,36 @@ void param_flush_restore(ParamHandle *handle) } } +#else /* WITH_OPENNL */ + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +/* stubs */ +void param_face_add(ParamHandle *handle, ParamKey key, int nverts, + ParamKey *vkeys, float **co, float **uv, + ParamBool *pin, ParamBool *select, float normal[3]) {} +void param_edge_set_seam(ParamHandle *handle, + ParamKey *vkeys) {} +void param_aspect_ratio(ParamHandle *handle, float aspx, float aspy) {} +ParamHandle *param_construct_begin(void) { return NULL; } +void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl) {} +void param_delete(ParamHandle *handle) {} + +void param_stretch_begin(ParamHandle *handle) {} +void param_stretch_blend(ParamHandle *handle, float blend) {} +void param_stretch_iter(ParamHandle *handle) {} +void param_stretch_end(ParamHandle *handle) {} + +void param_pack(ParamHandle *handle, float margin, bool do_rotate) {} +void param_average(ParamHandle *handle) {} + +void param_flush(ParamHandle *handle) {} +void param_flush_restore(ParamHandle *handle) {} + +void param_lscm_begin(ParamHandle *handle, ParamBool live, ParamBool abf) {} +void param_lscm_solve(ParamHandle *handle) {} +void param_lscm_end(ParamHandle *handle) {} + +#endif /* WITH_OPENNL */ diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index d6bd6f466b9..ebfef08c284 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1254,18 +1254,6 @@ void UV_OT_unwrap(wmOperatorType *ot) RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } -/* NOTE: could be generic function */ -static Camera *view3d_camera_get(View3D *v3d, RegionView3D *rv3d) -{ - /* establish the camera object, so we can default to view mapping if anything is wrong with it */ - if ((rv3d->persp == RV3D_CAMOB) && (v3d->camera) && (v3d->camera->type == OB_CAMERA)) { - return v3d->camera->data; - } - else { - return NULL; - } -} - /**************** Project From View operator **************/ static int uv_from_view_exec(bContext *C, wmOperator *op); @@ -1273,7 +1261,7 @@ static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - Camera *camera = view3d_camera_get(v3d, rv3d); + Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); PropertyRNA *prop; prop = RNA_struct_find_property(op->ptr, "camera_bounds"); @@ -1292,7 +1280,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - Camera *camera = view3d_camera_get(v3d, rv3d); + Camera *camera = ED_view3d_camera_data_get(v3d, rv3d); BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -1326,9 +1314,6 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) struct ProjCameraInfo *uci = BLI_uvproject_camera_info(v3d->camera, obedit->obmat, camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f, camera_bounds ? (scene->r.ysch * scene->r.yasp) : 1.0f); - - - // BLI_uvproject_camera_info_scale if (uci) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { |