diff options
Diffstat (limited to 'source/blender/editors')
126 files changed, 9316 insertions, 2538 deletions
diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 088376b20ef..67ed77bcc4b 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -24,6 +24,7 @@ if(WITH_BLENDER) add_subdirectory(curve) add_subdirectory(gpencil) add_subdirectory(interface) + add_subdirectory(mask) add_subdirectory(mesh) add_subdirectory(metaball) add_subdirectory(object) diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index ed66a76a324..d08b496f0ef 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -8,6 +8,7 @@ SConscript(['datafiles/SConscript', 'interface/SConscript', 'animation/SConscript', 'armature/SConscript', + 'mask/SConscript', 'mesh/SConscript', 'metaball/SConscript', 'object/SConscript', diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index a735f159e1b..9be0ab37510 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -55,6 +55,7 @@ #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_speaker_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" @@ -396,11 +397,8 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle /* get backdrop color for summary widget */ static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3]) { - // FIXME: hardcoded color - same as the 'action' line in NLA - // reddish color - r_color[0] = 0.8f; - r_color[1] = 0.2f; - r_color[2] = 0.0f; + /* reddish color - same as the 'action' line in NLA */ + UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color); } /* backdrop for summary widget */ @@ -2597,6 +2595,172 @@ static bAnimChannelType ACF_GPL = acf_gpl_setting_ptr /* pointer for setting */ }; + +/* Mask Datablock ------------------------------------------- */ + +/* get backdrop color for mask datablock widget */ +static void acf_mask_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3]) +{ + /* these are ID-blocks, but not exactly standalone... */ + UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color); +} + +// TODO: just get this from RNA? +static int acf_mask_icon(bAnimListElem *UNUSED(ale)) +{ + return ICON_GREASEPENCIL; // MASK_TODO - need real icon +} + +/* check if some setting exists for this channel */ +static short 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; + + default: + return 0; + } +} + +/* 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) +{ + /* clear extra return data first */ + *neg = 0; + + switch (setting) { + case ACHANNEL_SETTING_SELECT: /* selected */ + return AGRP_SELECTED; + + case ACHANNEL_SETTING_EXPAND: /* expanded */ + return MASK_ANIMF_EXPAND; + } + + /* this shouldn't happen */ + return 0; +} + +/* get pointer to the setting */ +static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) +{ + Mask *mask = (Mask *)ale->data; + + /* all flags are just in mask->flag for now... */ + return GET_ACF_FLAG_PTR(mask->flag, type); +} + +/* mask datablock type define */ +static bAnimChannelType ACF_MASKDATA = +{ + "Mask Datablock", /* type name */ + + acf_mask_color, /* backdrop color */ + acf_group_backdrop, /* backdrop */ + acf_generic_indention_0, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_generic_idblock_name, /* name */ + acf_generic_idfill_nameprop, /* name prop */ + acf_mask_icon, /* icon */ + + acf_mask_setting_valid, /* has setting */ + acf_mask_setting_flag, /* flag for setting */ + acf_mask_setting_ptr /* pointer for setting */ +}; + +/* Mask Layer ------------------------------------------- */ + +/* name for grease pencil layer entries */ +static void acf_masklay_name(bAnimListElem *ale, char *name) +{ + MaskLayer *masklay = (MaskLayer *)ale->data; + + if (masklay && name) + BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE); +} + +/* name property for grease pencil layer entries */ +static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop) +{ + if (ale->data) { + RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr); + *prop = RNA_struct_name_property(ptr->type); + + return (*prop != NULL); + } + + return 0; +} + +/* check if some setting exists for this channel */ +static short 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 */ + return 0; + + /* always available */ + default: + return 1; + } +} + +/* 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) +{ + /* clear extra return data first */ + *neg = 0; + + 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 edtiability + return MASK_LAYERFLAG_LOCKED; + + default: /* unsupported */ + return 0; + } +} + +/* get pointer to the setting */ +static void *acf_masklay_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) +{ + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* all flags are just in agrp->flag for now... */ + return GET_ACF_FLAG_PTR(masklay->flag, type); +} + +/* grease pencil layer type define */ +static bAnimChannelType ACF_MASKLAYER = +{ + "Mask Layer", /* type name */ + + acf_generic_channel_color, /* backdrop color */ + acf_generic_channel_backdrop, /* backdrop */ + acf_generic_indention_flexible, /* indent level */ + acf_generic_group_offset, /* offset */ + + acf_masklay_name, /* name */ + acf_masklay_name_prop, /* name prop */ + NULL, /* icon */ + + acf_masklay_setting_valid, /* has setting */ + acf_masklay_setting_flag, /* flag for setting */ + acf_masklay_setting_ptr /* pointer for setting */ +}; + + /* *********************************************** */ /* Type Registration and General Access */ @@ -2648,6 +2812,9 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */ animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */ + animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */ + animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */ + // TODO: these types still need to be implemented!!! // probably need a few extra flags for these special cases... animchannelTypeInfo[type++] = NULL; /* NLA Track */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index bbf89dfa74d..c2beeb17fe0 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -43,6 +43,7 @@ #include "DNA_scene_types.h" #include "DNA_key_types.h" #include "DNA_gpencil_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -51,6 +52,7 @@ #include "BKE_fcurve.h" #include "BKE_gpencil.h" #include "BKE_context.h" +#include "BKE_mask.h" #include "BKE_global.h" #include "UI_view2d.h" @@ -261,6 +263,10 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s if (ale->flag & GP_LAYER_SELECT) sel = ACHANNEL_SETFLAG_CLEAR; break; + case ANIMTYPE_MASKLAYER: + if (ale->flag & MASK_LAYERFLAG_SELECT) + sel = ACHANNEL_SETFLAG_CLEAR; + break; } } } @@ -358,6 +364,14 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, short datatype, s ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT); } break; + + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)ale->data; + + ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT); + } + break; } } @@ -1059,6 +1073,10 @@ static int animchannels_rearrange_exec(bContext *C, wmOperator *op) /* Grease Pencil channels */ printf("Grease Pencil not supported for moving yet\n"); } + else if (ac.datatype == ANIMCONT_MASK) { + /* Grease Pencil channels */ + printf("Mask does not supported for moving yet\n"); + } else if (ac.datatype == ANIMCONT_ACTION) { /* Directly rearrange action's channels */ rearrange_action_channels(&ac, ac.data, mode); @@ -1209,6 +1227,17 @@ static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op)) BLI_freelinkN(&gpd->layers, gpl); } break; + + case ANIMTYPE_MASKLAYER: + { + /* Grease Pencil layer */ + Mask *mask = (Mask *)ale->id; + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* try to delete the layer's data and the layer itself */ + BKE_mask_layer_remove(mask, masklay); + } + break; } } @@ -2292,6 +2321,36 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in notifierFlags |= (ND_ANIMCHAN | NA_EDITED); } break; + case ANIMTYPE_MASKDATABLOCK: + { + Mask *mask = (Mask *)ale->data; + + /* toggle expand + * - although the triangle widget already allows this, the whole channel can also be used for this purpose + */ + mask->flag ^= MASK_ANIMF_EXPAND; + + notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + } + break; + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)ale->data; + + /* select/deselect */ + if (selectmode == SELECT_INVERT) { + /* invert selection status of this layer only */ + masklay->flag ^= MASK_LAYERFLAG_SELECT; + } + else { + /* select layer by itself */ + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + masklay->flag |= MASK_LAYERFLAG_SELECT; + } + + notifierFlags |= (ND_ANIMCHAN | NA_EDITED); + } + break; default: if (G.debug & G_DEBUG) printf("Error: Invalid channel type in mouse_anim_channels()\n"); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index cebc0e8810e..103b23be466 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -57,6 +57,7 @@ #include "DNA_lattice_types.h" #include "DNA_linestyle_types.h" #include "DNA_key_types.h" +#include "DNA_mask_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" @@ -87,6 +88,7 @@ #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" +#include "BKE_mask.h" #include "BKE_sequencer.h" #include "BKE_utildefines.h" @@ -174,6 +176,22 @@ static short actedit_get_context(bAnimContext *ac, SpaceAction *saction) ac->mode = saction->mode; return 1; + case SACTCONT_MASK: /* Grease Pencil */ // XXX review how this mode is handled... + /* update scene-pointer (no need to check for pinning yet, as not implemented) */ +{ + // TODO, other methods to get the mask + // Sequence *seq = BKE_sequencer_active_get(ac->scene); + //MovieClip *clip = ac->scene->clip; +// struct Mask *mask = seq ? seq->mask : NULL; + + saction->ads.source = (ID *)ac->scene;; + + ac->datatype = ANIMCONT_MASK; + ac->data = &saction->ads; + + ac->mode = saction->mode; + return 1; +} case SACTCONT_DOPESHEET: /* DopeSheet */ /* update scene-pointer (no need to check for pinning yet, as not implemented) */ saction->ads.source = (ID *)ac->scene; @@ -821,7 +839,18 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne ale->datatype = ALE_GPFRAME; } break; - + + case ANIMTYPE_MASKLAYER: + { + MaskLayer *masklay = (MaskLayer *)data; + + ale->flag = masklay->flag; + + ale->key_data = NULL; + ale->datatype = ALE_MASKLAY; + } + break; + case ANIMTYPE_NLATRACK: { NlaTrack *nlt = (NlaTrack *)data; @@ -1367,6 +1396,83 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i return items; } +static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode) +{ + MaskLayer *masklay_act = BKE_mask_layer_active(mask); + MaskLayer *masklay; + size_t items = 0; + + /* loop over layers as the conditions are acceptable */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + /* only if selected */ + if (ANIMCHANNEL_SELOK(SEL_MASKLAY(masklay)) ) { + /* only if editable */ +// if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) { + /* active... */ + if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) { + /* add to list */ + ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask); + + +// if (filter_mode & ANIMFILTER_TMP_PEEK) +// return 1; +// else { +// bAnimListElem *ale = make_new_animlistelem(masklay, channel_type, (ID *)owner_id); +// if (ale) { +// BLI_addtail(anim_data, ale); +// items ++; +// } +// } + + } +// } + } + } + + return items; +} + +static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode) +{ + Mask *mask; + size_t items = 0; + + /* for now, grab grease pencil datablocks directly from main */ + // XXX: this is not good... + for (mask = G.main->mask.first; mask; mask = mask->id.next) { + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + + /* only show if gpd is used by something... */ + if (ID_REAL_USERS(mask) < 1) + continue; + + /* add gpencil animation channels */ + BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask)) + { + tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include data-expand widget first */ + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* add gpd as channel too (if for drawing, and it has layers) */ + ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL); + } + + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); + items += tmp_items; + } + } + + /* return the number of items added to the list */ + return items; +} + /* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */ // TODO: how to handle group nodes is still unclear... static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode) @@ -2347,7 +2453,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact); } break; - + case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */ { /* the check for the DopeSheet summary is included here since the summary works here too */ @@ -2361,7 +2467,13 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items = animdata_filter_gpencil(anim_data, data, filter_mode); } break; - + + case ANIMCONT_MASK: + { + items = animdata_filter_mask(anim_data, data, filter_mode); + } + break; + case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ { /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index cb7dc7ac206..e6fc4d5a168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -60,6 +60,7 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_mask_types.h" #include "BKE_key.h" #include "BKE_material.h" @@ -184,6 +185,50 @@ static void nupdate_ak_gpframe(void *node, void *data) ak->modified += 1; } +/* ......... */ + +/* Comparator callback used for ActKeyColumns and GPencil frame */ +static short compare_ak_masklayshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + if (masklay_shape->frame < ak->cfra) + return -1; + else if (masklay_shape->frame > ak->cfra) + return 1; + else + return 0; +} + +/* New node callback used for building ActKeyColumns from GPencil frames */ +static DLRBT_Node *nalloc_ak_masklayshape(void *data) +{ + ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF"); + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + /* store settings based on state of BezTriple */ + ak->cfra = masklay_shape->frame; + ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0; + + /* set 'modified', since this is used to identify long keyframes */ + ak->modified = 1; + + return (DLRBT_Node *)ak; +} + +/* Node updater callback used for building ActKeyColumns from GPencil frames */ +static void nupdate_ak_masklayshape(void *node, void *data) +{ + ActKeyColumn *ak = (ActKeyColumn *)node; + MaskLayerShape *masklay_shape = (MaskLayerShape *)data; + + /* set selection status and 'touched' status */ + if (masklay_shape->flag & MASK_SHAPE_SELECT) ak->sel = SELECT; + ak->modified += 1; +} + + /* --------------- */ /* Add the given BezTriple to the given 'list' of Keyframes */ @@ -204,6 +249,15 @@ static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf) BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf); } +/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */ +static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape) +{ + if (ELEM(NULL, keys, masklay_shape)) + return; + else + BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape); +} + /* ActBeztColumns (Helpers for Long Keyframes) ------------------------------ */ /* maximum size of default buffer for BezTriple columns */ @@ -764,6 +818,21 @@ void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) BLI_dlrbTree_free(&keys); } +void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos) +{ + DLRBT_Tree keys; + + BLI_dlrbTree_init(&keys); + + mask_to_keylist(ads, masklay, &keys); + + BLI_dlrbTree_linkedlist_sync(&keys); + + draw_keylist(v2d, &keys, NULL, ypos, (masklay->flag & MASK_LAYERFLAG_LOCKED)); + + BLI_dlrbTree_free(&keys); +} + /* *************************** Keyframe List Conversions *************************** */ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, DLRBT_Tree *blocks) @@ -940,3 +1009,17 @@ void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys) } } +void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys) +{ + MaskLayerShape *masklay_shape; + + if (masklay && keys) { + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + add_masklay_to_keycolumns_list(keys, masklay_shape); + } + } +} + diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index ac37b6c4141..14bee00a72a 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -374,16 +374,16 @@ void smooth_fcurve(FCurve *fcu) /* ---------------- */ /* little cache for values... */ -typedef struct tempFrameValCache { +typedef struct TempFrameValCache { float frame, val; -} tempFrameValCache; +} TempFrameValCache; /* Evaluates the curves between each selected keyframe on each frame, and keys the value */ void sample_fcurve(FCurve *fcu) { BezTriple *bezt, *start = NULL, *end = NULL; - tempFrameValCache *value_cache, *fp; + TempFrameValCache *value_cache, *fp; int sfra, range; int i, n, nIndex; @@ -406,7 +406,7 @@ void sample_fcurve(FCurve *fcu) sfra = (int)(floor(start->vec[1][0]) ); if (range) { - value_cache = MEM_callocN(sizeof(tempFrameValCache) * range, "IcuFrameValCache"); + value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache"); /* sample values */ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) { diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index fdebddbf41d..ea3c8685525 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -756,7 +756,7 @@ static int pose_visual_transform_apply_exec(bContext *C, wmOperator *UNUSED(op)) * * TODO, loop over children before parents if multiple bones * at once are to be predictable*/ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) { float delta_mat[4][4]; @@ -923,7 +923,7 @@ int join_armature_exec(bContext *C, wmOperator *UNUSED(op)) pose = ob->pose; ob->mode &= ~OB_MODE_POSE; - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) { if ((base->object->type == OB_ARMATURE) && (base->object != ob)) { bArmature *curarm = base->object->data; @@ -1195,7 +1195,7 @@ static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op)) /* 1) only edit-base selected */ // TODO: use context iterators for this? - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (base->object == obedit) base->flag |= 1; else base->flag &= ~1; @@ -2297,7 +2297,7 @@ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) ED_armature_deselect_all(obedit, 0); - /* Create a bone */ + /* Create a bone */ bone = ED_armature_edit_bone_add(arm, "Bone"); arm->act_edbone = bone; @@ -2308,7 +2308,6 @@ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1 else add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z - } @@ -2849,7 +2848,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* loop over all bones, and only consider if visible */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { if (!(ebone->flag & BONE_CONNECTED) && (ebone->flag & BONE_ROOTSEL)) fill_add_joint(ebone, 0, &points); @@ -3563,7 +3562,7 @@ static int armature_subdivide_exec(bContext *C, wmOperator *op) /* loop over all editable bones */ // XXX the old code did this in reverse order though! - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { for (i = numcuts + 1; i > 1; i--) { /* compute cut ratio first */ @@ -3852,7 +3851,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) */ /* parent selected bones to the active one */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ELEM(ebone, actbone, actmirb) == 0) { if (ebone->flag & BONE_SELECTED) @@ -3878,7 +3877,7 @@ static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEve uiLayout *layout = uiPupMenuLayout(pup); int allchildbones = 0; - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ebone != actbone) { if (ebone->parent != actbone) allchildbones = 1; @@ -3938,7 +3937,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op) bArmature *arm = (bArmature *)ob->data; int val = RNA_enum_get(op->ptr, "type"); - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { editbone_clear_parent(ebone, val); } @@ -3975,7 +3974,7 @@ void ARMATURE_OT_parent_clear(wmOperatorType *ot) static int armature_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) { /* Set the flags */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ if ((ebone->flag & BONE_UNSELECTABLE) == 0) { @@ -4018,7 +4017,7 @@ static int armature_de_select_all_exec(bContext *C, wmOperator *op) } /* Set the flags */ - CTX_DATA_BEGIN (C, EditBone *, ebone, visible_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, visible_bones) { /* ignore bone if selection can't change */ if ((ebone->flag & BONE_UNSELECTABLE) == 0) { @@ -4438,7 +4437,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) */ /* align selected bones to the active one */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { if (ELEM(ebone, actbone, actmirb) == 0) { if (ebone->flag & BONE_SELECTED) @@ -4524,13 +4523,12 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor * note, special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode - campbell */ - if ((!extend && !deselect && !toggle)|| ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) { + if ((!extend && !deselect && !toggle) || + ((ob_act && (ob_act != ob) && (ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0))) + { ED_pose_deselectall(ob, 0); nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 1); } else { if (extend) { @@ -4548,17 +4546,11 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor } else { nearBone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 0); } } else { nearBone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); arm->act_bone = nearBone; - - // XXX old cruft! use notifiers instead - //select_actionchannel_by_name(ob->action, nearBone->name, 1); } } } @@ -5144,7 +5136,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, } /* only clear relevant transforms for selected bones */ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, selected_pose_bones) { /* run provided clearing function */ clear_func(pchan); @@ -5288,7 +5280,7 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) } /* Set the flags */ - CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) + CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pose_bones) { /* select pchan only if selectable, but deselect works always */ switch (action) { @@ -5684,7 +5676,7 @@ static int armature_flip_names_exec(bContext *C, wmOperator *UNUSED(op)) arm = ob->data; /* loop through selected bones, auto-naming them */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { flip_side_name(newname, ebone->name, TRUE); // 1 = do strip off number extensions ED_armature_bone_rename(arm, ebone->name, newname); @@ -5729,7 +5721,7 @@ static int armature_autoside_names_exec(bContext *C, wmOperator *op) arm = ob->data; /* loop through selected bones, auto-naming them */ - CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) + CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) { BLI_strncpy(newname, ebone->name, sizeof(newname)); if (bone_autoside_name(newname, 1, axis, ebone->head[axis], ebone->tail[axis])) @@ -5752,7 +5744,8 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot) {0, "XAXIS", 0, "X-Axis", "Left/Right"}, {1, "YAXIS", 0, "Y-Axis", "Front/Back"}, {2, "ZAXIS", 0, "Z-Axis", "Top/Bottom"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "AutoName by Axis"; diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index d90bd96a6f1..91c342ec070 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -81,20 +81,17 @@ typedef struct RetargetParam { bContext *context; } RetargetParam; -typedef enum -{ +typedef enum { RETARGET_LENGTH, RETARGET_AGGRESSIVE } RetargetMode; -typedef enum -{ +typedef enum { METHOD_BRUTE_FORCE = 0, METHOD_MEMOIZE = 1 } RetargetMethod; -typedef enum -{ +typedef enum { ARC_FREE = 0, ARC_TAKEN = 1, ARC_USED = 2 diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index d642ee57c57..27c40095348 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -141,14 +141,14 @@ void ED_operatormacros_curve(void) wmOperatorTypeMacro *otmacro; ot = WM_operatortype_append_macro("CURVE_OT_duplicate_move", "Add Duplicate", "Duplicate curve and move", - OPTYPE_UNDO|OPTYPE_REGISTER); + OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "CURVE_OT_duplicate"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", FALSE); ot = WM_operatortype_append_macro("CURVE_OT_extrude_move", "Extrude Curve and Move", - "Extrude curve and move result", OPTYPE_UNDO|OPTYPE_REGISTER); + "Extrude curve and move result", OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "CURVE_OT_extrude"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); @@ -189,8 +189,8 @@ void ED_keymap_curve(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", ENDKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", LINE_END); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_CHAR); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_CHAR); - RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", PREV_WORD); - RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0)->ptr, "type", NEXT_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", LEFTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", PREV_WORD); + RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", RIGHTARROWKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0)->ptr, "type", NEXT_WORD); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", UPARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_LINE); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", DOWNARROWKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", NEXT_LINE); RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move_select", PAGEUPKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", PREV_PAGE); @@ -224,9 +224,9 @@ void ED_keymap_curve(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CURVE_OT_vertex_add", LEFTMOUSE, KM_CLICK, KM_CTRL, 0); kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", AKEY, KM_PRESS, 0, 0); - RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); kmi = WM_keymap_add_item(keymap, "CURVE_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); WM_keymap_add_item(keymap, "CURVE_OT_select_row", RKEY, KM_PRESS, KM_SHIFT, 0); WM_keymap_add_item(keymap, "CURVE_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index b94d3653f60..2fa7b4b2126 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3530,7 +3530,8 @@ void CURVE_OT_spline_type_set(wmOperatorType *ot) // {CU_CARDINAL, "CARDINAL", 0, "Cardinal", ""}, // {CU_BSPLINE, "B_SPLINE", 0, "B-Spline", ""}, {CU_NURBS, "NURBS", 0, "NURBS", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Set Spline Type"; @@ -3573,7 +3574,8 @@ void CURVE_OT_handle_type_set(wmOperatorType *ot) {5, "ALIGNED", 0, "Aligned", ""}, {6, "FREE_ALIGN", 0, "Free", ""}, {3, "TOGGLE_FREE_ALIGN", 0, "Toggle Free/Align", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Set Handle Type"; @@ -4886,7 +4888,8 @@ void CURVE_OT_cyclic_toggle(wmOperatorType *ot) static EnumPropertyItem direction_items[] = { {0, "CYCLIC_U", 0, "Cyclic U", ""}, {1, "CYCLIC_V", 0, "Cyclic V", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Toggle Cyclic"; @@ -6007,7 +6010,8 @@ void CURVE_OT_delete(wmOperatorType *ot) {0, "SELECTED", 0, "Select", ""}, {1, "SEGMENT", 0, "Segment", ""}, {2, "ALL", 0, "All", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Delete"; @@ -6101,7 +6105,7 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op)) /* trasnform all selected curves inverse in obact */ invert_m4_m4(imat, ob->obmat); - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) + CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases) { if (base->object->type == ob->type) { if (base->object != ob) { diff --git a/source/blender/editors/curve/lorem.c b/source/blender/editors/curve/lorem.c index 66b358e04e5..7823be3df6d 100644 --- a/source/blender/editors/curve/lorem.c +++ b/source/blender/editors/curve/lorem.c @@ -25,7 +25,7 @@ #include "curve_intern.h" -const char ED_lorem[]= { +const char ED_lorem[] = { 76, 111, 114, 101, 109, 32, 105, 112, 115, 117, 109, 32, 100, 111, 108, 111, 114, 32, 115, 105, 116, 32, 97, 109, 101, 116, 44, 32, 99, 111, 110, 115, 101, 99, 116, 101, 116, 117, 101, 114, 32, 97, 100, 105, 112, 105, 115, 99, 105, 110, 103, 32, 101, 108, 105, 116, 46, 32, 65, 108, 105, 113, 117, 97, 109, 32, 116, 114, 105, 115, 116, 105, 113, 117, 101, 32, 105, 110, 116, 101, 114, 100, 117, 109, 32, 115, 101, 109, 46, 32, 78, 117, 108, diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 8d771f0dc58..1823bbce3a1 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -669,7 +669,7 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, // ............................ /* draw grease-pencil sketches to specified 2d-view that uses ibuf corrections */ -void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) +void draw_gpencil_2dimage(bContext *C /* , ImBuf *ibuf */) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); @@ -678,8 +678,6 @@ void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) int offsx, offsy, sizex, sizey; int dflag = GP_DRAWDATA_NOSTATUS; - /* check that we have grease-pencil stuff to draw */ - if (ELEM(NULL, sa, ibuf)) return; gpd = gpencil_data_get_active(C); // XXX if (gpd == NULL) return; @@ -706,7 +704,10 @@ void draw_gpencil_2dimage(bContext *C, ImBuf *ibuf) { SpaceSeq *sseq = (SpaceSeq *)sa->spacedata.first; float zoom, zoomx, zoomy; - + + /* check that we have grease-pencil stuff to draw */ + if (ELEM(NULL, sa, ibuf)) return; + /* calculate accessory values */ zoom = (float)(SEQ_ZOOM_FAC(sseq->zoom)); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 9cc738b016e..a7beaa74eb7 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -62,7 +62,7 @@ /* Generics - Loopers */ /* Loops over the gp-frames for a gp-layer, and applies the given callback */ -short gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *)) +short ED_gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDframe *, Scene *)) { bGPDframe *gpf; @@ -85,7 +85,7 @@ short gplayer_frames_looper(bGPDlayer *gpl, Scene *scene, short (*gpf_cb)(bGPDfr /* Data Conversion Tools */ /* make a listing all the gp-frames in a layer as cfraelems */ -void gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) +void ED_gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) { bGPDframe *gpf; CfraElem *ce; @@ -111,7 +111,7 @@ void gplayer_make_cfra_list(bGPDlayer *gpl, ListBase *elems, short onlysel) /* Selection Tools */ /* check if one of the frames in this layer is selected */ -short is_gplayer_frame_selected(bGPDlayer *gpl) +short ED_gplayer_frame_select_check(bGPDlayer *gpl) { bGPDframe *gpf; @@ -149,7 +149,7 @@ static void gpframe_select(bGPDframe *gpf, short select_mode) } /* set all/none/invert select (like above, but with SELECT_* modes) */ -void select_gpencil_frames(bGPDlayer *gpl, short select_mode) +void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode) { bGPDframe *gpf; @@ -164,36 +164,33 @@ void select_gpencil_frames(bGPDlayer *gpl, short select_mode) } /* set all/none/invert select */ -void set_gplayer_frame_selection(bGPDlayer *gpl, short mode) +void ED_gplayer_frame_select_set(bGPDlayer *gpl, short mode) { /* error checking */ if (gpl == NULL) return; /* now call the standard function */ - select_gpencil_frames(gpl, mode); + ED_gpencil_select_frames(gpl, mode); } /* select the frame in this layer that occurs on this frame (there should only be one at most) */ -void select_gpencil_frame(bGPDlayer *gpl, int selx, short select_mode) +void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode) { bGPDframe *gpf; if (gpl == NULL) return; - - /* search through frames for a match */ - for (gpf = gpl->frames.first; gpf; gpf = gpf->next) { - /* there should only be one frame with this frame-number */ - if (gpf->framenum == selx) { - gpframe_select(gpf, select_mode); - break; - } + + gpf = BKE_gpencil_layer_find_frame(gpl, selx); + + if (gpf) { + gpframe_select(gpf, select_mode); } } /* select the frames in this layer that occur within the bounds specified */ -void borderselect_gplayer_frames(bGPDlayer *gpl, float min, float max, short select_mode) +void ED_gplayer_frames_select_border(bGPDlayer *gpl, float min, float max, short select_mode) { bGPDframe *gpf; @@ -211,7 +208,7 @@ void borderselect_gplayer_frames(bGPDlayer *gpl, float min, float max, short sel /* Frame Editing Tools */ /* Delete selected frames */ -void delete_gplayer_frames(bGPDlayer *gpl) +void ED_gplayer_frames_delete(bGPDlayer *gpl) { bGPDframe *gpf, *gpfn; @@ -229,7 +226,7 @@ void delete_gplayer_frames(bGPDlayer *gpl) } /* Duplicate selected frames from given gp-layer */ -void duplicate_gplayer_frames(bGPDlayer *gpl) +void ED_gplayer_frames_duplicate(bGPDlayer *gpl) { bGPDframe *gpf, *gpfn; @@ -502,19 +499,19 @@ void snap_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode) { switch (mode) { case 1: /* snap to nearest frame */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearest); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; case 2: /* snap to current frame */ - gplayer_frames_looper(gpl, scene, snap_gpf_cframe); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_cframe); break; case 3: /* snap to nearest marker */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearmarker); break; case 4: /* snap to nearest second */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearestsec); break; default: /* just in case */ - gplayer_frames_looper(gpl, scene, snap_gpf_nearest); + ED_gplayer_frames_looper(gpl, scene, snap_gpf_nearest); break; } } @@ -604,21 +601,21 @@ void mirror_gplayer_frames(bGPDlayer *gpl, Scene *scene, short mode) { switch (mode) { case 1: /* mirror over current frame */ - gplayer_frames_looper(gpl, scene, mirror_gpf_cframe); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_cframe); break; case 2: /* mirror over frame 0 */ - gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); break; case 3: /* mirror over value 0 */ - gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_xaxis); break; case 4: /* mirror over marker */ mirror_gpf_marker(NULL, NULL); - gplayer_frames_looper(gpl, scene, mirror_gpf_marker); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_marker); mirror_gpf_marker(NULL, NULL); break; default: /* just in case */ - gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); + ED_gplayer_frames_looper(gpl, scene, mirror_gpf_yaxis); break; } } diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c index 3a7e806c2ed..b59f3756819 100644 --- a/source/blender/editors/gpencil/gpencil_buttons.c +++ b/source/blender/editors/gpencil/gpencil_buttons.c @@ -40,6 +40,7 @@ #include "DNA_gpencil_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "BKE_context.h" #include "BKE_global.h" @@ -236,6 +237,7 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin PointerRNA gpd_ptr; bGPDlayer *gpl; uiLayout *col, *row; + SpaceClip *sc= CTX_wm_space_clip(C); short v3d_stroke_opts = STROKE_OPTS_NORMAL; const short is_v3d = CTX_wm_view3d(C) != NULL; @@ -244,6 +246,16 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin /* draw gpd settings first ------------------------------------- */ col = uiLayoutColumn(layout, 0); + + if (sc) { + bScreen *screen = CTX_wm_screen(C); + PointerRNA sc_ptr; + + RNA_pointer_create(&screen->id, &RNA_SpaceClipEditor, sc, &sc_ptr); + row = uiLayoutRow(col, 1); + uiItemR(row, &sc_ptr, "grease_pencil_source", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + } + /* current Grease Pencil block */ /* TODO: show some info about who owns this? */ uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink"); @@ -281,14 +293,17 @@ static void draw_gpencil_panel(bContext *C, uiLayout *layout, bGPdata *gpd, Poin row = uiLayoutRow(col, 1); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "VIEW", NULL, ICON_NONE); uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "CURSOR", NULL, ICON_NONE); - row = uiLayoutRow(col, 1); - uiLayoutSetActive(row, v3d_stroke_opts); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); - uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); - row = uiLayoutRow(col, 0); - uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); - uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + if (sc == NULL) { + row = uiLayoutRow(col, 1); + uiLayoutSetActive(row, v3d_stroke_opts); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "SURFACE", NULL, ICON_NONE); + uiItemEnumR_string(row, &gpd_ptr, "draw_mode", "STROKE", NULL, ICON_NONE); + + row = uiLayoutRow(col, 0); + uiLayoutSetActive(row, v3d_stroke_opts == STROKE_OPTS_V3D_ON); + uiItemR(row, &gpd_ptr, "use_stroke_endpoints", 0, NULL, ICON_NONE); + } } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 9250d48a20c..71cbabe9114 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -57,6 +57,7 @@ #include "BKE_library.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "WM_api.h" @@ -144,9 +145,23 @@ bGPdata **gpencil_data_get_pointers(bContext *C, PointerRNA *ptr) MovieClip *clip = ED_space_clip(sc); if (clip) { - /* for now, as long as there's a clip, default to using that in Clip Editor */ - if (ptr) RNA_id_pointer_create(&clip->id, ptr); - return &clip->gpd; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&clip->tracking); + + if (!track) + return NULL; + + if (ptr) + RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, ptr); + + return &track->gpd; + } + else { + if (ptr) + RNA_id_pointer_create(&clip->id, ptr); + + return &clip->gpd; + } } } break; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 3e569f8eb96..89d8ed9c465 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -44,6 +44,7 @@ #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -1125,6 +1126,15 @@ static int gp_session_initdata(bContext *C, tGPsdata *p) p->custom_color[1] = 0.0f; p->custom_color[2] = 0.5f; p->custom_color[3] = 0.9f; + + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + int framenr = sc->user.framenr; + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + p->imat[3][0] -= marker->pos[0]; + p->imat[3][1] -= marker->pos[1]; + } } break; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 6ababe2becb..7afa9fe8bc5 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -89,15 +89,16 @@ typedef struct bAnimContext { /* Main Data container types */ typedef enum eAnimCont_Types { - ANIMCONT_NONE = 0, /* invalid or no data */ - ANIMCONT_ACTION, /* action (bAction) */ - ANIMCONT_SHAPEKEY, /* shapekey (Key) */ - ANIMCONT_GPENCIL, /* grease pencil (screen) */ - ANIMCONT_DOPESHEET, /* dopesheet (bDopesheet) */ - ANIMCONT_FCURVES, /* animation F-Curves (bDopesheet) */ - ANIMCONT_DRIVERS, /* drivers (bDopesheet) */ - ANIMCONT_NLA, /* nla (bDopesheet) */ - ANIMCONT_CHANNEL /* animation channel (bAnimListElem) */ + ANIMCONT_NONE = 0, /* invalid or no data */ + ANIMCONT_ACTION = 1, /* action (bAction) */ + ANIMCONT_SHAPEKEY = 2, /* shapekey (Key) */ + ANIMCONT_GPENCIL = 3, /* grease pencil (screen) */ + ANIMCONT_DOPESHEET = 4, /* dopesheet (bDopesheet) */ + ANIMCONT_FCURVES = 5, /* animation F-Curves (bDopesheet) */ + ANIMCONT_DRIVERS = 6, /* drivers (bDopesheet) */ + ANIMCONT_NLA = 7, /* nla (bDopesheet) */ + ANIMCONT_CHANNEL = 8, /* animation channel (bAnimListElem) */ + ANIMCONT_MASK = 9 /* mask dopesheet */ } eAnimCont_Types; /* --------------- Channels -------------------- */ @@ -161,6 +162,9 @@ typedef enum eAnim_ChannelType { ANIMTYPE_GPDATABLOCK, ANIMTYPE_GPLAYER, + + ANIMTYPE_MASKDATABLOCK, + ANIMTYPE_MASKLAYER, ANIMTYPE_NLATRACK, ANIMTYPE_NLAACTION, @@ -174,6 +178,7 @@ typedef enum eAnim_KeyType { ALE_NONE = 0, /* no keyframe data */ ALE_FCURVE, /* F-Curve */ ALE_GPFRAME, /* Grease Pencil Frames */ + ALE_MASKLAY, /* Mask */ ALE_NLASTRIP, /* NLA Strips */ ALE_ALL, /* All channels summary */ @@ -281,6 +286,15 @@ typedef enum eAnimFilter_Flags { #define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED) == 0) #define SEL_GPL(gpl) (gpl->flag & GP_LAYER_SELECT) +/* Mask Only */ +/* Grease Pencil datablock settings */ +#define EXPANDED_MASK(mask) (mask->flag & MASK_ANIMF_EXPAND) +/* Grease Pencil Layer settings */ +#define EDITABLE_MASK(masklay) ((masklay->flag & MASK_LAYERFLAG_LOCKED) == 0) +#define SEL_MASKLAY(masklay) (masklay->flag & SELECT) + + + /* NLA only */ #define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED) #define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0) @@ -343,20 +357,20 @@ short ANIM_animdata_context_getdata(bAnimContext *ac); /* flag-setting behavior */ typedef enum eAnimChannels_SetFlag { - ACHANNEL_SETFLAG_CLEAR = 0, /* turn off */ - ACHANNEL_SETFLAG_ADD, /* turn on */ - ACHANNEL_SETFLAG_INVERT, /* on->off, off->on */ - ACHANNEL_SETFLAG_TOGGLE /* some on -> all off // all on */ + ACHANNEL_SETFLAG_CLEAR = 0, /* turn off */ + ACHANNEL_SETFLAG_ADD = 1, /* turn on */ + ACHANNEL_SETFLAG_INVERT = 2, /* on->off, off->on */ + ACHANNEL_SETFLAG_TOGGLE = 3 /* some on -> all off // all on */ } eAnimChannels_SetFlag; /* types of settings for AnimChannels */ typedef enum eAnimChannel_Settings { - ACHANNEL_SETTING_SELECT = 0, - ACHANNEL_SETTING_PROTECT, // warning: for drawing UI's, need to check if this is off (maybe inverse this later) - ACHANNEL_SETTING_MUTE, - ACHANNEL_SETTING_EXPAND, - ACHANNEL_SETTING_VISIBLE, /* only for Graph Editor */ - ACHANNEL_SETTING_SOLO /* only for NLA Tracks */ + ACHANNEL_SETTING_SELECT = 0, + ACHANNEL_SETTING_PROTECT = 1, /* warning: for drawing UI's, need to check if this is off (maybe inverse this later) */ + ACHANNEL_SETTING_MUTE = 2, + ACHANNEL_SETTING_EXPAND = 3, + ACHANNEL_SETTING_VISIBLE = 4, /* only for Graph Editor */ + ACHANNEL_SETTING_SOLO = 5 /* only for NLA Tracks */ } eAnimChannel_Settings; diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 7943a17c377..1d42954a416 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -36,6 +36,7 @@ struct bContext; struct bScreen; struct ImBuf; struct Main; +struct Mask; struct MovieClip; struct SpaceClip; struct wmEvent; @@ -46,14 +47,21 @@ int ED_space_clip_poll(struct bContext *C); int ED_space_clip_view_clip_poll(struct bContext *C); int ED_space_clip_tracking_poll(struct bContext *C); -int ED_space_clip_tracking_size_poll(struct bContext *C); -int ED_space_clip_tracking_frame_poll(struct bContext *C); +int ED_space_clip_maskedit_poll(struct bContext *C); +int ED_space_clip_maskedit_mask_poll(bContext *C); void ED_space_clip_set(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip); struct MovieClip *ED_space_clip(struct SpaceClip *sc); +struct Mask *ED_space_clip_mask(struct SpaceClip *sc); void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy); + +int ED_space_clip_clip_framenr(struct SpaceClip *sc); + +void ED_space_clip_mask_size(struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_mask_aspect(struct SpaceClip *sc, float *aspx, float *aspy); struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc); struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle); @@ -72,6 +80,8 @@ void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); int ED_space_clip_show_trackedit(struct SpaceClip *sc); +int ED_space_clip_show_maskedit(struct SpaceClip *sc); +void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask); /* clip_ops.c */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index bd3e4371a79..32eb63a26d5 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -76,31 +76,34 @@ void ED_operatortypes_gpencil(void); /* ------------ Grease-Pencil Drawing API ------------------ */ /* drawgpencil.c */ -void draw_gpencil_2dimage(struct bContext *C, struct ImBuf *ibuf); +void draw_gpencil_2dimage(struct bContext *C /* , struct ImBuf *ibuf */); void draw_gpencil_view2d(struct bContext *C, short onlyv2d); void draw_gpencil_view3d(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, short only3d); void gpencil_panel_standard(const struct bContext *C, struct Panel *pa); /* ----------- Grease-Pencil AnimEdit API ------------------ */ -short gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, short (*gpf_cb)(struct bGPDframe *, struct Scene *)); -void gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel); +short ED_gplayer_frames_looper(struct bGPDlayer *gpl, struct Scene *scene, + short (*gpf_cb)(struct bGPDframe *, struct Scene *)); +void ED_gplayer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, short onlysel); -short is_gplayer_frame_selected(struct bGPDlayer *gpl); -void set_gplayer_frame_selection(struct bGPDlayer *gpl, short mode); -void select_gpencil_frames(struct bGPDlayer *gpl, short select_mode); -void select_gpencil_frame(struct bGPDlayer *gpl, int selx, short select_mode); -void borderselect_gplayer_frames(struct bGPDlayer *gpl, float min, float max, short select_mode); +short ED_gplayer_frame_select_check(struct bGPDlayer *gpl); +void ED_gplayer_frame_select_set(struct bGPDlayer *gpl, short mode); +void ED_gplayer_frames_select_border(struct bGPDlayer *gpl, float min, float max, short select_mode); +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 delete_gplayer_frames(struct bGPDlayer *gpl); -void duplicate_gplayer_frames(struct bGPDlayer *gpd); +void ED_gplayer_frames_delete(struct bGPDlayer *gpl); +void ED_gplayer_frames_duplicate(struct bGPDlayer *gpl); +#if 0 void free_gpcopybuf(void); void copy_gpdata(void); void paste_gpdata(void); void snap_gplayer_frames(struct bGPDlayer *gpl, short mode); void mirror_gplayer_frames(struct bGPDlayer *gpl, short mode); +#endif /* ------------ Grease-Pencil Undo System ------------------ */ int ED_gpencil_session_active(void); diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index cd64427de78..8a65699f404 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -42,6 +42,7 @@ struct bActionGroup; struct Object; struct ListBase; struct bGPDlayer; +struct MaskLayer; struct Scene; struct View2D; struct DLRBT_Tree; @@ -122,6 +123,8 @@ void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypo /* Grease Pencil Layer */ // XXX not restored void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos); +/* Mask Layer */ +void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos); /* Keydata Generation --------------- */ /* F-Curve */ @@ -139,6 +142,9 @@ void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, struct /* Grease Pencil Layer */ // XXX not restored void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct DLRBT_Tree *keys); +/* Mask */ +// XXX not restored +void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, struct DLRBT_Tree *keys); /* ActKeyColumn API ---------------- */ /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ diff --git a/source/blender/editors/include/ED_mask.h b/source/blender/editors/include/ED_mask.h new file mode 100644 index 00000000000..773da04bc7b --- /dev/null +++ b/source/blender/editors/include/ED_mask.h @@ -0,0 +1,74 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ED_mask.h + * \ingroup editors + */ + +#ifndef __ED_MASK_H__ +#define __ED_MASK_H__ + +struct wmKeyConfig; +struct MaskLayer; +struct MaskLayerShape; + +/* mask_editor.c */ +void ED_operatortypes_mask(void); +void ED_keymap_mask(struct wmKeyConfig *keyconf); +void ED_operatormacros_mask(void); + +/* mask_draw.c */ +void ED_mask_draw(const bContext *C, const char draw_flag, const char draw_type); + +/* 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); + +/* ----------- Mask AnimEdit API ------------------ */ +short ED_masklayer_frames_looper(struct MaskLayer *masklay, struct Scene *scene, + short (*masklay_shape_cb)(struct MaskLayerShape *, struct Scene *)); +void ED_masklayer_make_cfra_list(struct MaskLayer *masklay, ListBase *elems, short onlysel); + +short ED_masklayer_frame_select_check(struct MaskLayer *masklay); +void ED_masklayer_frame_select_set(struct MaskLayer *masklay, short mode); +void ED_masklayer_frames_select_border(struct MaskLayer *masklay, float min, float max, short select_mode); +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); +void ED_masklayer_frames_duplicate(struct MaskLayer *masklay); + +#if 0 +void free_gpcopybuf(void); +void copy_gpdata(void); +void paste_gpdata(void); + + void snap_masklayer_frames(struct MaskLayer *masklay, short mode); + void mirror_masklayer_frames(struct MaskLayer *masklay, short mode); +#endif + +#endif /* __ED_MASK_H__ */ diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 8dc83df2977..9c10a270ef8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -90,6 +90,7 @@ struct Base *ED_object_scene_link(struct Scene *scene, struct Object *ob); void ED_keymap_proportional_cycle(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_obmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); +void ED_keymap_proportional_maskmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap); void ED_keymap_proportional_editmode(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, const short do_connected); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 464f2db30a2..4faf82eec36 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -170,6 +170,7 @@ int ED_operator_editmball(struct bContext *C); int ED_operator_uvedit(struct bContext *C); int ED_operator_uvmap(struct bContext *C); int ED_operator_posemode(struct bContext *C); +int ED_operator_mask(struct bContext *C); /* default keymaps, bitflags */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 3bef1f56655..608df8dd9b3 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -71,6 +71,7 @@ enum { TFM_BONESIZE, TFM_BONE_ENVELOPE, TFM_CURVE_SHRINKFATTEN, + TFM_MASK_SHRINKFATTEN, TFM_BONE_ROLL, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE, @@ -96,12 +97,13 @@ enum { #define CTX_BMESH 64 #define CTX_NDOF 128 #define CTX_MOVIECLIP 256 +#define CTX_MASK 512 /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) * (if 0 is returns, *vec is unmodified) * */ -int calculateTransformCenter(struct bContext *C, int centerMode, float *cent3d, int *cent2d); +int calculateTransformCenter(struct bContext *C, int centerMode, float cent3d[3], int cent2d[2]); struct TransInfo; struct ScrArea; @@ -166,8 +168,7 @@ typedef struct DepthPeel { struct ListBase; -typedef enum SnapMode -{ +typedef enum SnapMode { SNAP_ALL = 0, SNAP_NOT_SELECTED = 1, SNAP_NOT_OBEDIT = 2 diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 55210080e01..34892fb3c27 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -282,7 +282,7 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active); int ED_view3d_context_activate(struct bContext *C); void ED_view3d_draw_offscreen(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, - int winx, int winy, float viewmat[][4], float winmat[][4], int draw_background); + int winx, int winy, float viewmat[][4], float winmat[][4], int do_bgpic); struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey, unsigned int flag, int draw_background, char err_out[256]); struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(struct Scene *scene, struct Object *camera, int width, int height, unsigned int flag, int drawtype, int draw_background, char err_out[256]); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index b82a0c5e480..bb6f9fad771 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -195,7 +195,8 @@ typedef struct uiLayout uiLayout; /*#define FUN 192*/ /*UNUSED*/ #define BIT 256 -#define BUTPOIN (128 + 64 + 32) +/* button reqyires a pointer */ +#define BUTPOIN (FLO | SHO | CHA) #define BUT (1 << 9) #define ROW (2 << 9) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index ca19a8092d0..ac59d2a6983 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -151,6 +151,7 @@ enum { TH_SEQ_MOVIE, TH_SEQ_MOVIECLIP, + TH_SEQ_MASK, TH_SEQ_IMAGE, TH_SEQ_SCENE, TH_SEQ_AUDIO, @@ -203,7 +204,20 @@ enum { TH_MATCH, /* highlight color for search matches */ TH_SELECT_HIGHLIGHT, /* highlight color for selected outliner item */ - TH_SKIN_ROOT + TH_SKIN_ROOT, + + TH_ANIM_ACTIVE, /* active action */ + TH_ANIM_INACTIVE, /* no active action */ + + TH_NLA_TWEAK, /* 'tweaking' track in NLA */ + TH_NLA_TWEAK_DUPLI, /* error/warning flag for other strips referencing dupli strip */ + + TH_NLA_TRANSITION, + TH_NLA_TRANSITION_SEL, + TH_NLA_META, + TH_NLA_META_SEL, + TH_NLA_SOUND, + TH_NLA_SOUND_SEL }; /* XXX WARNING: previous is saved in file, so do not change order! */ @@ -242,6 +256,9 @@ void UI_GetThemeColor3fv(int colorid, float col[3]); void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]); void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3]); +// get four color values, scaled to 0.0-1.0 range +void UI_GetThemeColor4fv(int colorid, float col[4]); + // get the 3 or 4 byte values void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]); void UI_GetThemeColor4ubv(int colorid, unsigned char col[4]); diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index a0b418c1a9a..f368e7cf4c7 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -43,6 +43,7 @@ #include "BKE_colortools.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "IMB_imbuf.h" @@ -658,37 +659,59 @@ static void draw_scope_end(rctf *rect, GLint *scissor) } static void histogram_draw_one(float r, float g, float b, float alpha, - float x, float y, float w, float h, float *data, int res) + float x, float y, float w, float h, float *data, int res, const short is_line) { int i; - /* under the curve */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glColor4f(r, g, b, alpha); - - glShadeModel(GL_FLAT); - glBegin(GL_QUAD_STRIP); - glVertex2f(x, y); - glVertex2f(x, y + (data[0] * h)); - for (i = 1; i < res; i++) { - float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); - glVertex2f(x2, y); + if (is_line) { + + glLineWidth(1.5); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glColor4f(r, g, b, alpha); + + /* curve outline */ + + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable(GL_LINE_SMOOTH); + glBegin(GL_LINE_STRIP); + for (i = 0; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + } + glEnd(); + glDisable(GL_LINE_SMOOTH); + + glLineWidth(1.0); } - glEnd(); - - /* curve outline */ - glColor4f(0.f, 0.f, 0.f, 0.25f); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_LINE_SMOOTH); - glBegin(GL_LINE_STRIP); - for (i = 0; i < res; i++) { - float x2 = x + i * (w / (float)res); - glVertex2f(x2, y + (data[i] * h)); + else { + /* under the curve */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glColor4f(r, g, b, alpha); + + glShadeModel(GL_FLAT); + glBegin(GL_QUAD_STRIP); + glVertex2f(x, y); + glVertex2f(x, y + (data[0] * h)); + for (i = 1; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + glVertex2f(x2, y); + } + glEnd(); + + /* curve outline */ + glColor4f(0.f, 0.f, 0.f, 0.25f); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_LINE_SMOOTH); + glBegin(GL_LINE_STRIP); + for (i = 0; i < res; i++) { + float x2 = x + i * (w / (float)res); + glVertex2f(x2, y + (data[i] * h)); + } + glEnd(); + glDisable(GL_LINE_SMOOTH); } - glEnd(); - glDisable(GL_LINE_SMOOTH); } void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) @@ -698,6 +721,7 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) rctf rect; int i; float w, h; + const short is_line = (hist->flag & HISTO_FLAG_LINE) != 0; //float alpha; GLint scissor[4]; @@ -730,15 +754,19 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) fdrawline(rect.xmin + (i / 4.f) * w, rect.ymin, rect.xmin + (i / 4.f) * w, rect.ymax); } - if (hist->mode == HISTO_MODE_LUMA) - histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res); + if (hist->mode == HISTO_MODE_LUMA) { + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line); + } + else if (hist->mode == HISTO_MODE_ALPHA) { + histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line); + } else { if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) - histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res); + histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) - histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res); + histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line); if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) - histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res); + histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line); } /* outline, scale gripper */ @@ -1480,36 +1508,10 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } -static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float track_pos[2], int width, float height, int margin) -{ - ImBuf *scaleibuf; - const float scalex = ((float)ibuf->x - 2 * margin) / width; - const float scaley = ((float)ibuf->y - 2 * margin) / height; - /* NOTE: 1.0f = 0.5f for integer coordinate coorrection (center of pixel vs. left bottom corner of bixel) - * and 0.5f for centering image in preview (cross is draving at exact center of widget so image - * should be shifted by half of pixel for correct centering) - sergey */ - float off_x = (int)track_pos[0] - track_pos[0] + 1.0f; - float off_y = (int)track_pos[1] - track_pos[1] + 1.0f; - int x, y; - - scaleibuf = IMB_allocImBuf(width, height, 32, IB_rect); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - float src_x = scalex * (x) + margin - off_x; - float src_y = scaley * (y) + margin - off_y; - - bicubic_interpolation(ibuf, scaleibuf, src_x, src_y, x, y); - } - } - - return scaleibuf; -} - void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) { rctf rect; - int ok = 0; + int ok = 0, width, height; GLint scissor[4]; MovieClipScopes *scopes = (MovieClipScopes *)but->poin; @@ -1518,6 +1520,9 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2; rect.ymax = (float)recti->ymax - 1; + width = rect.xmax - rect.xmin + 1; + height = rect.ymax - rect.ymin; + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1535,40 +1540,53 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc ok = 1; } - else if (scopes->track_preview) { - /* additional margin around image */ - /* NOTE: should be kept in sync with value from BKE_movieclip_update_scopes */ - const int margin = 3; - float zoomx, zoomy, track_pos[2], off_x, off_y; - int a, width, height; + else if ((scopes->track_search) && + ((!scopes->track_preview) || + (scopes->track_preview->x != width || scopes->track_preview->y != height))) + { + ImBuf *tmpibuf; + + if (scopes->track_preview) + IMB_freeImBuf(scopes->track_preview); + + tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height, + scopes->track_search, &scopes->undist_marker, + width, height, scopes->track_pos); + + if (tmpibuf->rect_float) + IMB_rect_from_float(tmpibuf); + + // XXX: for debug only + // tmpibuf->ftype = PNG; + // IMB_saveiff(tmpibuf, "sample.png", IB_rect); + + if (tmpibuf->rect) + scopes->track_preview = tmpibuf; + else + IMB_freeImBuf(tmpibuf); + } + + if (!ok && scopes->track_preview) { + float track_pos[2]; + int a; ImBuf *drawibuf; glPushMatrix(); - track_pos[0] = scopes->track_pos[0] - margin; - track_pos[1] = scopes->track_pos[1] - margin; + track_pos[0] = scopes->track_pos[0]; + track_pos[1] = scopes->track_pos[1]; /* draw content of pattern area */ glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]); - width = rect.xmax - rect.xmin + 1; - height = rect.ymax - rect.ymin; - if (width > 0 && height > 0) { - zoomx = (float)width / (scopes->track_preview->x - 2 * margin); - zoomy = (float)height / (scopes->track_preview->y - 2 * margin); - - off_x = ((int)track_pos[0] - track_pos[0] + 0.5f) * zoomx; - off_y = ((int)track_pos[1] - track_pos[1] + 0.5f) * zoomy; - - drawibuf = scale_trackpreview_ibuf(scopes->track_preview, track_pos, width, height, margin); + drawibuf = scopes->track_preview; glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); - IMB_freeImBuf(drawibuf); /* draw cross for pizel position */ - glTranslatef(off_x + rect.xmin + track_pos[0] * zoomx, off_y + rect.ymin + track_pos[1] * zoomy, 0.f); + glTranslatef(rect.xmin + track_pos[0], rect.ymin + track_pos[1], 0.f); glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, rect.xmax - rect.xmin, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 8753c427816..a2adbd7a143 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3819,22 +3819,21 @@ static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx Histogram *hist = (Histogram *)but->poin; /* rcti rect; */ int changed = 1; - float /* dx, */ dy, yfac = 1.f; /* UNUSED */ + float /* dx, */ dy; /* UNUSED */ /* rect.xmin = but->x1; rect.xmax = but->x2; */ /* rect.ymin = but->y1; rect.ymax = but->y2; */ /* dx = mx - data->draglastx; */ /* UNUSED */ dy = my - data->draglasty; - - + if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { /* resize histogram widget itself */ hist->height = (but->y2 - but->y1) + (data->dragstarty - my); } else { /* scale histogram values */ - yfac = MIN2(powf(hist->ymax, 2.f), 1.f) * 0.5f; + const float yfac = MIN2(powf(hist->ymax, 2.f), 1.f) * 0.5f; hist->ymax += dy * yfac; CLAMP(hist->ymax, 1.f, 100.f); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 21f87029cb0..7f9a998e6d0 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -166,13 +166,14 @@ static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) static void panels_collapse_all(ScrArea *sa, ARegion *ar) { - Panel *pa; - int flag = ((panel_aligned(sa, ar)==BUT_HORIZONTAL)? PNL_CLOSEDX: PNL_CLOSEDY); + Panel *pa; + int flag = ((panel_aligned(sa, ar) == BUT_HORIZONTAL) ? PNL_CLOSEDX : PNL_CLOSEDY); - for (pa= ar->panels.first; pa; pa= pa->next) { - if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) - pa->flag = flag; - } + for (pa = ar->panels.first; pa; pa = pa->next) { + if (pa->type && !(pa->type->flag & PNL_NO_HEADER)) { + pa->flag = flag; + } + } } diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index dee9368bbc6..eae721ef484 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -580,8 +580,10 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co row = uiLayoutRow(layout, 1); /* Label - either use the provided text, or will become "ID-Block:" */ - if (text) - uiItemL(row, text, ICON_NONE); + if (text) { + if (text[0]) + uiItemL(row, text, ICON_NONE); + } else uiItemL(row, "ID-Block:", ICON_NONE); @@ -2240,6 +2242,20 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe uiItemL(split, name, ICON_OBJECT_DATA); } } + else if (itemptr->type == &RNA_MaskLayer) { + split = uiLayoutSplit(sub, 0.5f, 0); + + uiItemL(split, name, icon); + + uiBlockSetEmboss(block, UI_EMBOSSN); + row = uiLayoutRow(split, 1); + // uiItemR(row, itemptr, "alpha", 0, "", ICON_NONE); // enable when used + uiItemR(row, itemptr, "hide", 0, "", 0); + uiItemR(row, itemptr, "hide_select", 0, "", 0); + uiItemR(row, itemptr, "hide_render", 0, "", 0); + + uiBlockSetEmboss(block, UI_EMBOSS); + } /* There is a last chance to display custom controls (in addition to the name/label): * If the given item property group features a string property named as prop_list, diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 1a7fc98ef74..004c5306d65 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -162,9 +162,10 @@ static unsigned int scroll_circle_face[14][3] = { }; -static float menu_tria_vert[6][2]= { -{-0.33, 0.16}, {0.33, 0.16}, {0, 0.82}, -{0, -0.82}, {-0.33, -0.16}, {0.33, -0.16}}; +static float menu_tria_vert[6][2] = { + {-0.33, 0.16}, {0.33, 0.16}, {0, 0.82}, + {0, -0.82}, {-0.33, -0.16}, {0.33, -0.16} +}; @@ -1168,7 +1169,7 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b #if 0 ui_rasterpos_safe(x, y, but->aspect); - if (but->type == IDPOIN) transopts = 0; // no translation, of course! + if (but->type == IDPOIN) transopts = 0; // no translation, of course! else transopts = ui_translate_buttons(); #endif @@ -3133,7 +3134,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct if (but->drawflag & UI_BUT_DRAW_ENUM_ARROWS) wt = widget_type(UI_WTYPE_MENU_RADIO); /* with arrows */ else - wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */ + wt = widget_type(UI_WTYPE_MENU_ICON_RADIO); /* no arrows */ } /* with menu arrows */ else diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 027655e393f..f39510666ec 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -376,6 +376,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = ts->movie; break; case TH_SEQ_MOVIECLIP: cp = ts->movieclip; break; + case TH_SEQ_MASK: + cp = ts->mask; break; case TH_SEQ_IMAGE: cp = ts->image; break; case TH_SEQ_SCENE: @@ -477,6 +479,39 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_SKIN_ROOT: cp = ts->skin_root; break; + + case TH_ANIM_ACTIVE: + cp = ts->anim_active; + break; + case TH_ANIM_INACTIVE: + cp = ts->anim_non_active; + break; + + case TH_NLA_TWEAK: + cp = ts->nla_tweaking; + break; + case TH_NLA_TWEAK_DUPLI: + cp = ts->nla_tweakdupli; + break; + + case TH_NLA_TRANSITION: + cp = ts->nla_transition; + break; + case TH_NLA_TRANSITION_SEL: + cp = ts->nla_transition_sel; + break; + case TH_NLA_META: + cp = ts->nla_meta; + break; + case TH_NLA_META_SEL: + cp = ts->nla_meta_sel; + break; + case TH_NLA_SOUND: + cp = ts->nla_sound; + break; + case TH_NLA_SOUND_SEL: + cp = ts->nla_sound_sel; + break; } } } @@ -741,19 +776,34 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tipo.handle_sel_auto_clamped, 0xf0, 0xaf, 0x90, 255); btheme->tipo.handle_vertex_size = 4; - rgba_char_args_set(btheme->tipo.ds_channel, 82, 96, 110, 255); + rgba_char_args_set(btheme->tipo.ds_channel, 82, 96, 110, 255); rgba_char_args_set(btheme->tipo.ds_subchannel, 124, 137, 150, 255); - rgba_char_args_set(btheme->tipo.group, 79, 101, 73, 255); - rgba_char_args_set(btheme->tipo.group_active, 135, 177, 125, 255); + rgba_char_args_set(btheme->tipo.group, 79, 101, 73, 255); + rgba_char_args_set(btheme->tipo.group_active, 135, 177, 125, 255); /* dopesheet */ btheme->tact = btheme->tipo; rgba_char_args_set(btheme->tact.strip, 12, 10, 10, 128); rgba_char_args_set(btheme->tact.strip_select, 255, 140, 0, 255); + rgba_char_args_set(btheme->tact.anim_active, 204, 112, 26, 102); + /* space nla */ btheme->tnla = btheme->tact; + rgba_char_args_set(btheme->tnla.anim_active, 204, 112, 26, 102); /* same as for dopesheet; duplicate here for easier reference */ + rgba_char_args_set(btheme->tnla.anim_non_active, 153, 135, 97, 77); + + rgba_char_args_set(btheme->tnla.nla_tweaking, 77, 243, 26, 77); + rgba_char_args_set(btheme->tnla.nla_tweakdupli, 217, 0, 0, 255); + + rgba_char_args_set(btheme->tnla.nla_transition, 28, 38, 48, 255); + rgba_char_args_set(btheme->tnla.nla_transition_sel, 46, 117, 219, 255); + rgba_char_args_set(btheme->tnla.nla_meta, 51, 38, 66, 255); + rgba_char_args_set(btheme->tnla.nla_meta_sel, 105, 33, 150, 255); + rgba_char_args_set(btheme->tnla.nla_sound, 43, 61, 61, 255); + rgba_char_args_set(btheme->tnla.nla_sound_sel, 31, 122, 122, 255); + /* space file */ /* to have something initialized */ btheme->tfile = btheme->tv3d; @@ -777,6 +827,7 @@ void ui_theme_init_default(void) rgba_char_args_set(btheme->tseq.back, 116, 116, 116, 255); rgba_char_args_set(btheme->tseq.movie, 81, 105, 135, 255); rgba_char_args_set(btheme->tseq.movieclip, 32, 32, 143, 255); + rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255); rgba_char_args_set(btheme->tseq.image, 109, 88, 129, 255); rgba_char_args_set(btheme->tseq.scene, 78, 152, 62, 255); rgba_char_args_set(btheme->tseq.audio, 46, 143, 143, 255); @@ -1049,6 +1100,17 @@ void UI_GetThemeColor3fv(int colorid, float col[3]) col[2] = ((float)cp[2]) / 255.0f; } +void UI_GetThemeColor4fv(int colorid, float col[4]) +{ + const unsigned char *cp; + + cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid); + col[0] = ((float)cp[0]) / 255.0f; + col[1] = ((float)cp[1]) / 255.0f; + col[2] = ((float)cp[2]) / 255.0f; + col[3] = ((float)cp[3]) / 255.0f; +} + // get the color, range 0.0-1.0, complete with shading offset void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]) { @@ -1822,6 +1884,38 @@ void init_userdef_do_versions(void) for (btheme = U.themes.first; btheme; btheme = btheme->next) rgba_char_args_set(btheme->tv3d.skin_root, 180, 77, 77, 255); } + + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 7)) { + bTheme *btheme; + + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + /* DopeSheet Summary */ + rgba_char_args_set(btheme->tact.anim_active, 204, 112, 26, 102); + + /* NLA Colors */ + rgba_char_args_set(btheme->tnla.anim_active, 204, 112, 26, 102); /* same as dopesheet above */ + rgba_char_args_set(btheme->tnla.anim_non_active,153, 135, 97, 77); + + rgba_char_args_set(btheme->tnla.nla_tweaking, 77, 243, 26, 77); + rgba_char_args_set(btheme->tnla.nla_tweakdupli, 217, 0, 0, 255); + + rgba_char_args_set(btheme->tnla.nla_transition, 28, 38, 48, 255); + rgba_char_args_set(btheme->tnla.nla_transition_sel, 46, 117, 219, 255); + rgba_char_args_set(btheme->tnla.nla_meta, 51, 38, 66, 255); + rgba_char_args_set(btheme->tnla.nla_meta_sel, 105, 33, 150, 255); + rgba_char_args_set(btheme->tnla.nla_sound, 43, 61, 61, 255); + rgba_char_args_set(btheme->tnla.nla_sound_sel, 31, 122, 122, 255); + } + } + + if (bmain->versionfile < 263 || (bmain->versionfile == 263 && bmain->subversionfile < 11)) { + bTheme *btheme; + for (btheme = U.themes.first; btheme; btheme = btheme->next) { + if (btheme->tseq.movieclip[0] == 0) { + rgba_char_args_set(btheme->tseq.mask, 152, 78, 62, 255); + } + } + } /* Freestyle color settings */ { diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt new file mode 100644 index 00000000000..57be5a2234a --- /dev/null +++ b/source/blender/editors/mask/CMakeLists.txt @@ -0,0 +1,52 @@ +# ***** 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. +# +# The Original Code is Copyright (C) 2012 Blender Foundation. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenloader + ../../blenlib + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ${GLEW_INCLUDE_PATH} +) + +set(INC_SYS +) + +set(SRC + mask_add.c + mask_draw.c + mask_edit.c + mask_editaction.c + mask_ops.c + mask_relationships.c + mask_select.c + mask_shapekey.c + + mask_intern.h +) + +blender_add_lib(bf_editor_mask "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mask/SConscript b/source/blender/editors/mask/SConscript new file mode 100644 index 00000000000..4af000d038d --- /dev/null +++ b/source/blender/editors/mask/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') +defs = [] +incs = '../include ../../blenkernel ../../blenloader ../../blenlib ../../windowmanager ../../makesdna' +incs += ' ../../makesrna #/extern/glew/include #/intern/guardedalloc' + +env.BlenderLib ( 'bf_editors_mask', sources, Split(incs), defs, libtype=['core'], priority=[100] ) diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c new file mode 100644 index 00000000000..0bc9adb6577 --- /dev/null +++ b/source/blender/editors/mask/mask_add.c @@ -0,0 +1,711 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_add.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mask.h" /* own include */ + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + + +static int find_nearest_diff_point(bContext *C, Mask *mask, const float normal_co[2], int threshold, int feather, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + float *u_r, float tangent[2], + const short use_deform) +{ + MaskLayer *masklay, *point_masklay; + MaskSpline *point_spline; + MaskSplinePoint *point = NULL; + float dist, co[2]; + int width, height; + float u; + float scalex, scaley, aspx, aspy; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + MaskSplinePoint *cur_point; + + for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points; + i < spline->tot_point; + i++, cur_point++) + { + float *diff_points; + int tot_diff_point; + + diff_points = BKE_mask_point_segment_diff_with_resolution(spline, cur_point, width, height, + &tot_diff_point); + + if (diff_points) { + int i, tot_feather_point, tot_point; + float *feather_points = NULL, *points; + + if (feather) { + feather_points = BKE_mask_point_segment_feather_diff_with_resolution(spline, cur_point, + width, height, + &tot_feather_point); + + points = feather_points; + tot_point = tot_feather_point; + } + else { + points = diff_points; + tot_point = tot_diff_point; + } + + for (i = 0; i < tot_point - 1; i++) { + float cur_dist, a[2], b[2]; + + a[0] = points[2 * i] * scalex; + a[1] = points[2 * i + 1] * scaley; + + b[0] = points[2 * i + 2] * scalex; + b[1] = points[2 * i + 3] * scaley; + + cur_dist = dist_to_line_segment_v2(co, a, b); + + if (point == NULL || cur_dist < dist) { + if (tangent) + sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + + point_masklay = masklay; + point_spline = spline; + point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; + dist = cur_dist; + u = (float)i / tot_point; + + } + } + + if (feather_points) + MEM_freeN(feather_points); + + MEM_freeN(diff_points); + } + } + } + } + + if (point && dist < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (u_r) { + u = BKE_mask_spline_project_co(point_spline, point, u, normal_co, MASK_PROJ_ANY); + + *u_r = u; + } + + return TRUE; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + +/******************** add vertex *********************/ + +static void setup_vertex_point(bContext *C, Mask *mask, MaskSpline *spline, MaskSplinePoint *new_point, + const float point_co[2], const float tangent[2], const float u, + MaskSplinePoint *reference_point, const short reference_adjacent) +{ + MaskSplinePoint *prev_point = NULL; + MaskSplinePoint *next_point = NULL; + BezTriple *bezt; + int width, height; + float co[3]; + const float len = 20.0; /* default length of handle in pixel space */ + + copy_v2_v2(co, point_co); + co[2] = 0.0f; + + ED_mask_size(C, &width, &height); + + /* point coordinate */ + bezt = &new_point->bezt; + + bezt->h1 = bezt->h2 = HD_ALIGN; + + if (reference_point) { + bezt->h1 = bezt->h2 = MAX2(reference_point->bezt.h2, reference_point->bezt.h1); + } + else if (reference_adjacent) { + if (spline->tot_point != 1) { + int index = (int)(new_point - spline->points); + prev_point = &spline->points[(index - 1) % spline->tot_point]; + next_point = &spline->points[(index + 1) % spline->tot_point]; + + bezt->h1 = bezt->h2 = MAX2(prev_point->bezt.h2, next_point->bezt.h1); + + /* note, we may want to copy other attributes later, radius? pressure? color? */ + } + } + + copy_v3_v3(bezt->vec[0], co); + copy_v3_v3(bezt->vec[1], co); + copy_v3_v3(bezt->vec[2], co); + + /* initial offset for handles */ + if (spline->tot_point == 1) { + /* first point of splien is aligned horizontally */ + bezt->vec[0][0] -= len / width; + bezt->vec[2][0] += len / width; + } + else if (tangent) { + float vec[2]; + + copy_v2_v2(vec, tangent); + + vec[0] *= width; + vec[1] *= height; + + mul_v2_fl(vec, len / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + sub_v2_v2(bezt->vec[0], vec); + add_v2_v2(bezt->vec[2], vec); + + if (reference_adjacent) { + BKE_mask_calc_handle_adjacent_interp(spline, new_point, u); + } + } + else { + + /* calculating auto handles works much nicer */ +#if 0 + /* next points are aligning in the direction of previous/next point */ + MaskSplinePoint *point; + float v1[2], v2[2], vec[2]; + float dir = 1.0f; + + if (new_point == spline->points) { + point = new_point + 1; + dir = -1.0f; + } + else + point = new_point - 1; + + if (spline->tot_point < 3) { + v1[0] = point->bezt.vec[1][0] * width; + v1[1] = point->bezt.vec[1][1] * height; + + v2[0] = new_point->bezt.vec[1][0] * width; + v2[1] = new_point->bezt.vec[1][1] * height; + } + else { + if (new_point == spline->points) { + v1[0] = spline->points[1].bezt.vec[1][0] * width; + v1[1] = spline->points[1].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 1].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 1].bezt.vec[1][1] * height; + } + else { + v1[0] = spline->points[0].bezt.vec[1][0] * width; + v1[1] = spline->points[0].bezt.vec[1][1] * height; + + v2[0] = spline->points[spline->tot_point - 2].bezt.vec[1][0] * width; + v2[1] = spline->points[spline->tot_point - 2].bezt.vec[1][1] * height; + } + } + + sub_v2_v2v2(vec, v1, v2); + mul_v2_fl(vec, len * dir / len_v2(vec)); + + vec[0] /= width; + vec[1] /= height; + + add_v2_v2(bezt->vec[0], vec); + sub_v2_v2(bezt->vec[2], vec); +#else + BKE_mask_calc_handle_point_auto(spline, new_point, TRUE); + BKE_mask_calc_handle_adjacent_interp(spline, new_point, u); + +#endif + } + + BKE_mask_parent_init(&new_point->parent); + + /* select new point */ + MASKPOINT_SEL_ALL(new_point); + ED_mask_select_flush_all(mask); +} + + +/* **** add extrude vertex **** */ + +static void finSelectedSplinePoint(MaskLayer *masklay, MaskSpline **spline, MaskSplinePoint **point, short check_active) +{ + MaskSpline *cur_spline = masklay->splines.first; + + *spline = NULL; + *point = NULL; + + if (check_active) { + if (masklay->act_spline && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + *spline = masklay->act_spline; + *point = masklay->act_point; + return; + } + } + + while (cur_spline) { + int i; + + for (i = 0; i < cur_spline->tot_point; i++) { + MaskSplinePoint *cur_point = &cur_spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(cur_point)) { + if (*spline != NULL && *spline != cur_spline) { + *spline = NULL; + *point = NULL; + return; + } + else if (*point) { + *point = NULL; + } + else { + *spline = cur_spline; + *point = cur_point; + } + } + } + + cur_spline = cur_spline->next; + } +} + +/* **** add subdivide vertex **** */ + +static void mask_spline_add_point_at_index(MaskSpline *spline, int point_index) +{ + MaskSplinePoint *new_point_array; + + new_point_array = MEM_callocN(sizeof(MaskSplinePoint) * (spline->tot_point + 1), "add mask vert points"); + + memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * (point_index + 1)); + memcpy(new_point_array + point_index + 2, spline->points + point_index + 1, + sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1)); + + MEM_freeN(spline->points); + spline->points = new_point_array; + spline->tot_point++; +} + +static int add_vertex_subdivide(bContext *C, Mask *mask, const float co[2]) +{ + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float tangent[2]; + float u; + + if (find_nearest_diff_point(C, mask, co, threshold, FALSE, &masklay, &spline, &point, &u, tangent, TRUE)) { + MaskSplinePoint *new_point; + int point_index = point - spline->points; + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + mask_spline_add_point_at_index(spline, point_index); + + new_point = &spline->points[point_index + 1]; + + setup_vertex_point(C, mask, spline, new_point, co, tangent, u, NULL, TRUE); + + /* TODO - we could pass the spline! */ + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, TRUE, TRUE); + + masklay->act_point = new_point; + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; + } + + return FALSE; +} + +static int add_vertex_extrude(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + /* check on which side we want to add the point */ + int point_index; + float tangent_point[2]; + float tangent_co[2]; + int do_cyclic_correct = FALSE; + int do_recalc_src = FALSE; /* when extruding from endpoints only */ + int do_prev; /* use prev point rather then next?? */ + + if (!masklay) { + return FALSE; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + point_index = (point - spline->points); + + MASKPOINT_DESEL_ALL(point); + + if ((spline->flag & MASK_SPLINE_CYCLIC) || + (point_index > 0 && point_index != spline->tot_point - 1)) + { + BKE_mask_calc_tangent_polyline(spline, point, tangent_point); + sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); + + if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { + do_prev = TRUE; + } + else { + do_prev = FALSE; + } + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { + do_prev = TRUE; + do_recalc_src = TRUE; + } + else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { + do_prev = FALSE; + do_recalc_src = TRUE; + } + else { + do_prev = FALSE; /* quiet warning */ + /* should never get here */ + BLI_assert(0); + } + + /* use the point before the active one */ + if (do_prev) { + point_index--; + if (point_index < 0) { + point_index += spline->tot_point; /* wrap index */ + if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { + do_cyclic_correct = TRUE; + point_index = 0; + } + } + } + +// print_v2("", tangent_point); +// printf("%d\n", point_index); + + mask_spline_add_point_at_index(spline, point_index); + + if (do_cyclic_correct) { + ref_point = &spline->points[point_index + 1]; + new_point = &spline->points[point_index]; + *ref_point = *new_point; + memset(new_point, 0, sizeof(*new_point)); + } + else { + ref_point = &spline->points[point_index]; + new_point = &spline->points[point_index + 1]; + } + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + if (masklay->splines_shapes.first) { + point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + if (do_recalc_src) { + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(spline, ref_point, FALSE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_new(bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) +{ + MaskSpline *spline; + MaskSplinePoint *point; + MaskSplinePoint *new_point = NULL, *ref_point = NULL; + + if (!masklay) { + /* if there's no masklay currently operationg on, create new one */ + masklay = BKE_mask_layer_new(mask, ""); + mask->masklay_act = mask->masklay_tot - 1; + spline = NULL; + point = NULL; + } + else { + finSelectedSplinePoint(masklay, &spline, &point, TRUE); + } + + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (!spline) { + /* no selected splines in active masklay, create new spline */ + spline = BKE_mask_spline_add(masklay); + } + + masklay->act_spline = spline; + new_point = spline->points; + + masklay->act_point = new_point; + + setup_vertex_point(C, mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE); + + { + int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); + BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return TRUE; +} + +static int add_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + float co[2]; + + masklay = BKE_mask_layer_active(mask); + + if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + masklay = NULL; + } + + RNA_float_get_array(op->ptr, "location", co); + + if (masklay && masklay->act_point && MASKPOINT_ISSEL_ANY(masklay->act_point)) { + + /* cheap trick - double click for cyclic */ + MaskSpline *spline = masklay->act_spline; + MaskSplinePoint *point = masklay->act_point; + + int is_sta = (point == spline->points); + int is_end = (point == &spline->points[spline->tot_point - 1]); + + /* then check are we overlapping the mouse */ + if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { + if (spline->flag & MASK_SPLINE_CYCLIC) { + /* nothing to do */ + return OPERATOR_CANCELLED; + } + else { + /* recalc the connecting point as well to make a nice even curve */ + MaskSplinePoint *point_other = is_end ? spline->points : &spline->points[spline->tot_point - 1]; + spline->flag |= MASK_SPLINE_CYCLIC; + + /* TODO, update keyframes in time */ + BKE_mask_calc_handle_point_auto(spline, point, FALSE); + BKE_mask_calc_handle_point_auto(spline, point_other, FALSE); + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + return OPERATOR_FINISHED; + } + } + + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_extrude(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + else { + if (!add_vertex_subdivide(C, mask, co)) { + if (!add_vertex_new(C, mask, masklay, co)) { + return OPERATOR_CANCELLED; + } + } + } + + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + return OPERATOR_FINISHED; +} + +static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_vertex_exec(C, op); +} + +void MASK_OT_add_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Vertex"; + ot->description = "Add vertex to active spline"; + ot->idname = "MASK_OT_add_vertex"; + + /* api callbacks */ + ot->exec = add_vertex_exec; + ot->invoke = add_vertex_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + +/******************** add feather vertex *********************/ + +static int add_feather_vertex_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + const float threshold = 9; + float co[2], u; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); + if (point) + return OPERATOR_FINISHED; + + if (find_nearest_diff_point(C, mask, co, threshold, TRUE, &masklay, &spline, &point, &u, NULL, TRUE)) { + Scene *scene = CTX_data_scene(C); + float w = BKE_mask_point_weight(spline, point, u); + float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u); + + if (weight_scalar != 0.0f) { + w = w / weight_scalar; + } + + BKE_mask_point_add_uw(point, u, w); + + BKE_mask_update_display(mask, scene->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_feather_vertex_exec(C, op); +} + +void MASK_OT_add_feather_vertex(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add feather Vertex"; + ot->description = "Add vertex to feather"; + ot->idname = "MASK_OT_add_feather_vertex"; + + /* api callbacks */ + ot->exec = add_feather_vertex_exec; + ot->invoke = add_feather_vertex_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c new file mode 100644 index 00000000000..e1efb6d841b --- /dev/null +++ b/source/blender/editors/mask/mask_draw.c @@ -0,0 +1,425 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_draw.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "ED_mask.h" /* own include */ +#include "BIF_gl.h" + +#include "UI_resources.h" + +#include "mask_intern.h" /* own include */ + +static void mask_spline_color_get(MaskLayer *masklay, MaskSpline *spline, const int is_sel, + unsigned char r_rgb[4]) +{ + if (is_sel) { + if (masklay->act_spline == spline) { + r_rgb[0] = r_rgb[1] = r_rgb[2] = 255; + } + else { + r_rgb[0] = 255; + r_rgb[1] = r_rgb[2] = 0; + } + } + else { + r_rgb[0] = 128; + r_rgb[1] = r_rgb[2] = 0; + } + + r_rgb[3] = 255; +} + +static void mask_spline_feather_color_get(MaskLayer *UNUSED(masklay), MaskSpline *UNUSED(spline), const int is_sel, + unsigned char r_rgb[4]) +{ + if (is_sel) { + r_rgb[1] = 255; + r_rgb[0] = r_rgb[2] = 0; + } + else { + r_rgb[1] = 128; + r_rgb[0] = r_rgb[2] = 0; + } + + r_rgb[3] = 255; +} + +#if 0 +static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) +{ + int i; + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + if (!spline->tot_point) + return; + + glColor3ub(0, 0, 0); + glEnable(GL_LINE_STIPPLE); + glLineStipple(1, 0xAAAA); + + glBegin(GL_LINES); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &points_array[i]; + BezTriple *bezt = &point->bezt; + + if (point->parent.id) { + glVertex2f(bezt->vec[1][0], + bezt->vec[1][1]); + + glVertex2f(bezt->vec[1][0] - point->parent.offset[0], + bezt->vec[1][1] - point->parent.offset[1]); + } + } + + glEnd(); + + glDisable(GL_LINE_STIPPLE); +} +#endif + +/* return non-zero if spline is selected */ +static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline) +{ + const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; + unsigned char rgb_spline[4]; + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i, hsize, tot_feather_point; + float (*feather_points)[2], (*fp)[2]; + + if (!spline->tot_point) + return; + + hsize = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + + glPointSize(hsize); + + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); + + /* feather points */ + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); + for (i = 0; i < spline->tot_point; i++) { + + /* watch it! this is intentionally not the deform array, only check for sel */ + MaskSplinePoint *point = &spline->points[i]; + + int j; + + for (j = 0; j < point->tot_uw + 1; j++) { + int sel = FALSE; + + if (j == 0) { + sel = MASKPOINT_ISSEL_ANY(point); + } + else { + sel = point->uw[j - 1].flag & SELECT; + } + + if (sel) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.5f, 0.5f, 0.0f); + } + + glBegin(GL_POINTS); + glVertex2fv(*fp); + glEnd(); + + fp++; + } + } + MEM_freeN(feather_points); + + /* control points */ + for (i = 0; i < spline->tot_point; i++) { + + /* watch it! this is intentionally not the deform array, only check for sel */ + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + BezTriple *bezt = &point_deform->bezt; + + float handle[2]; + float *vert = bezt->vec[1]; + int has_handle = BKE_mask_point_has_handle(point); + + BKE_mask_point_handle(point_deform, handle); + + /* draw handle segment */ + if (has_handle) { + glColor3ubv(rgb_spline); + + glBegin(GL_LINES); + glVertex3fv(vert); + glVertex3fv(handle); + glEnd(); + } + + /* draw CV point */ + if (MASKPOINT_ISSEL_KNOT(point)) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else + glColor3f(0.5f, 0.5f, 0.0f); + + glBegin(GL_POINTS); + glVertex3fv(vert); + glEnd(); + + /* draw handle points */ + if (has_handle) { + if (MASKPOINT_ISSEL_HANDLE(point)) { + if (point == masklay->act_point) + glColor3f(1.0f, 1.0f, 1.0f); + else + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.5f, 0.5f, 0.0f); + } + + glBegin(GL_POINTS); + glVertex3fv(handle); + glEnd(); + } + } + + glPointSize(1.0f); +} + +/* #define USE_XOR */ + +static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, + const short is_feather, const short is_smooth, + const unsigned char rgb_spline[4], const char draw_type) +{ + const int draw_method = (spline->flag & MASK_SPLINE_CYCLIC) ? GL_LINE_LOOP : GL_LINE_STRIP; + unsigned char rgb_tmp[4]; + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + + switch (draw_type) { + + case MASK_DT_OUTLINE: + glLineWidth(3); + cpack(0x0); + + glDrawArrays(draw_method, 0, tot_point); + + glLineWidth(1); + glColor4ubv(rgb_spline); + glDrawArrays(draw_method, 0, tot_point); + + break; + + case MASK_DT_DASH: + default: + glEnable(GL_LINE_STIPPLE); + +#ifdef USE_XOR + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_OR); +#endif + glColor4ubv(rgb_spline); + glLineStipple(3, 0xaaaa); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + +#ifdef USE_XOR + glDisable(GL_COLOR_LOGIC_OP); +#endif + glColor4ub(0, 0, 0, 255); + glLineStipple(3, 0x5555); + glDrawArrays(draw_method, 0, tot_point); + + glDisable(GL_LINE_STIPPLE); + break; + + + case MASK_DT_BLACK: + case MASK_DT_WHITE: + if (draw_type == MASK_DT_BLACK) { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 0; } + else { rgb_tmp[0] = rgb_tmp[1] = rgb_tmp[2] = 255; } + /* alpha values seem too low but gl draws many points that compensate for it */ + if (is_feather) { rgb_tmp[3] = 64; } + else { rgb_tmp[3] = 128; } + + if (is_feather) { + rgb_tmp[0] = (unsigned char)(((short)rgb_tmp[0] + (short)rgb_spline[0]) / 2); + rgb_tmp[1] = (unsigned char)(((short)rgb_tmp[1] + (short)rgb_spline[1]) / 2); + rgb_tmp[2] = (unsigned char)(((short)rgb_tmp[2] + (short)rgb_spline[2]) / 2); + } + + if (is_smooth == FALSE && is_feather) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + glColor4ubv(rgb_tmp); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, points); + glDrawArrays(draw_method, 0, tot_point); + + glDrawArrays(draw_method, 0, tot_point); + + if (is_smooth == FALSE && is_feather) { + glDisable(GL_BLEND); + } + + break; + } + + glDisableClientState(GL_VERTEX_ARRAY); + +} + +static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, + const char draw_flag, const char draw_type, + int width, int height) +{ + unsigned char rgb_tmp[4]; + + const short is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; + const short is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH); + + int tot_diff_point; + float (*diff_points)[2]; + + int tot_feather_point; + float (*feather_points)[2]; + + diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height, &tot_diff_point); + + if (!diff_points) + return; + + if (is_smooth) { + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + feather_points = BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height, &tot_feather_point); + + /* draw feather */ + mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); + mask_draw_curve_type(spline, feather_points, tot_feather_point, + TRUE, is_smooth, + rgb_tmp, draw_type); + MEM_freeN(feather_points); + + /* draw main curve */ + mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); + mask_draw_curve_type(spline, diff_points, tot_diff_point, + FALSE, is_smooth, + rgb_tmp, draw_type); + MEM_freeN(diff_points); + + if (draw_flag & MASK_DRAWFLAG_SMOOTH) { + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); + } + + (void)draw_type; +} + +static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, + int width, int height) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + + /* draw curve itself first... */ + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); + +// draw_spline_parents(masklay, spline); + + if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { + /* ...and then handles over the curve so they're nicely visible */ + draw_spline_points(masklay, spline); + } + + /* show undeform for testing */ + if (0) { + void *back = spline->points_deform; + + spline->points_deform = NULL; + draw_spline_curve(masklay, spline, draw_flag, draw_type, width, height); +// draw_spline_parents(masklay, spline); + draw_spline_points(masklay, spline); + spline->points_deform = back; + } + } + } +} + +void ED_mask_draw(const bContext *C, + const char draw_flag, const char draw_type) +{ + Mask *mask = CTX_data_edit_mask(C); + int width, height; + + if (!mask) + return; + + /* TODO: for now, in the future better to make sure all utility functions + * are using const specifier for non-changing pointers + */ + ED_mask_size((bContext *)C, &width, &height); + + draw_masklays(mask, draw_flag, draw_type, width, height); +} diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c new file mode 100644 index 00000000000..24f55f66bb8 --- /dev/null +++ b/source/blender/editors/mask/mask_edit.c @@ -0,0 +1,342 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_edit.c + * \ingroup edmask + */ + + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" /* own include */ +#include "ED_object.h" /* ED_keymap_proportional_maskmode only */ +#include "ED_clip.h" +#include "ED_transform.h" + +#include "RNA_access.h" + +#include "mask_intern.h" /* own include */ + +/********************** generic poll functions *********************/ + +int ED_maskedit_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskedit_poll(C); + } + + return FALSE; +} + +int ED_maskedit_mask_poll(bContext *C) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + return ED_space_clip_maskedit_mask_poll(C); + } + + return FALSE; +} + +/********************** registration *********************/ + +void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2]) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_clip_mouse_pos(C, event, co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } +} + +/* input: x/y - mval space + * output: xr/yr - mask point space */ +void ED_mask_point_pos(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + float co[2]; + + if (sc) { + ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + +void ED_mask_point_pos__reverse(bContext *C, float x, float y, float *xr, float *yr) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + + float co[2]; + + if (sc && ar) { + co[0] = x; + co[1] = y; + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co); + ED_clip_point_stable_pos__reverse(sc, ar, co, co); + } + else { + /* possible other spaces from which mask editing is available */ + zero_v2(co); + } + + *xr = co[0]; + *yr = co[1]; +} + +void ED_mask_size(bContext *C, int *width, int *height) +{ + ScrArea *sa = CTX_wm_area(C); + if (sa && sa->spacedata.first) { + if (sa->spacetype == SPACE_CLIP) { + SpaceClip *sc = sa->spacedata.first; + ED_space_clip_mask_size(sc, width, height); + return; + } + else if (sa->spacetype == SPACE_SEQ) { + Scene *scene = CTX_data_scene(C); + *width = (scene->r.size * scene->r.xsch) / 100; + *height = (scene->r.size * scene->r.ysch) / 100; + return; + } + } + + /* possible other spaces from which mask editing is available */ + *width = 0; + *height = 0; +} + +void ED_mask_aspect(bContext *C, float *aspx, float *aspy) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ED_space_clip_mask_aspect(sc, aspx, aspy); + } + else { + /* possible other spaces from which mask editing is available */ + *aspx = 1.0f; + *aspy = 1.0f; + } +} + +void ED_mask_pixelspace_factor(bContext *C, float *scalex, float *scaley) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { + ARegion *ar = CTX_wm_region(C); + int width, height; + float zoomx, zoomy, aspx, aspy; + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *scalex = ((float)width * aspx) * zoomx; + *scaley = ((float)height * aspy) * zoomy; + } + else { + /* possible other spaces from which mask editing is available */ + *scalex = 1.0f; + *scaley = 1.0f; + } +} + +/********************** registration *********************/ + +void ED_operatortypes_mask(void) +{ + WM_operatortype_append(MASK_OT_new); + + /* mask layers */ + WM_operatortype_append(MASK_OT_layer_new); + WM_operatortype_append(MASK_OT_layer_remove); + + /* add */ + WM_operatortype_append(MASK_OT_add_vertex); + WM_operatortype_append(MASK_OT_add_feather_vertex); + + /* geometry */ + WM_operatortype_append(MASK_OT_switch_direction); + WM_operatortype_append(MASK_OT_delete); + + /* select */ + WM_operatortype_append(MASK_OT_select); + WM_operatortype_append(MASK_OT_select_all); + WM_operatortype_append(MASK_OT_select_border); + WM_operatortype_append(MASK_OT_select_lasso); + WM_operatortype_append(MASK_OT_select_circle); + WM_operatortype_append(MASK_OT_select_linked_pick); + WM_operatortype_append(MASK_OT_select_linked); + + /* hide/reveal */ + WM_operatortype_append(MASK_OT_hide_view_clear); + WM_operatortype_append(MASK_OT_hide_view_set); + + /* feather */ + WM_operatortype_append(MASK_OT_feather_weight_clear); + + /* shape */ + WM_operatortype_append(MASK_OT_slide_point); + WM_operatortype_append(MASK_OT_cyclic_toggle); + WM_operatortype_append(MASK_OT_handle_type_set); + + /* relationships */ + WM_operatortype_append(MASK_OT_parent_set); + WM_operatortype_append(MASK_OT_parent_clear); + + /* shapekeys */ + WM_operatortype_append(MASK_OT_shape_key_insert); + WM_operatortype_append(MASK_OT_shape_key_clear); + WM_operatortype_append(MASK_OT_shape_key_feather_reset); +} + +void ED_keymap_mask(wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0); + keymap->poll = ED_maskedit_poll; + + WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0); + + /* mask mode supports PET now */ + ED_keymap_proportional_cycle(keyconf, keymap); + ED_keymap_proportional_maskmode(keyconf, keymap); + + /* geometry */ + WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0); + + /* selection */ + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + RNA_boolean_set(kmi->ptr, "toggle", TRUE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", SEL_INVERT); + + WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + + WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", FALSE); + kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "deselect", TRUE); + + /* hide/reveal */ + WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0); + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", FALSE); + + kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", TRUE); + + /* select clip while in maker view, + * this matches View3D functionality where you can select an + * object while in editmode to allow vertex parenting */ + kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "extend", FALSE); + + /* shape */ + WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0); + // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0); + /* ... matches curve editmode */ + RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_MASK_SHRINKFATTEN); + + /* relationships */ + WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0); + + WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0); + + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); +} + +void ED_operatormacros_mask(void) +{ + /* XXX: just for sample */ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); + ot->description = "Add new vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_vertex"); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE); + + ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", "Add new vertex to feater and slide it", OPTYPE_UNDO | OPTYPE_REGISTER); + ot->description = "Add new feather vertex and slide it"; + WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex"); + otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point"); + RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE); +} diff --git a/source/blender/editors/mask/mask_editaction.c b/source/blender/editors/mask/mask_editaction.c new file mode 100644 index 00000000000..3836b393bf8 --- /dev/null +++ b/source/blender/editors/mask/mask_editaction.c @@ -0,0 +1,250 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2008, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Joshua Leung + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_editaction.c + * \ingroup edgpencil + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BKE_fcurve.h" +#include "BKE_mask.h" + +#include "ED_anim_api.h" +#include "ED_keyframes_edit.h" + +/* ***************************************** */ +/* NOTE ABOUT THIS FILE: + * This file contains code for editing Grease Pencil data in the Action Editor + * as a 'keyframes', so that a user can adjust the timing of Grease Pencil drawings. + * Therefore, this file mostly contains functions for selecting Grease-Pencil frames. + */ +/* ***************************************** */ +/* Generics - Loopers */ + +/* Loops over the gp-frames for a gp-layer, and applies the given callback */ +short ED_masklayer_frames_looper(MaskLayer *masklay, Scene *scene, short (*masklay_shape_cb)(MaskLayerShape *, Scene *)) +{ + MaskLayerShape *masklay_shape; + + /* error checker */ + if (masklay == NULL) + return 0; + + /* do loop */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + /* execute callback */ + if (masklay_shape_cb(masklay_shape, scene)) + return 1; + } + + /* nothing to return */ + return 0; +} + +/* ****************************************** */ +/* Data Conversion Tools */ + +/* make a listing all the gp-frames in a layer as cfraelems */ +void ED_masklayer_make_cfra_list(MaskLayer *masklay, ListBase *elems, short onlysel) +{ + MaskLayerShape *masklay_shape; + CfraElem *ce; + + /* error checking */ + if (ELEM(NULL, masklay, elems)) + return; + + /* loop through gp-frames, adding */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if ((onlysel == 0) || (masklay_shape->flag & MASK_SHAPE_SELECT)) { + ce = MEM_callocN(sizeof(CfraElem), "CfraElem"); + + ce->cfra = (float)masklay_shape->frame; + ce->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? 1 : 0; + + BLI_addtail(elems, ce); + } + } +} + +/* ***************************************** */ +/* Selection Tools */ + +/* check if one of the frames in this layer is selected */ +short ED_masklayer_frame_select_check(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape; + + /* error checking */ + if (masklay == NULL) + return 0; + + /* stop at the first one found */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if (masklay_shape->flag & MASK_SHAPE_SELECT) + return 1; + } + + /* not found */ + return 0; +} + +/* helper function - select gp-frame based on SELECT_* mode */ +static void masklayshape_select(MaskLayerShape *masklay_shape, short select_mode) +{ + if (masklay_shape == NULL) + return; + + switch (select_mode) { + case SELECT_ADD: + masklay_shape->flag |= MASK_SHAPE_SELECT; + break; + case SELECT_SUBTRACT: + masklay_shape->flag &= ~MASK_SHAPE_SELECT; + break; + case SELECT_INVERT: + masklay_shape->flag ^= MASK_SHAPE_SELECT; + break; + } +} + +/* set all/none/invert select (like above, but with SELECT_* modes) */ +void ED_mask_select_frames(MaskLayer *masklay, short select_mode) +{ + MaskLayerShape *masklay_shape; + + /* error checking */ + if (masklay == NULL) + return; + + /* handle according to mode */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + masklayshape_select(masklay_shape, select_mode); + } +} + +/* set all/none/invert select */ +void ED_masklayer_frame_select_set(MaskLayer *masklay, short mode) +{ + /* error checking */ + if (masklay == NULL) + return; + + /* now call the standard function */ + ED_mask_select_frames(masklay, mode); +} + +/* select the frame in this layer that occurs on this frame (there should only be one at most) */ +void ED_mask_select_frame(MaskLayer *masklay, int selx, short select_mode) +{ + MaskLayerShape *masklay_shape; + + if (masklay == NULL) + return; + + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, selx); + + if (masklay_shape) { + masklayshape_select(masklay_shape, select_mode); + } +} + +/* select the frames in this layer that occur within the bounds specified */ +void ED_masklayer_frames_select_border(MaskLayer *masklay, float min, float max, short select_mode) +{ + MaskLayerShape *masklay_shape; + + if (masklay == NULL) + return; + + /* only select those frames which are in bounds */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) { + if (IN_RANGE(masklay_shape->frame, min, max)) + masklayshape_select(masklay_shape, select_mode); + } +} + +/* ***************************************** */ +/* Frame Editing Tools */ + +/* Delete selected frames */ +void ED_masklayer_frames_delete(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape, *masklay_shape_next; + + /* error checking */ + if (masklay == NULL) + return; + + /* 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) + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + } +} + +/* Duplicate selected frames from given gp-layer */ +void ED_masklayer_frames_duplicate(MaskLayer *masklay) +{ + MaskLayerShape *masklay_shape, *gpfn; + + /* error checking */ + if (masklay == NULL) + return; + + /* duplicate selected frames */ + for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = gpfn) { + gpfn = masklay_shape->next; + + /* duplicate this frame */ + if (masklay_shape->flag & MASK_SHAPE_SELECT) { + MaskLayerShape *mask_shape_dupe; + + /* duplicate frame, and deselect self */ + mask_shape_dupe = BKE_mask_layer_shape_duplicate(masklay_shape); + masklay_shape->flag &= ~MASK_SHAPE_SELECT; + + // XXX - how to handle duplicate frames? + BLI_insertlinkafter(&masklay->splines_shapes, masklay_shape, mask_shape_dupe); + } + } +} diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h new file mode 100644 index 00000000000..fc6089238a1 --- /dev/null +++ b/source/blender/editors/mask/mask_intern.h @@ -0,0 +1,113 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_intern.h + * \ingroup spclip + */ + +#ifndef __MASK_INTERN_H__ +#define __MASK_INTERN_H__ + +struct bContext; +struct wmEvent; +struct wmOperatorType; + +/* internal exports only */ + +/* mask_add.c */ +void MASK_OT_add_vertex(struct wmOperatorType *ot); +void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); + +/* mask_ops.c */ +void MASK_OT_new(struct wmOperatorType *ot); +void MASK_OT_layer_new(struct wmOperatorType *ot); +void MASK_OT_layer_remove(struct wmOperatorType *ot); +void MASK_OT_cyclic_toggle(struct wmOperatorType *ot); + +void MASK_OT_slide_point(struct wmOperatorType *ot); + +void MASK_OT_delete(struct wmOperatorType *ot); + +void MASK_OT_hide_view_clear(struct wmOperatorType *ot); +void MASK_OT_hide_view_set(struct wmOperatorType *ot); +void MASK_OT_feather_weight_clear(struct wmOperatorType *ot); +void MASK_OT_switch_direction(struct wmOperatorType *ot); + +void MASK_OT_handle_type_set(struct wmOperatorType *ot); + +int ED_mask_feather_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, struct MaskSplinePoint **point_r, + struct MaskSplinePointUW **uw_r, float *score); + +struct MaskSplinePoint *ED_mask_point_find_nearest( + struct bContext *C, struct Mask *mask, float normal_co[2], int threshold, + struct MaskLayer **masklay_r, struct MaskSpline **spline_r, int *is_handle_r, + float *score); + +/* mask_relationships.c */ +void MASK_OT_parent_set(struct wmOperatorType *ot); +void MASK_OT_parent_clear(struct wmOperatorType *ot); + +/* mask_select.c */ +void MASK_OT_select(struct wmOperatorType *ot); +void MASK_OT_select_all(struct wmOperatorType *ot); + +void MASK_OT_select_border(struct wmOperatorType *ot); +void MASK_OT_select_lasso(struct wmOperatorType *ot); +void MASK_OT_select_circle(struct wmOperatorType *ot); +void MASK_OT_select_linked_pick(struct wmOperatorType *ot); +void MASK_OT_select_linked(struct wmOperatorType *ot); + +int ED_mask_spline_select_check(struct MaskSpline *spline); +int ED_mask_layer_select_check(struct MaskLayer *masklay); +int ED_mask_select_check(struct Mask *mask); + +void ED_mask_spline_select_set(struct MaskSpline *spline, const short do_select); +void ED_mask_layer_select_set(struct MaskLayer *masklay, const short do_select); +void ED_mask_select_toggle_all(struct Mask *mask, int action); +void ED_mask_select_flush_all(struct Mask *mask); + +/* mask_editor.c */ +int ED_maskedit_poll(struct bContext *C); +int ED_maskedit_mask_poll(struct bContext *C); + +void ED_mask_size(struct bContext *C, int *width, int *height); +void ED_mask_aspect(struct bContext *C, float *aspx, float *aspy); + +void ED_mask_pixelspace_factor(struct bContext *C, float *scalex, float *scaley); +void ED_mask_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); + +void ED_mask_point_pos(struct bContext *C, float x, float y, float *xr, float *yr); +void ED_mask_point_pos__reverse(struct bContext *C, float x, float y, float *xr, float *yr); + +/* mask_shapekey.c */ +void MASK_OT_shape_key_insert(struct wmOperatorType *ot); +void MASK_OT_shape_key_clear(struct wmOperatorType *ot); +void MASK_OT_shape_key_feather_reset(struct wmOperatorType *ot); + +#endif /* __MASK_INTERN_H__ */ diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c new file mode 100644 index 00000000000..67fd57ed50b --- /dev/null +++ b/source/blender/editors/mask/mask_ops.c @@ -0,0 +1,1263 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_ops.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_scene_types.h" +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" +#include "ED_clip.h" +#include "ED_keyframing.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +/******************** utility functions *********************/ + +MaskSplinePoint *ED_mask_point_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskLayer **masklay_r, MaskSpline **spline_r, int *is_handle_r, + float *score) +{ + MaskLayer *masklay; + MaskLayer *point_masklay = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + float co[2], aspx, aspy; + float len = FLT_MAX, scalex, scaley; + int is_handle = FALSE, width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + MaskSplinePoint *cur_point_deform = &points_array[i]; + float cur_len, vec[2], handle[2]; + + vec[0] = cur_point_deform->bezt.vec[1][0] * scalex; + vec[1] = cur_point_deform->bezt.vec[1][1] * scaley; + + if (BKE_mask_point_has_handle(cur_point)) { + BKE_mask_point_handle(cur_point_deform, handle); + handle[0] *= scalex; + handle[1] *= scaley; + + cur_len = len_v2v2(co, handle); + + if (cur_len < len) { + point_masklay = masklay; + point_spline = spline; + point = cur_point; + len = cur_len; + is_handle = TRUE; + } + } + + cur_len = len_v2v2(co, vec); + + if (cur_len < len) { + point_spline = spline; + point_masklay = masklay; + point = cur_point; + len = cur_len; + is_handle = FALSE; + } + } + } + } + + if (len < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (is_handle_r) + *is_handle_r = is_handle; + + if (score) + *score = len; + + return point; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (is_handle_r) + *is_handle_r = FALSE; + + return NULL; +} + +int ED_mask_feather_find_nearest(bContext *C, Mask *mask, float normal_co[2], int threshold, + MaskLayer **masklay_r, MaskSpline **spline_r, MaskSplinePoint **point_r, + MaskSplinePointUW **uw_r, float *score) +{ + MaskLayer *masklay, *point_masklay = NULL; + MaskSpline *point_spline = NULL; + MaskSplinePoint *point = NULL; + MaskSplinePointUW *uw = NULL; + float len = FLT_MAX, co[2]; + float scalex, scaley, aspx, aspy; + int width, height; + + ED_mask_size(C, &width, &height); + ED_mask_aspect(C, &aspx, &aspy); + ED_mask_pixelspace_factor(C, &scalex, &scaley); + + co[0] = normal_co[0] * scalex; + co[1] = normal_co[1] * scaley; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + //MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + int i, tot_feather_point; + float (*feather_points)[2], (*fp)[2]; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); + + for (i = 0; i < spline->tot_point; i++) { + int j; + MaskSplinePoint *cur_point = &spline->points[i]; + + for (j = 0; j < cur_point->tot_uw + 1; j++) { + float cur_len, vec[2]; + + vec[0] = (*fp)[0] * scalex; + vec[1] = (*fp)[1] * scaley; + + cur_len = len_v2v2(vec, co); + + if (point == NULL || cur_len < len) { + if (j == 0) + uw = NULL; + else + uw = &cur_point->uw[j - 1]; + + point_masklay = masklay; + point_spline = spline; + point = cur_point; + len = cur_len; + } + + fp++; + } + } + + MEM_freeN(feather_points); + } + } + + if (len < threshold) { + if (masklay_r) + *masklay_r = point_masklay; + + if (spline_r) + *spline_r = point_spline; + + if (point_r) + *point_r = point; + + if (uw_r) + *uw_r = uw; + + if (score) + *score = len; + + return TRUE; + } + + if (masklay_r) + *masklay_r = NULL; + + if (spline_r) + *spline_r = NULL; + + if (point_r) + *point_r = NULL; + + return FALSE; +} + + +/******************** create new mask *********************/ + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask; + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + mask = BKE_mask_new(name); + + if (sc) + ED_space_clip_set_mask(C, sc, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "New Mask"; + ot->description = "Create new mask"; + ot->idname = "MASK_OT_new"; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* api callbacks */ + ot->exec = mask_new_exec; + ot->poll = ED_operator_mask; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask"); +} + +/******************** create new masklay *********************/ + +static int masklay_new_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + BKE_mask_layer_new(mask, name); + mask->masklay_act = mask->masklay_tot - 1; + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_layer_new(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Mask Layer"; + ot->description = "Add new mask layer for masking"; + ot->idname = "MASK_OT_layer_new"; + + /* api callbacks */ + ot->exec = masklay_new_exec; + ot->poll = ED_maskedit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_string(ot->srna, "name", "", MAX_ID_NAME - 2, "Name", "Name of new mask layer"); +} + +/******************** remove mask layer *********************/ + +static int masklay_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay = BKE_mask_layer_active(mask); + + if (masklay) { + BKE_mask_layer_remove(mask, masklay); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + } + + return OPERATOR_FINISHED; +} + +void MASK_OT_layer_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Remove Mask Layer"; + ot->description = "Remove mask layer"; + ot->idname = "MASK_OT_layer_remove"; + + /* api callbacks */ + ot->exec = masklay_remove_exec; + ot->poll = ED_maskedit_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************** slide *********************/ + +enum { + SLIDE_ACTION_NONE = 0, + SLIDE_ACTION_POINT = 1, + SLIDE_ACTION_HANDLE = 2, + SLIDE_ACTION_FEATHER = 3 +}; + +typedef struct SlidePointData { + int action; + + float co[2]; + float vec[3][3]; + + Mask *mask; + MaskLayer *masklay; + MaskSpline *spline, *orig_spline; + MaskSplinePoint *point; + MaskSplinePointUW *uw; + float handle[2], no[2], feather[2]; + int width, height; + float weight; + + short curvature_only, accurate; + short initial_feather, overall_feather; +} SlidePointData; + +static int slide_point_check_initial_feather(MaskSpline *spline) +{ + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (point->bezt.weight != 0.0f) + return FALSE; + + /* comment for now. if all bezt weights are zero - this is as good-as initial */ +#if 0 + int j; + for (j = 0; j < point->tot_uw; j++) { + if (point->uw[j].w != 0.0f) + return FALSE; + } +#endif + } + + return TRUE; +} + +static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + SlidePointData *customdata = NULL; + MaskLayer *masklay, *cv_masklay, *feather_masklay; + MaskSpline *spline, *cv_spline, *feather_spline; + MaskSplinePoint *point, *cv_point, *feather_point; + MaskSplinePointUW *uw = NULL; + int is_handle = FALSE, width, height, action = SLIDE_ACTION_NONE; + int slide_feather = RNA_boolean_get(op->ptr, "slide_feather"); + float co[2], cv_score, feather_score; + const float threshold = 19; + + ED_mask_mouse_pos(C, event, co); + ED_mask_size(C, &width, &height); + + cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score); + + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) { + if (slide_feather || !cv_point || feather_score < cv_score) { + action = SLIDE_ACTION_FEATHER; + + masklay = feather_masklay; + spline = feather_spline; + point = feather_point; + } + } + + if (cv_point && action == SLIDE_ACTION_NONE) { + if (is_handle) + action = SLIDE_ACTION_HANDLE; + else + action = SLIDE_ACTION_POINT; + + masklay = cv_masklay; + spline = cv_spline; + point = cv_point; + } + + if (action != SLIDE_ACTION_NONE) { + customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); + + customdata->mask = mask; + customdata->masklay = masklay; + customdata->spline = spline; + customdata->point = point; + customdata->width = width; + customdata->height = height; + customdata->action = action; + customdata->uw = uw; + + if (uw) { + float co[2]; + float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); + + customdata->weight = uw->w; + BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_normal(spline, point, uw->u, customdata->no); + + madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar); + } + else { + BezTriple *bezt = &point->bezt; + + customdata->weight = bezt->weight; + BKE_mask_point_normal(spline, point, 0.0f, customdata->no); + + madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight); + } + + if (customdata->action == SLIDE_ACTION_FEATHER) + customdata->initial_feather = slide_point_check_initial_feather(spline); + + copy_m3_m3(customdata->vec, point->bezt.vec); + if (BKE_mask_point_has_handle(point)) + BKE_mask_point_handle(point, customdata->handle); + ED_mask_mouse_pos(C, event, customdata->co); + } + + return customdata; +} + +static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *slidedata = slide_point_customdata(C, op, event); + + if (slidedata) { + Mask *mask = CTX_data_edit_mask(C); + + op->customdata = slidedata; + + WM_event_add_modal_handler(C, op); + + if (slidedata->uw) { + if ((slidedata->uw->flag & SELECT) == 0) { + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + slidedata->uw->flag |= SELECT; + + ED_mask_select_flush_all(mask); + } + } + else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) { + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + BKE_mask_point_select_set(slidedata->point, TRUE); + + ED_mask_select_flush_all(mask); + } + + slidedata->masklay->act_spline = slidedata->spline; + slidedata->masklay->act_point = slidedata->point; + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_PASS_THROUGH; +} + +static void slide_point_delta_all_feather(SlidePointData *data, float delta) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + + point->bezt.weight = orig_point->bezt.weight + delta; + if (point->bezt.weight < 0.0f) + point->bezt.weight = 0.0f; + + /* not needed anymore */ +#if 0 + int j; + for (j = 0; j < point->tot_uw; j++) { + point->uw[j].w = orig_point->uw[j].w + delta; + if (point->uw[j].w < 0.0f) + point->uw[j].w = 0.0f; + } +#endif + } +} + +static void slide_point_restore_spline(SlidePointData *data) +{ + int i; + + for (i = 0; i < data->spline->tot_point; i++) { + MaskSplinePoint *point = &data->spline->points[i]; + MaskSplinePoint *orig_point = &data->orig_spline->points[i]; + int j; + + point->bezt = orig_point->bezt; + + for (j = 0; j < point->tot_uw; j++) + point->uw[j] = orig_point->uw[j]; + } +} + +static void cancel_slide_point(SlidePointData *data) +{ + /* cancel sliding */ + + if (data->orig_spline) { + slide_point_restore_spline(data); + } + else { + if (data->action == SLIDE_ACTION_FEATHER) { + if (data->uw) + data->uw->w = data->weight; + else + data->point->bezt.weight = data->weight; + } + else { + copy_m3_m3(data->point->bezt.vec, data->vec); + } + } +} + +static void free_slide_point_data(SlidePointData *data) +{ + if (data->orig_spline) + BKE_mask_spline_free(data->orig_spline); + + MEM_freeN(data); +} + +static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SlidePointData *data = (SlidePointData *)op->customdata; + BezTriple *bezt = &data->point->bezt; + float co[2], dco[2]; + + switch (event->type) { + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) { + if (data->action == SLIDE_ACTION_FEATHER) + data->overall_feather = event->val == KM_PRESS; + else + data->curvature_only = event->val == KM_PRESS; + } + + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) + data->accurate = event->val == KM_PRESS; + + /* no break! update CV position */ + + case MOUSEMOVE: + ED_mask_mouse_pos(C, event, co); + sub_v2_v2v2(dco, co, data->co); + + if (data->action == SLIDE_ACTION_HANDLE) { + float delta[2], offco[2]; + + sub_v2_v2v2(delta, data->handle, data->co); + + sub_v2_v2v2(offco, co, data->co); + if (data->accurate) + mul_v2_fl(offco, 0.2f); + add_v2_v2(offco, data->co); + add_v2_v2(offco, delta); + + BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec); + } + else if (data->action == SLIDE_ACTION_POINT) { + float delta[2]; + + copy_v2_v2(delta, dco); + if (data->accurate) + mul_v2_fl(delta, 0.2f); + + add_v2_v2v2(bezt->vec[0], data->vec[0], delta); + add_v2_v2v2(bezt->vec[1], data->vec[1], delta); + add_v2_v2v2(bezt->vec[2], data->vec[2], delta); + } + else if (data->action == SLIDE_ACTION_FEATHER) { + float vec[2], no[2], p[2], c[2], w, offco[2]; + float *weight = NULL; + float weight_scalar = 1.0f; + int overall_feather = data->overall_feather || data->initial_feather; + + add_v2_v2v2(offco, data->feather, dco); + + if (data->uw) { + /* project on both sides and find the closest one, + * prevents flickering when projecting onto both sides can happen */ + const float u_pos = BKE_mask_spline_project_co(data->spline, data->point, + data->uw->u, offco, MASK_PROJ_NEG); + const float u_neg = BKE_mask_spline_project_co(data->spline, data->point, + data->uw->u, offco, MASK_PROJ_POS); + float dist_pos = FLT_MAX; + float dist_neg = FLT_MAX; + float co_pos[2]; + float co_neg[2]; + float u; + + if (u_pos > 0.0f && u_pos < 1.0f) { + BKE_mask_point_segment_co(data->spline, data->point, u_pos, co_pos); + dist_pos = len_squared_v2v2(offco, co_pos); + } + + if (u_neg > 0.0f && u_neg < 1.0f) { + BKE_mask_point_segment_co(data->spline, data->point, u_neg, co_neg); + dist_neg = len_squared_v2v2(offco, co_neg); + } + + u = dist_pos < dist_neg ? u_pos : u_neg; + + if (u > 0.0f && u < 1.0f) { + data->uw->u = u; + + data->uw = BKE_mask_point_sort_uw(data->point, data->uw); + weight = &data->uw->w; + weight_scalar = BKE_mask_point_weight_scalar(data->spline, data->point, u); + if (weight_scalar != 0.0f) { + weight_scalar = 1.0f / weight_scalar; + } + + BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); + BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); + } + } + else { + weight = &bezt->weight; + /* weight_scalar = 1.0f; keep as is */ + copy_v2_v2(no, data->no); + copy_v2_v2(p, bezt->vec[1]); + } + + if (weight) { + sub_v2_v2v2(c, offco, p); + project_v2_v2v2(vec, c, no); + + w = len_v2(vec); + + if (overall_feather) { + float delta; + + if (dot_v2v2(no, vec) <= 0.0f) + w = -w; + + delta = w - data->weight; + + if (data->orig_spline == NULL) { + /* restore weight for currently sliding point, so orig_spline would be created + * with original weights used + */ + *weight = data->weight * weight_scalar; + + data->orig_spline = BKE_mask_spline_copy(data->spline); + } + + slide_point_delta_all_feather(data, delta); + } + else { + if (dot_v2v2(no, vec) <= 0.0f) + w = 0.0f; + + if (data->orig_spline) { + /* restore possible overall feather changes */ + slide_point_restore_spline(data); + + BKE_mask_spline_free(data->orig_spline); + data->orig_spline = NULL; + } + + if (weight_scalar != 0.0f) { + *weight = w * weight_scalar; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + break; + + case LEFTMOUSE: + if (event->val == KM_RELEASE) { + Scene *scene = CTX_data_scene(C); + + /* dont key sliding feather uw's */ + if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == FALSE) { + if (IS_AUTOKEY_ON(scene)) { + ED_mask_layer_shape_auto_key(data->masklay, CFRA); + } + } + + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_FINISHED; + } + + break; + + case ESCKEY: + cancel_slide_point(op->customdata); + + free_slide_point_data(op->customdata); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); + DAG_id_tag_update(&data->mask->id, 0); + + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; +} + +void MASK_OT_slide_point(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Slide Point"; + ot->description = "Slide control points"; + ot->idname = "MASK_OT_slide_point"; + + /* api callbacks */ + ot->invoke = slide_point_invoke; + ot->modal = slide_point_modal; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "slide_feather", 0, "Slide Feather", "First try to slide feather instead of vertex"); +} + +/******************** toggle cyclic *********************/ + +static int cyclic_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + spline->flag ^= MASK_SPLINE_CYCLIC; + } + } + } + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_cyclic_toggle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Toggle Cyclic"; + ot->description = "Toggle cyclic for selected splines"; + ot->idname = "MASK_OT_cyclic_toggle"; + + /* api callbacks */ + ot->exec = cyclic_toggle_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/******************** delete *********************/ + +static void delete_feather_points(MaskSplinePoint *point) +{ + int i, count = 0; + + if (!point->tot_uw) + return; + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) + count++; + } + + if (count == 0) { + MEM_freeN(point->uw); + point->uw = NULL; + point->tot_uw = 0; + } + else { + MaskSplinePointUW *new_uw; + int j = 0; + + new_uw = MEM_callocN(count * sizeof(MaskSplinePointUW), "new mask uw points"); + + for (i = 0; i < point->tot_uw; i++) { + if ((point->uw[i].flag & SELECT) == 0) { + new_uw[j++] = point->uw[i]; + } + } + + MEM_freeN(point->uw); + + point->uw = new_uw; + point->tot_uw = count; + } +} + +static int delete_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int mask_layer_shape_ofs = 0; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + spline = masklay->splines.first; + + while (spline) { + const int tot_point_orig = spline->tot_point; + int i, count = 0; + MaskSpline *next_spline = spline->next; + + /* count unselected points */ + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL_ANY(point)) + count++; + } + + if (count == 0) { + + /* delete the whole spline */ + BLI_remlink(&masklay->splines, spline); + BKE_mask_spline_free(spline); + + if (spline == masklay->act_spline) { + masklay->act_spline = NULL; + masklay->act_point = NULL; + } + + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig); + } + else { + MaskSplinePoint *new_points; + int j; + + new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints"); + + for (i = 0, j = 0; i < tot_point_orig; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (!MASKPOINT_ISSEL_ANY(point)) { + if (point == masklay->act_point) + masklay->act_point = &new_points[j]; + + delete_feather_points(point); + + new_points[j] = *point; + j++; + } + else { + if (point == masklay->act_point) + masklay->act_point = NULL; + + BKE_mask_point_free(point); + spline->tot_point--; + + BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1); + } + } + + mask_layer_shape_ofs += spline->tot_point; + + MEM_freeN(spline->points); + spline->points = new_points; + + ED_mask_select_flush_all(mask); + } + + spline = next_spline; + } + } + + /* TODO: only update edited splines */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_delete(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Delete"; + ot->description = "Delete selected control points or splines"; + ot->idname = "MASK_OT_delete"; + + /* api callbacks */ + ot->invoke = WM_operator_confirm; + ot->exec = delete_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/* *** switch direction *** */ +static int mask_switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + BKE_mask_spline_direction_switch(masklay, spline); + change = TRUE; + } + } + } + + if (change) { + /* TODO: only update this spline */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_switch_direction(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Switch Direction"; + ot->description = "Switch direction of selected splines"; + ot->idname = "MASK_OT_switch_direction"; + + /* api callbacks */ + ot->exec = mask_switch_direction_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/******************** set handle type *********************/ + +static int set_handle_type_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int handle_type = RNA_enum_get(op->ptr, "type"); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + BezTriple *bezt = &point->bezt; + + bezt->h1 = bezt->h2 = handle_type; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_handle_type_set(wmOperatorType *ot) +{ + static EnumPropertyItem editcurve_handle_type_items[] = { + {HD_AUTO, "AUTO", 0, "Auto", ""}, + {HD_VECT, "VECTOR", 0, "Vector", ""}, + {HD_ALIGN, "ALIGNED", 0, "Aligned", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Set Handle Type"; + ot->description = "Set type of handles for selected control points"; + ot->idname = "MASK_OT_handle_type_set"; + + /* api callbacks */ + ot->invoke = WM_menu_invoke; + ot->exec = set_handle_type_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", editcurve_handle_type_items, 1, "Type", "Spline type"); +} + + +/* ********* clear/set restrict view *********/ +static int mask_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int 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; + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_clear(wmOperatorType *ot) +{ + + /* identifiers */ + ot->name = "Clear Restrict View"; + ot->description = "Reveal the layer by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_clear"; + + /* api callbacks */ + ot->exec = mask_hide_view_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +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; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { + continue; + } + + if (!unselected) { + if (ED_mask_layer_select_check(masklay)) { + ED_mask_layer_select_set(masklay, FALSE); + + masklay->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); + } + } + } + else { + if (!ED_mask_layer_select_check(masklay)) { + masklay->restrictflag |= OB_RESTRICT_VIEW; + changed = 1; + if (masklay == BKE_mask_layer_active(mask)) { + BKE_mask_layer_active_set(mask, NULL); + } + } + } + } + + if (changed) { + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_hide_view_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Restrict View"; + ot->description = "Hide the layer by setting the hide flag"; + ot->idname = "MASK_OT_hide_view_set"; + + /* api callbacks */ + ot->exec = mask_hide_view_set_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers"); +} + + +static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int changed = FALSE; + int i; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_SELECT | MASK_RESTRICT_VIEW)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + BezTriple *bezt = &point->bezt; + bezt->weight = 0.0f; + changed = TRUE; + } + } + } + } + + if (changed) { + /* TODO: only update edited splines */ + BKE_mask_update_display(mask, CTX_data_scene(C)->r.cfra); + + WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_feather_weight_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Feather Weight"; + ot->description = "Reset the feather weight to zero"; + ot->idname = "MASK_OT_feather_weight_clear"; + + /* api callbacks */ + ot->exec = mask_feather_weight_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_relationships.c b/source/blender/editors/mask/mask_relationships.c new file mode 100644 index 00000000000..77fe2a71225 --- /dev/null +++ b/source/blender/editors/mask/mask_relationships.c @@ -0,0 +1,172 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_relationships.c + * \ingroup edmask + */ + + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" +#include "BKE_tracking.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_mask.h" /* own include */ + +#include "mask_intern.h" /* own include */ + +static int mask_parent_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + point->parent.id = NULL; + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +void MASK_OT_parent_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Parent"; + ot->description = "Clear the mask's parenting"; + ot->idname = "MASK_OT_parent_clear"; + + /* api callbacks */ + ot->exec = mask_parent_clear_exec; + + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + /* parent info */ + SpaceClip *sc; + MovieClip *clip; + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + MovieTrackingObject *tracking; + /* done */ + + float marker_pos_ofs[2]; + float parmask_pos[2]; + + if ((NULL == (sc = CTX_wm_space_clip(C))) || + (NULL == (clip = sc->clip)) || + (NULL == (track = clip->tracking.act_track)) || + (NULL == (marker = BKE_tracking_get_marker(track, sc->user.framenr))) || + (NULL == (tracking = BKE_tracking_active_object(&clip->tracking)))) + { + return OPERATOR_CANCELLED; + } + + add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset); + + BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs); + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + int i; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + point->parent.id_type = ID_MC; + point->parent.id = &clip->id; + strcpy(point->parent.parent, tracking->name); + strcpy(point->parent.sub_parent, track->name); + + copy_v2_v2(point->parent.parent_orig, parmask_pos); + } + } + } + } + + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; +} + +/** based on #OBJECT_OT_parent_set */ +void MASK_OT_parent_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Make Parent"; + ot->description = "Set the mask's parenting"; + ot->idname = "MASK_OT_parent_set"; + + /* api callbacks */ + //ot->invoke = mask_parent_set_invoke; + ot->exec = mask_parent_set_exec; + + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c new file mode 100644 index 00000000000..55e09529320 --- /dev/null +++ b/source/blender/editors/mask/mask_select.c @@ -0,0 +1,766 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_select.c + * \ingroup edmask + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_rect.h" +#include "BLI_lasso.h" + +#include "BKE_context.h" +#include "BKE_mask.h" + +#include "DNA_mask_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_mask.h" /* own include */ + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "mask_intern.h" /* own include */ + +/* 'check' select */ +int ED_mask_spline_select_check(MaskSpline *spline) +{ + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) + return TRUE; + } + + return FALSE; +} + +int ED_mask_layer_select_check(MaskLayer *masklay) +{ + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + return FALSE; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + return TRUE; + } + } + + return FALSE; +} + +int ED_mask_select_check(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + if (ED_mask_layer_select_check(masklay)) { + return TRUE; + } + } + + return FALSE; +} + +/* 'sel' select */ +void ED_mask_spline_select_set(MaskSpline *spline, const short do_select) +{ + int i; + + if (do_select) + spline->flag |= SELECT; + else + spline->flag &= ~SELECT; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + BKE_mask_point_select_set(point, do_select); + } +} + +void ED_mask_layer_select_set(MaskLayer *masklay, const short do_select) +{ + MaskSpline *spline; + + if (masklay->restrictflag & MASK_RESTRICT_SELECT) { + if (do_select == TRUE) { + return; + } + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + ED_mask_spline_select_set(spline, do_select); + } +} + +void ED_mask_select_toggle_all(Mask *mask, int action) +{ + MaskLayer *masklay; + + if (action == SEL_TOGGLE) { + if (ED_mask_select_check(mask)) + action = SEL_DESELECT; + else + action = SEL_SELECT; + } + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + ED_mask_layer_select_set(masklay, (action == SEL_SELECT) ? TRUE : FALSE); + } +} + +void ED_mask_select_flush_all(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + spline->flag &= ~SELECT; + + /* intentionally _dont_ do this in the masklay loop + * so we clear flags on all splines */ + if (masklay->restrictflag & MASK_RESTRICT_VIEW) { + continue; + } + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *cur_point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(cur_point)) { + spline->flag |= SELECT; + } + else { + int j; + + for (j = 0; j < cur_point->tot_uw; j++) { + if (cur_point->uw[j].flag & SELECT) { + spline->flag |= SELECT; + break; + } + } + } + } + } + } +} + +/******************** toggle selection *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + int action = RNA_enum_get(op->ptr, "action"); + + ED_mask_select_toggle_all(mask, action); + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; +} + +void MASK_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->description = "Change selection of all curve points"; + ot->idname = "MASK_OT_select_all"; + + /* api callbacks */ + ot->exec = select_all_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_all(ot); +} + +/******************** select *********************/ + +static int select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + short extend = RNA_boolean_get(op->ptr, "extend"); + short deselect = RNA_boolean_get(op->ptr, "deselect"); + short toggle = RNA_boolean_get(op->ptr, "toggle"); + + int is_handle = 0; + const float threshold = 19; + + RNA_float_get_array(op->ptr, "location", co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + + if (extend == 0 && deselect == 0 && toggle == 0) + ED_mask_select_toggle_all(mask, SEL_DESELECT); + + if (point) { + + if (is_handle) { + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set_handle(point, FALSE); + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (!MASKPOINT_ISSEL_HANDLE(point)) { + BKE_mask_point_select_set_handle(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set_handle(point, FALSE); + } + } + } + else { + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + BKE_mask_point_select_set(point, TRUE); + } + else if (deselect) { + BKE_mask_point_select_set(point, FALSE); + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (!MASKPOINT_ISSEL_ANY(point)) { + BKE_mask_point_select_set(point, TRUE); + } + else if (toggle) { + BKE_mask_point_select_set(point, FALSE); + } + } + } + + masklay->act_spline = spline; + masklay->act_point = point; + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + else { + MaskSplinePointUW *uw; + + if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) { + + if (extend) { + masklay->act_spline = spline; + masklay->act_point = point; + + if (uw) uw->flag |= SELECT; + } + else if (deselect) { + if (uw) uw->flag &= ~SELECT; + } + else { + masklay->act_spline = spline; + masklay->act_point = point; + + if (uw) { + if (!(uw->flag & SELECT)) { + uw->flag |= SELECT; + } + else if (toggle) { + uw->flag &= ~SELECT; + } + } + } + + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_PASS_THROUGH; +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_mask_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void MASK_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select"; + ot->description = "Select spline points"; + ot->idname = "MASK_OT_select"; + + /* api callbacks */ + ot->exec = select_exec; + ot->invoke = select_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_mouse_select(ot); + + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of vertex in normalized space", -1.0f, 1.0f); +} + + + +/********************** border select operator *********************/ + +static int border_select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + rcti rect; + rctf rectf; + int change = FALSE, mode, extend; + + /* get rectangle from operator */ + rect.xmin = RNA_int_get(op->ptr, "xmin"); + rect.ymin = RNA_int_get(op->ptr, "ymin"); + rect.xmax = RNA_int_get(op->ptr, "xmax"); + rect.ymax = RNA_int_get(op->ptr, "ymax"); + + ED_mask_point_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_mask_point_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + extend = RNA_boolean_get(op->ptr, "extend"); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + if (BLI_in_rctf(&rectf, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1])) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + } + else if (!extend) { + BKE_mask_point_select_set(point, FALSE); + BKE_mask_point_select_set_handle(point, FALSE); + } + + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Border Select"; + ot->description = "Select markers using border selection"; + ot->idname = "MASK_OT_select_border"; + + /* api callbacks */ + ot->invoke = WM_border_select_invoke; + ot->exec = border_select_exec; + ot->modal = WM_border_select_modal; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, TRUE); +} + +static int do_lasso_select_mask(bContext *C, int mcords[][2], short moves, short select) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + rcti rect; + int change = FALSE; + + /* get rectangle from operator */ + BLI_lasso_boundbox(&rect, mcords, moves); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + /* TODO: handles? */ + /* TODO: uw? */ + + float screen_co[2]; + + /* marker in screen coords */ + ED_mask_point_pos__reverse(C, + point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], + &screen_co[0], &screen_co[1]); + + if (BLI_in_rcti(&rect, screen_co[0], screen_co[1]) && + BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) + { + BKE_mask_point_select_set(point, select); + BKE_mask_point_select_set_handle(point, select); + } + + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + } + + return change; +} + +static int clip_lasso_select_exec(bContext *C, wmOperator *op) +{ + int mcords_tot; + int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot); + + if (mcords) { + short select; + + select = !RNA_boolean_get(op->ptr, "deselect"); + do_lasso_select_mask(C, mcords, mcords_tot, select); + + MEM_freeN(mcords); + + return OPERATOR_FINISHED; + } + return OPERATOR_PASS_THROUGH; +} + +void MASK_OT_select_lasso(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Lasso Select"; + ot->description = "Select markers using lasso selection"; + ot->idname = "MASK_OT_select_lasso"; + + /* api callbacks */ + ot->invoke = WM_gesture_lasso_invoke; + ot->modal = WM_gesture_lasso_modal; + ot->exec = clip_lasso_select_exec; + ot->poll = ED_maskedit_mask_poll; + ot->cancel = WM_gesture_lasso_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_collection_runtime(ot->srna, "path", &RNA_OperatorMousePath, "Path", ""); + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", "Deselect rather than select items"); + RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection instead of deselecting everything first"); +} + +/********************** circle select operator *********************/ + +static int mask_spline_point_inside_ellipse(BezTriple *bezt, float offset[2], float ellipse[2]) +{ + /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ + float x, y; + + x = (bezt->vec[1][0] - offset[0]) * ellipse[0]; + y = (bezt->vec[1][1] - offset[1]) * ellipse[1]; + + return x * x + y * y < 1.0f; +} + +static int circle_select_exec(bContext *C, wmOperator *op) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int i; + + SpaceClip *sc = CTX_wm_space_clip(C); + ARegion *ar = CTX_wm_region(C); + int x, y, radius, width, height, mode, change = FALSE; + float zoomx, zoomy, offset[2], ellipse[2]; + + /* get operator properties */ + x = RNA_int_get(op->ptr, "x"); + y = RNA_int_get(op->ptr, "y"); + radius = RNA_int_get(op->ptr, "radius"); + + mode = RNA_int_get(op->ptr, "gesture_mode"); + + /* TODO - make generic! - this is SpaceClip only! */ + /* compute ellipse and position in unified coordinates */ + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + width = height = MAX2(width, height); + + ellipse[0] = width * zoomx / radius; + ellipse[1] = height * zoomy / radius; + + ED_mask_point_pos(C, x, y, &offset[0], &offset[1]); + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + MaskSplinePoint *point_deform = &points_array[i]; + + if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) { + BKE_mask_point_select_set(point, mode == GESTURE_MODAL_SELECT); + BKE_mask_point_select_set_handle(point, mode == GESTURE_MODAL_SELECT); + + change = TRUE; + } + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Circle Select"; + ot->description = "Select markers using circle selection"; + ot->idname = "MASK_OT_select_circle"; + + /* api callbacks */ + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = circle_select_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + MaskSpline *spline; + MaskSplinePoint *point = NULL; + float co[2]; + int do_select = !RNA_boolean_get(op->ptr, "deselect"); + + int is_handle = 0; + const float threshold = 19; + int change = FALSE; + + ED_mask_mouse_pos(C, event, co); + + point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); + + if (point) { + ED_mask_spline_select_set(spline, do_select); + masklay->act_spline = spline; + masklay->act_point = point; + + change = TRUE; + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked_pick(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked"; + ot->idname = "MASK_OT_select_linked_pick"; + ot->description = "(De)select all points linked to the curve under the mouse cursor"; + + /* api callbacks */ + ot->invoke = mask_select_linked_pick_invoke; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "deselect", 0, "Deselect", ""); +} + +static int mask_select_linked_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + + int change = FALSE; + + /* do actual selection */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + if (ED_mask_spline_select_check(spline)) { + ED_mask_spline_select_set(spline, TRUE); + change = TRUE; + } + } + } + + if (change) { + ED_mask_select_flush_all(mask); + + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void MASK_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked All"; + ot->idname = "MASK_OT_select_linked"; + ot->description = "Select all vertices linked to the active mesh"; + + /* api callbacks */ + ot->exec = mask_select_linked_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} diff --git a/source/blender/editors/mask/mask_shapekey.c b/source/blender/editors/mask/mask_shapekey.c new file mode 100644 index 00000000000..8da083ab400 --- /dev/null +++ b/source/blender/editors/mask/mask_shapekey.c @@ -0,0 +1,276 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2012 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mask/mask_shapekey.c + * \ingroup edmask + */ + +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_mask.h" + +#include "DNA_object_types.h" +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mask.h" /* own include */ + +#include "mask_intern.h" /* own include */ + +static int mask_shape_key_insert_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); + change = TRUE; + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_insert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Insert Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_insert"; + + /* api callbacks */ + ot->exec = mask_shape_key_insert_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskLayerShape *masklay_shape; + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame); + + if (masklay_shape) { + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + change = TRUE; + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Shape Key"; + ot->description = ""; + ot->idname = "MASK_OT_shape_key_clear"; + + /* api callbacks */ + ot->exec = mask_shape_key_clear_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +static int mask_shape_key_feather_reset_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + const int frame = CFRA; + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + if (masklay->splines_shapes.first) { + MaskLayerShape *masklay_shape_reset; + MaskLayerShape *masklay_shape; + + /* get the shapekey of the current state */ + masklay_shape_reset = BKE_mask_layer_shape_alloc(masklay, frame); + /* initialize from mask - as if inseting a keyframe */ + BKE_mask_layer_shape_from_mask(masklay, masklay_shape_reset); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + + if (masklay_shape_reset->tot_vert == masklay_shape->tot_vert) { + int i_abs = 0; + int i; + MaskSpline *spline; + MaskLayerShapeElem *shape_ele_src; + MaskLayerShapeElem *shape_ele_dst; + + shape_ele_src = (MaskLayerShapeElem *)masklay_shape_reset->data; + shape_ele_dst = (MaskLayerShapeElem *)masklay_shape->data; + + for (spline = masklay->splines.first; spline; spline = spline->next) { + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + /* TODO - nicer access here */ + shape_ele_dst->value[6] = shape_ele_src->value[6]; + } + + shape_ele_src++; + shape_ele_dst++; + + i_abs++; + } + } + + } + else { + // printf("%s: skipping\n", __func__); + } + + change = TRUE; + } + + BKE_mask_layer_shape_free(masklay_shape_reset); + } + } + + if (change) { + WM_event_add_notifier(C, NC_MASK | ND_DATA, mask); + DAG_id_tag_update(&mask->id, 0); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } +} + +void MASK_OT_shape_key_feather_reset(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Feather Reset Animation"; + ot->description = "Resets fearther weights on all selected points animation values"; + ot->idname = "MASK_OT_shape_key_feather_reset"; + + /* api callbacks */ + ot->exec = mask_shape_key_feather_reset_exec; + ot->poll = ED_maskedit_mask_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + + +/* *** Shape Key Utils *** */ + +void ED_mask_layer_shape_auto_key(MaskLayer *masklay, const int frame) +{ + MaskLayerShape *masklay_shape; + + masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, frame); + BKE_mask_layer_shape_from_mask(masklay, masklay_shape); +} + +int ED_mask_layer_shape_auto_key_all(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} + +int ED_mask_layer_shape_auto_key_select(Mask *mask, const int frame) +{ + MaskLayer *masklay; + int change = FALSE; + + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + + if (!ED_mask_layer_select_check(masklay)) { + continue; + } + + ED_mask_layer_shape_auto_key(masklay, frame); + change = TRUE; + } + + return change; +} diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 6bbcd1d253e..f154aec2eb4 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2247,7 +2247,7 @@ static int find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, Li ListBase *chain; BMVert *v; BMIter iter; - int nh, nf, i, j, k, m, ax, ay, ok, sep, bestsep; + int nh, nf, i, j, k, m, ax, ay, ok, sep = 0 /* Quite warnings */, bestsep; int besti[2], bestj[2]; float d, bestd; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index 7298153791e..185c804661d 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -86,7 +86,7 @@ /* ringsel operator */ /* struct for properties used while drawing */ -typedef struct tringselOpData { +typedef struct RingSelOpData { ARegion *ar; /* region that ringsel was activated in */ void *draw_handle; /* for drawing preview loop */ @@ -102,13 +102,13 @@ typedef struct tringselOpData { int extend; int do_cut; -} tringselOpData; +} RingSelOpData; /* modal loop selection drawing callback */ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) { View3D *v3d = CTX_wm_view3d(C); - tringselOpData *lcd = arg; + RingSelOpData *lcd = arg; int i; if (lcd->totedge > 0) { @@ -176,7 +176,7 @@ static void edgering_find_order(BMEdge *lasteed, BMEdge *eed, } } -static void edgering_sel(tringselOpData *lcd, int previewlines, int select) +static void edgering_sel(RingSelOpData *lcd, int previewlines, int select) { BMEditMesh *em = lcd->em; BMEdge *startedge = lcd->eed; @@ -290,7 +290,7 @@ static void edgering_sel(tringselOpData *lcd, int previewlines, int select) lcd->totedge = tot; } -static void ringsel_find_edge(tringselOpData *lcd, int cuts) +static void ringsel_find_edge(RingSelOpData *lcd, int cuts) { if (lcd->eed) { edgering_sel(lcd, cuts, 0); @@ -304,7 +304,7 @@ static void ringsel_find_edge(tringselOpData *lcd, int cuts) static void ringsel_finish(bContext *C, wmOperator *op) { - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; int cuts = RNA_int_get(op->ptr, "number_cuts"); if (lcd->eed) { @@ -350,7 +350,7 @@ static void ringsel_finish(bContext *C, wmOperator *op) /* called when modal loop selection is done... */ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op) { - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; /* deactivate the extra drawing stuff in 3D-View */ ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle); @@ -368,10 +368,10 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op) /* called when modal loop selection gets set up... */ static int ringsel_init(bContext *C, wmOperator *op, int do_cut) { - tringselOpData *lcd; + RingSelOpData *lcd; /* alloc new customdata */ - lcd = op->customdata = MEM_callocN(sizeof(tringselOpData), "ringsel Modal Op Data"); + lcd = op->customdata = MEM_callocN(sizeof(RingSelOpData), "ringsel Modal Op Data"); /* assign the drawing handle for drawing preview line... */ lcd->ar = CTX_wm_region(C); @@ -402,7 +402,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op) static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) { Object *obedit = CTX_data_edit_object(C); - tringselOpData *lcd; + RingSelOpData *lcd; BMEdge *edge; int dist = 75; @@ -434,7 +434,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) { int cuts = RNA_int_get(op->ptr, "number_cuts"); - tringselOpData *lcd = op->customdata; + RingSelOpData *lcd = op->customdata; int show_cuts = 0; view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index b7c921cd8af..09475db0ed2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -3676,14 +3676,14 @@ enum { SRT_REVERSE, /* Reverse current order of selected elements. */ }; -typedef struct bmelemsort { +typedef struct BMElemSort { float srt; /* Sort factor */ int org_idx; /* Original index of this element _in its mempool_ */ -} bmelemsort; +} BMElemSort; static int bmelemsort_comp(const void *v1, const void *v2) { - const bmelemsort *x1 = v1, *x2 = v2; + const BMElemSort *x1 = v1, *x2 = v2; return (x1->srt > x2->srt) - (x1->srt < x2->srt); } @@ -3704,7 +3704,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const /* In all five elements below, 0 = vertices, 1 = edges, 2 = faces. */ /* Just to mark protected elements. */ char *pblock[3] = {NULL, NULL, NULL}, *pb; - bmelemsort *sblock[3] = {NULL, NULL, NULL}, *sb; + BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb; int *map[3] = {NULL, NULL, NULL}, *mp; int totelem[3] = {0, 0, 0}, tot; int affected[3] = {0, 0, 0}, aff; @@ -3733,7 +3733,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3752,7 +3752,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -3772,7 +3772,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3806,7 +3806,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3822,7 +3822,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -3841,7 +3841,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3862,7 +3862,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const /* Faces only! */ else if (action == SRT_MATERIAL && totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -3966,7 +3966,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const * enabling/disabling an element type. */ BLI_srandom(seed); pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -3983,7 +3983,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { BLI_srandom(seed); pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -4000,7 +4000,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { BLI_srandom(seed); pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -4018,7 +4018,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const else if (action == SRT_REVERSE) { if (totelem[0]) { pb = pblock[0] = MEM_callocN(sizeof(char) * totelem[0], "sort_bmelem vert pblock"); - sb = sblock[0] = MEM_callocN(sizeof(bmelemsort) * totelem[0], "sort_bmelem vert sblock"); + sb = sblock[0] = MEM_callocN(sizeof(BMElemSort) * totelem[0], "sort_bmelem vert sblock"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { if (BM_elem_flag_test(ve, flag)) { @@ -4034,7 +4034,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[1]) { pb = pblock[1] = MEM_callocN(sizeof(char) * totelem[1], "sort_bmelem edge pblock"); - sb = sblock[1] = MEM_callocN(sizeof(bmelemsort) * totelem[1], "sort_bmelem edge sblock"); + sb = sblock[1] = MEM_callocN(sizeof(BMElemSort) * totelem[1], "sort_bmelem edge sblock"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { if (BM_elem_flag_test(ed, flag)) { @@ -4050,7 +4050,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const if (totelem[2]) { pb = pblock[2] = MEM_callocN(sizeof(char) * totelem[2], "sort_bmelem face pblock"); - sb = sblock[2] = MEM_callocN(sizeof(bmelemsort) * totelem[2], "sort_bmelem face sblock"); + sb = sblock[2] = MEM_callocN(sizeof(BMElemSort) * totelem[2], "sort_bmelem face sblock"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { if (BM_elem_flag_test(fa, flag)) { @@ -4086,11 +4086,11 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const sb = sblock[j]; if (pb && sb && !map[j]) { char *p_blk; - bmelemsort *s_blk; + BMElemSort *s_blk; tot = totelem[j]; aff = affected[j]; - qsort(sb, aff, sizeof(bmelemsort), bmelemsort_comp); + qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp); mp = map[j] = MEM_mallocN(sizeof(int) * tot, "sort_bmelem map"); p_blk = pb + tot - 1; @@ -4498,13 +4498,18 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) BevelData *opdata; float mlen[2]; - if (!edbm_bevel_init(C, op, TRUE)) + if (!edbm_bevel_init(C, op, TRUE)) { return OPERATOR_CANCELLED; + } - /* initialize mouse values */ opdata = op->customdata; - calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); + /* initialize mouse values */ + if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + /* in this case the tool will likely do nothing, + * ideally this will never happen and should be checked for above */ + opdata->mcenter[0] = opdata->mcenter[1] = 0; + } mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); @@ -4795,8 +4800,12 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata = op->customdata; - calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); /* initialize mouse values */ + if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + /* in this case the tool will likely do nothing, + * ideally this will never happen and should be checked for above */ + opdata->mcenter[0] = opdata->mcenter[1] = 0; + } mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); @@ -4830,13 +4839,11 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; if (opdata->modify_depth) { - amount = opdata->old_depth + (len_v2(mdiff) - - opdata->initial_length) / opdata->initial_length; + amount = opdata->old_depth + (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; RNA_float_set(op->ptr, "depth", amount); } else { - amount = opdata->old_thickness - (len_v2(mdiff) - - opdata->initial_length) / opdata->initial_length; + amount = opdata->old_thickness - (len_v2(mdiff) - opdata->initial_length) / opdata->initial_length; amount = MAX2(amount, 0.0f); RNA_float_set(op->ptr, "thickness", amount); diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 24dd56a4834..3d7dd01bf30 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -180,7 +180,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) short changed = 0; const int unselected = RNA_boolean_get(op->ptr, "unselected"); - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (!unselected) { if (base->flag & SELECT) { @@ -240,7 +240,7 @@ static int object_hide_render_clear_exec(bContext *C, wmOperator *UNUSED(op)) short changed = 0; /* XXX need a context loop to handle such cases */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->restrictflag & OB_RESTRICT_RENDER) { ob->restrictflag &= ~OB_RESTRICT_RENDER; @@ -275,7 +275,7 @@ static int object_hide_render_set_exec(bContext *C, wmOperator *op) { const int unselected = RNA_boolean_get(op->ptr, "unselected"); - CTX_DATA_BEGIN (C, Base *, base, visible_bases) + CTX_DATA_BEGIN(C, Base *, base, visible_bases) { if (!unselected) { if (base->flag & SELECT) { @@ -1114,7 +1114,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene) ListBase targets = {NULL, NULL}; /* loop over objects in scene */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { /* set flag to force recalc, then grab path(s) from object */ ob->avs.recalc |= ANIMVIZ_RECALC_PATHS; @@ -1157,7 +1157,7 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op) int end = RNA_int_get(op->ptr, "end_frame"); /* set up path data for bones being calculated */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { bAnimVizSettings *avs = &ob->avs; @@ -1196,9 +1196,9 @@ void OBJECT_OT_paths_calculate(wmOperatorType *ot) /* properties */ RNA_def_int(ot->srna, "start_frame", 1, MINAFRAME, MAXFRAME, "Start", - "First frame to calculate object paths on", MINFRAME, MAXFRAME/2.0); + "First frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0); RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", - "Last frame to calculate object paths on", MINFRAME, MAXFRAME/2.0); + "Last frame to calculate object paths on", MINFRAME, MAXFRAME / 2.0); } /* --------- */ @@ -1231,7 +1231,7 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* TODO: this should probably check for existing paths */ /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } /* --------- */ @@ -1240,7 +1240,7 @@ void OBJECT_OT_paths_update(wmOperatorType *ot) void ED_objects_clear_paths(bContext *C) { /* loop over objects in scene */ - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->mpath) { animviz_free_motionpath(ob->mpath); @@ -1288,7 +1288,7 @@ static int shade_smooth_exec(bContext *C, wmOperator *op) int clear = (strcmp(op->idname, "OBJECT_OT_shade_flat") == 0); int done = FALSE; - CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects) { if (ob->type == OB_MESH) { @@ -1666,10 +1666,12 @@ static EnumPropertyItem game_properties_copy_operations[] = { {COPY_PROPERTIES_REPLACE, "REPLACE", 0, "Replace Properties", ""}, {COPY_PROPERTIES_MERGE, "MERGE", 0, "Merge Properties", ""}, {COPY_PROPERTIES_COPY, "COPY", 0, "Copy a Property", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; -static EnumPropertyItem gameprops_items[]= { - {0, NULL, 0, NULL, NULL}}; +static EnumPropertyItem gameprops_items[] = { + {0, NULL, 0, NULL, NULL} +}; static EnumPropertyItem *gameprops_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -1706,7 +1708,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) prop = BLI_findlink(&ob->prop, propid - 1); if (prop) { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) set_ob_property(ob_iter, prop); @@ -1715,7 +1717,7 @@ static int game_property_copy_exec(bContext *C, wmOperator *op) } else { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { if (type == COPY_PROPERTIES_REPLACE) @@ -1756,7 +1758,7 @@ void OBJECT_OT_game_property_copy(wmOperatorType *ot) static int game_property_clear_exec(bContext *C, wmOperator *UNUSED(op)) { - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { free_properties(&ob_iter->prop); } @@ -1786,7 +1788,7 @@ static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_active_context(C); - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { /* first: free all logic */ @@ -1843,7 +1845,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_active_context(C); - CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) + CTX_DATA_BEGIN(C, Object *, ob_iter, selected_editable_objects) { if (ob != ob_iter) { ob_iter->gameflag = ob->gameflag; diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index f6e8ccf4ec9..0a9944debe1 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -344,18 +344,17 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int bp = findnearestLattvert(&vc, mval, 1); if (bp) { - if (extend) { - bp->f1 |= SELECT; - } - else if (deselect) { - bp->f1 &= ~SELECT; - } + if (extend) { + bp->f1 |= SELECT; + } + else if (deselect) { + bp->f1 &= ~SELECT; + } else if (toggle) { bp->f1 ^= SELECT; /* swap */ } - else - { - ED_setflagsLatt(vc.obedit, 0); + else { + ED_setflagsLatt(vc.obedit, 0); bp->f1 |= SELECT; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 7dd17e59f6f..d6b5fb9fc10 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -642,8 +642,10 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi BLI_remlink(&ob->modifiers, md); modifier_free(md); - /* ensure mesh paint mask layer remains after applying */ - ED_sculpt_mask_layers_ensure(ob, NULL); + if (ob->type == OB_MESH) { + /* ensure mesh paint mask layer remains after applying */ + ED_sculpt_mask_layers_ensure(ob, NULL); + } return 1; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 6e653eff57c..d0a93302b7f 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -441,6 +441,14 @@ void ED_keymap_proportional_obmode(struct wmKeyConfig *UNUSED(keyconf), struct w RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_objects"); } +void ED_keymap_proportional_maskmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_edit_mask"); +} + void ED_keymap_proportional_editmode(struct wmKeyConfig *UNUSED(keyconf), struct wmKeyMap *keymap, const short do_connected) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 85b9d78c657..fc0aa39e733 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1929,6 +1929,7 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *even DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C)); + WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING, ma); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index fa86f089387..89f018a1b76 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -708,10 +708,11 @@ void OBJECT_OT_select_grouped(wmOperatorType *ot) static int object_select_by_layer_exec(bContext *C, wmOperator *op) { unsigned int layernum; - short extend; + short extend, match; extend = RNA_boolean_get(op->ptr, "extend"); layernum = RNA_int_get(op->ptr, "layers"); + match = RNA_enum_get(op->ptr, "match"); if (extend == 0) { CTX_DATA_BEGIN (C, Base *, base, visible_bases) @@ -723,7 +724,14 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, Base *, base, visible_bases) { - if (base->lay == (1 << (layernum - 1))) + int ok = 0; + + if (match == 1) /* exact */ + ok = (base->lay == (1 << (layernum - 1))); + else /* shared layers */ + ok = (base->lay & (1 << (layernum - 1))); + + if (ok) ED_base_object_select(base, BA_SELECT); } CTX_DATA_END; @@ -736,6 +744,12 @@ static int object_select_by_layer_exec(bContext *C, wmOperator *op) void OBJECT_OT_select_by_layer(wmOperatorType *ot) { + static EnumPropertyItem match_items[] = { + {1, "EXACT", 0, "Exact Match", ""}, + {2, "SHARED", 0, "Shared Layers", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ ot->name = "Select by Layer"; ot->description = "Select all visible objects on a layer"; @@ -750,6 +764,7 @@ void OBJECT_OT_select_by_layer(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ + RNA_def_enum(ot->srna, "match", match_items, 0, "Match", ""); RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); RNA_def_int(ot->srna, "layers", 1, 1, 20, "Layer", "", 1, 20); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 356ede878b5..8fa3c6f992f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -288,11 +288,12 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) else if (scene->r.scemode & R_SINGLE_LAYER) spos += sprintf(spos, "Single Layer | "); + spos += sprintf(spos, "Frame:%d ", (scene->r.cfra)); + if (rs->statstr) { - spos += sprintf(spos, "%s ", rs->statstr); + spos += sprintf(spos, "| %s ", rs->statstr); } else { - spos += sprintf(spos, "Fra:%d ", (scene->r.cfra)); if (rs->totvert) spos += sprintf(spos, "Ve:%d ", rs->totvert); if (rs->totface) spos += sprintf(spos, "Fa:%d ", rs->totface); if (rs->tothalo) spos += sprintf(spos, "Ha:%d ", rs->tothalo); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 8baca253519..4e98d2ae967 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "DNA_meta_types.h" #include "DNA_mesh_types.h" +#include "DNA_mask_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" @@ -59,6 +60,7 @@ #include "BKE_screen.h" #include "BKE_tessmesh.h" #include "BKE_sound.h" +#include "BKE_mask.h" #include "WM_api.h" #include "WM_types.h" @@ -71,6 +73,7 @@ #include "ED_screen_types.h" #include "ED_keyframes_draw.h" #include "ED_view3d.h" +#include "ED_clip.h" #include "RNA_access.h" #include "RNA_define.h" @@ -453,6 +456,13 @@ int ED_operator_editmball(bContext *C) return 0; } +int ED_operator_mask(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + return ED_space_clip_show_maskedit(sc); +} + /* *************************** action zone operator ************************** */ /* operator state vars used: @@ -1937,7 +1947,17 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) if (ob) ob_to_keylist(&ads, ob, &keys, NULL); - + + { + SpaceClip *sc = CTX_wm_space_clip(C); + if (sc) { + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + mask_to_keylist(&ads, masklay, &keys); + } + } + } + /* build linked-list for searching */ BLI_dlrbTree_linkedlist_sync(&keys); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index b5d44676cf6..5ca436b07b2 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -333,7 +333,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, float location[3]) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); float window[2]; int hit; @@ -503,7 +503,7 @@ static void paint_cursor_on_hit(Sculpt *sd, Brush *brush, ViewContext *vc, static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); ViewContext vc; float final_radius; @@ -605,7 +605,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) void paint_cursor_start(bContext *C, int (*poll)(bContext *C)) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); if (p && !p->paint_cursor) p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index cd8b9164862..89c328e71d8 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -265,7 +265,7 @@ static void get_pbvh_nodes(PBVH *pbvh, float clip_planes[4][4], PartialVisArea mode) { - BLI_pbvh_SearchCallback cb; + BLI_pbvh_SearchCallback cb = NULL; /* select search callback */ switch (mode) { @@ -277,7 +277,6 @@ static void get_pbvh_nodes(PBVH *pbvh, break; case PARTIALVIS_ALL: case PARTIALVIS_MASKED: - cb = NULL; break; } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ed86cb67687..4dee83dbb82 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5215,7 +5215,7 @@ static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata) Scene *scene = CTX_data_scene(C); //Brush *brush= image_paint_brush(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); if (paint && brush && paint->flags & PAINT_SHOW_BRUSH) { @@ -5420,13 +5420,12 @@ void PAINT_OT_grab_clone(wmOperatorType *ot) static int sample_color_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); Brush *brush = image_paint_brush(C); ARegion *ar = CTX_wm_region(C); int location[2]; RNA_int_get_array(op->ptr, "location", location); - paint_sample_color(scene, ar, location[0], location[1]); + paint_sample_color(C, ar, location[0], location[1]); WM_event_add_notifier(C, NC_BRUSH | NA_EDITED, brush); diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index de149bf2806..794e7755636 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -137,7 +137,7 @@ float paint_get_tex_pixel(struct Brush *br, float u, float v); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); -void paint_sample_color(struct Scene *scene, struct ARegion *ar, int x, int y); +void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y); void BRUSH_OT_curve_preset(struct wmOperatorType *ot); void PAINT_OT_face_select_linked(struct wmOperatorType *ot); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 298ecf764d6..e309bdb99cb 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -61,16 +61,16 @@ #include <stdlib.h> static void mask_flood_fill_set_elem(float *elem, - PaintMaskFloodMode mode, - float value) + PaintMaskFloodMode mode, + float value) { switch (mode) { - case PAINT_MASK_FLOOD_VALUE: - (*elem) = value; - break; - case PAINT_MASK_INVERT: - (*elem) = 1.0f - (*elem); - break; + case PAINT_MASK_FLOOD_VALUE: + (*elem) = value; + break; + case PAINT_MASK_INVERT: + (*elem) = 1.0f - (*elem); + break; } } diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 23d1c0090a0..7df6a893b5c 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -60,7 +60,7 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) { /*int type = RNA_enum_get(op->ptr, "type");*/ - Paint *paint = paint_get_active(CTX_data_scene(C)); + Paint *paint = paint_get_active_from_context(C); struct Brush *br = paint_brush(paint); if (br) @@ -68,7 +68,7 @@ static int brush_add_exec(bContext *C, wmOperator *UNUSED(op)) else br = BKE_brush_add("Brush"); - paint_brush_set(paint_get_active(CTX_data_scene(C)), br); + paint_brush_set(paint, br); return OPERATOR_FINISHED; } @@ -91,7 +91,7 @@ static void BRUSH_OT_add(wmOperatorType *ot) static int brush_scale_size_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); struct Brush *brush = paint_brush(paint); // Object *ob= CTX_data_active_object(C); float scalar = RNA_float_get(op->ptr, "scalar"); @@ -173,7 +173,7 @@ static void PAINT_OT_vertex_color_set(wmOperatorType *ot) static int brush_reset_exec(bContext *C, wmOperator *UNUSED(op)) { - Paint *paint = paint_get_active(CTX_data_scene(C)); + Paint *paint = paint_get_active_from_context(C); struct Brush *brush = paint_brush(paint); Object *ob = CTX_data_active_object(C); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 987ab932fd6..b53edeadb51 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -100,10 +100,11 @@ typedef struct PaintStroke { /*** Cursor ***/ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata) { - Brush *brush = paint_brush(paint_get_active(CTX_data_scene(C))); + Paint *paint = paint_get_active_from_context(C); + Brush *brush = paint_brush(paint); PaintStroke *stroke = customdata; - glColor4ubv(paint_get_active(CTX_data_scene(C))->paint_cursor_col); + glColor4ubv(paint->paint_cursor_col); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); @@ -141,7 +142,7 @@ static float event_tablet_data(wmEvent *event, int *pen_flip) static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) { Scene *scene = CTX_data_scene(C); - Paint *paint = paint_get_active(scene); + Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; float mouse[3]; @@ -202,10 +203,10 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2], if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) && !ELEM4(stroke->brush->sculpt_tool, - SCULPT_TOOL_GRAB, - SCULPT_TOOL_THUMB, - SCULPT_TOOL_ROTATE, - SCULPT_TOOL_SNAKE_HOOK) && + SCULPT_TOOL_GRAB, + SCULPT_TOOL_THUMB, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_SNAKE_HOOK) && !(stroke->brush->flag & BRUSH_ANCHORED) && !(stroke->brush->flag & BRUSH_RESTORE_MESH)) { @@ -281,7 +282,7 @@ PaintStroke *paint_stroke_new(bContext *C, { PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke"); - stroke->brush = paint_brush(paint_get_active(CTX_data_scene(C))); + stroke->brush = paint_brush(paint_get_active_from_context(C)); view3d_set_viewcontext(C, &stroke->vc); view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats); @@ -358,12 +359,12 @@ struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf) } static void paint_stroke_add_sample(const Paint *paint, - PaintStroke *stroke, - float x, float y) + PaintStroke *stroke, + float x, float y) { PaintSample *sample = &stroke->samples[stroke->cur_sample]; int max_samples = MIN2(PAINT_MAX_INPUT_SAMPLES, - MAX2(paint->num_input_samples, 1)); + MAX2(paint->num_input_samples, 1)); sample->mouse[0] = x; sample->mouse[1] = y; @@ -376,7 +377,7 @@ static void paint_stroke_add_sample(const Paint *paint, } static void paint_stroke_sample_average(const PaintStroke *stroke, - PaintSample *average) + PaintSample *average) { int i; @@ -394,7 +395,7 @@ static void paint_stroke_sample_average(const PaintStroke *stroke, int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); PaintStroke *stroke = op->customdata; PaintSample sample_average; float mouse[2]; @@ -518,7 +519,7 @@ void paint_stroke_set_mode_data(PaintStroke *stroke, void *mode_data) int paint_poll(bContext *C) { - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); Object *ob = CTX_data_active_object(C); return p && ob && paint_brush(p) && diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 4c374674c9a..082e40f8e4c 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -333,9 +333,9 @@ int imapaint_pick_face(ViewContext *vc, const int mval[2], unsigned int *index, } /* used for both 3d view and image window */ -void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf */ +void paint_sample_color(const bContext *C, ARegion *ar, int x, int y) /* frontbuf */ { - Brush *br = paint_brush(paint_get_active(scene)); + Brush *br = paint_brush(paint_get_active_from_context(C)); unsigned int col; char *cp; @@ -357,7 +357,7 @@ void paint_sample_color(Scene *scene, ARegion *ar, int x, int y) /* frontbuf static int brush_curve_preset_exec(bContext *C, wmOperator *op) { - Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); + Brush *br = paint_brush(paint_get_active_from_context(C)); BKE_brush_curve_preset(br, RNA_enum_get(op->ptr, "shape")); return OPERATOR_FINISHED; @@ -365,7 +365,7 @@ static int brush_curve_preset_exec(bContext *C, wmOperator *op) static int brush_curve_preset_poll(bContext *C) { - Brush *br = paint_brush(paint_get_active(CTX_data_scene(C))); + Brush *br = paint_brush(paint_get_active_from_context(C)); return br && br->curve; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index eb79989b90b..3c37ad8cf2a 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2461,6 +2461,8 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) } DAG_id_tag_update(ob->data, 0); + + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } @@ -2622,10 +2624,10 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) * - revise whether op->customdata should be added in object, in set_vpaint */ -typedef struct polyfacemap_e { - struct polyfacemap_e *next, *prev; +typedef struct PolyFaceMap { + struct PolyFaceMap *next, *prev; int facenr; -} polyfacemap_e; +} PolyFaceMap; typedef struct VPaintData { ViewContext vc; @@ -2646,7 +2648,7 @@ typedef struct VPaintData { static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) { MFace *mf; - polyfacemap_e *e; + PolyFaceMap *e; int *origIndex; int i; @@ -2665,7 +2667,7 @@ static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me) if (*origIndex == ORIGINDEX_NONE) continue; - e = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(polyfacemap_e)); + e = BLI_memarena_alloc(vd->polyfacemap_arena, sizeof(PolyFaceMap)); e->facenr = i; BLI_addtail(&vd->polyfacemap[*origIndex], e); @@ -2782,7 +2784,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Object *ob, MCol *mc; MLoop *ml; MLoopCol *mlc; - polyfacemap_e *e; + PolyFaceMap *e; unsigned int *lcol = ((unsigned int *)me->mloopcol) + mpoly->loopstart; unsigned int *lcolorig = ((unsigned int *)vp->vpaint_prev) + mpoly->loopstart; float alpha; @@ -2954,6 +2956,8 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) { ToolSettings *ts = CTX_data_tool_settings(C); struct VPaintData *vpd = paint_stroke_mode_data(stroke); + ViewContext *vc = &vpd->vc; + Object *ob = vc->obact; if (vpd->vertexcosnos) MEM_freeN(vpd->vertexcosnos); @@ -2966,6 +2970,8 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) BLI_memarena_free(vpd->polyfacemap_arena); } + 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 7b8337ff957..66ad05aec7e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -753,8 +753,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], else if (ss->texcache) { float rotation = -mtex->rot; float symm_point[3], point_2d[2]; - float x, y; - float radius; + float x = 0.0f, y = 0.0f; /* Quite warnings */ + float radius = 1.0f; /* Quite warnings */ /* if the active area is being applied for symmetry, flip it * across the symmetry axis and rotate it back to the original @@ -981,8 +981,8 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod /* Calculate primary direction of movement for many brushes */ static void calc_sculpt_normal(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode, - float an[3]) + PBVHNode **nodes, int totnode, + float an[3]) { const Brush *brush = paint_brush(&sd->paint); const SculptSession *ss = ob->sculpt; @@ -990,8 +990,8 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, switch (brush->sculpt_plane) { case SCULPT_DISP_DIR_VIEW: ED_view3d_global_to_vector(ss->cache->vc->rv3d, - ss->cache->vc->rv3d->twmat[3], - an); + ss->cache->vc->rv3d->twmat[3], + an); break; case SCULPT_DISP_DIR_X: @@ -1021,7 +1021,7 @@ static void calc_sculpt_normal(Sculpt *sd, Object *ob, } static void update_sculpt_normal(Sculpt *sd, Object *ob, - PBVHNode **nodes, int totnode) + PBVHNode **nodes, int totnode) { const Brush *brush = paint_brush(&sd->paint); StrokeCache *cache = ob->sculpt->cache; @@ -1056,7 +1056,7 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) } static void calc_brush_local_mat(const Brush *brush, Object *ob, - float local_mat[4][4]) + float local_mat[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; @@ -1105,10 +1105,10 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) StrokeCache *cache = ob->sculpt->cache; if (cache->mirror_symmetry_pass == 0 && - cache->radial_symmetry_pass == 0) + cache->radial_symmetry_pass == 0) { calc_brush_local_mat(paint_brush(&sd->paint), ob, - cache->brush_local_mat); + cache->brush_local_mat); } } @@ -1413,6 +1413,7 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, SculptSession *ss = ob->sculpt; const int max_iterations = 4; const float fract = 1.0f / max_iterations; + PBVHType type = BLI_pbvh_type(ss->pbvh); int iteration, n, count; float last; @@ -1421,16 +1422,25 @@ static void smooth(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, count = (int)(bstrength * max_iterations); last = max_iterations * (bstrength - count * fract); + if (type == PBVH_FACES && !ss->pmap) { + BLI_assert(!"sculpt smooth: pmap missing"); + return; + } + for (iteration = 0; iteration <= count; ++iteration) { + float strength = (iteration != count) ? 1.0f : last; + #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (n = 0; n < totnode; n++) { - if (ss->multires) { - do_multires_smooth_brush(sd, ss, nodes[n], - iteration != count ? 1.0f : last, smooth_mask); - } - else if (ss->pmap) { - do_mesh_smooth_brush(sd, ss, nodes[n], - iteration != count ? 1.0f : last, smooth_mask); + switch(type) { + case PBVH_GRIDS: + do_multires_smooth_brush(sd, ss, nodes[n], strength, + smooth_mask); + break; + case PBVH_FACES: + do_mesh_smooth_brush(sd, ss, nodes[n], strength, + smooth_mask); + break; } } @@ -3571,6 +3581,21 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sd->special_rotation = cache->special_rotation; } +/* Returns true iff any of the smoothing modes are active (currently + one of smooth brush, autosmooth, mask smooth, or shift-key + smooth) */ +static int sculpt_any_smooth_mode(const Brush *brush, + StrokeCache *cache, + int stroke_mode) +{ + return ((stroke_mode == BRUSH_STROKE_SMOOTH) || + (cache && cache->alt_smooth) || + (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || + (brush->autosmooth_factor > 0) || + ((brush->sculpt_tool == SCULPT_TOOL_MASK) && + (brush->mask_tool == BRUSH_MASK_SMOOTH))); +} + static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) { SculptSession *ss = ob->sculpt; @@ -3579,7 +3604,8 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Brush *brush = paint_brush(&sd->paint); - sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH); + sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, + sculpt_any_smooth_mode(brush, ss->cache, 0)); } } @@ -3689,11 +3715,7 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op) view3d_operator_needs_opengl(C); sculpt_brush_init_tex(scene, sd, ss); - is_smooth |= mode == BRUSH_STROKE_SMOOTH; - is_smooth |= brush->sculpt_tool == SCULPT_TOOL_SMOOTH; - is_smooth |= ((brush->sculpt_tool == SCULPT_TOOL_MASK) && - (brush->mask_tool == BRUSH_MASK_SMOOTH)); - + is_smooth = sculpt_any_smooth_mode(brush, NULL, mode); sculpt_update_mesh_elements(scene, sd, ob, is_smooth); return 1; diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index af7f3bd4aed..9827ffdc324 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -676,7 +676,7 @@ static int sound_poll(bContext *C) { Editing *ed = CTX_data_scene(C)->ed; - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return 0; return 1; @@ -689,7 +689,7 @@ static int sound_pack_exec(bContext *C, wmOperator *op) Editing *ed = CTX_data_scene(C)->ed; bSound *sound; - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return OPERATOR_CANCELLED; sound = ed->act_seq->sound; @@ -751,7 +751,7 @@ static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even if (RNA_struct_property_is_set(op->ptr, "id")) return sound_unpack_exec(C, op); - if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_SOUND) + if (!ed || !ed->act_seq || ed->act_seq->type != SEQ_TYPE_SOUND_RAM) return OPERATOR_CANCELLED; sound = ed->act_seq->sound; diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 3961e566f80..edec57d9e93 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -236,8 +236,8 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) switch (ale->type) { case ANIMTYPE_SUMMARY: { - // FIXME: hardcoded colors - reddish color from NLA - glColor4f(0.8f, 0.2f, 0.0f, 0.4f); + /* reddish color from NLA */ + UI_ThemeColor4(TH_ANIM_ACTIVE); } break; @@ -290,6 +290,18 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) else glColor4ub(col2[0], col2[1], col2[2], 0x44); glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF); } + else if (ac->datatype == ANIMCONT_MASK) { + /* TODO --- this is a copy of gpencil */ + /* frames less than one get less saturated background */ + if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x22); + else glColor4ub(col2[0], col2[1], col2[2], 0x22); + glRectf(0.0f, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmin, (float)y + ACHANNEL_HEIGHT_HALF); + + /* frames one and higher get a saturated background */ + if (sel) glColor4ub(col1[0], col1[1], col1[2], 0x44); + else glColor4ub(col2[0], col2[1], col2[2], 0x44); + glRectf(v2d->cur.xmin, (float)y - ACHANNEL_HEIGHT_HALF, v2d->cur.xmax + EXTRA_SCROLL_PAD, (float)y + ACHANNEL_HEIGHT_HALF); + } } } @@ -340,6 +352,9 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) case ALE_GPFRAME: draw_gpl_channel(v2d, ads, ale->data, y); break; + case ALE_MASKLAY: + draw_masklay_channel(v2d, ads, ale->data, y); + break; } } } diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 0c32ebe549d..b5cd49cc15c 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -44,6 +44,7 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -64,6 +65,7 @@ #include "ED_screen.h" #include "ED_transform.h" #include "ED_markers.h" +#include "ED_mask.h" #include "WM_api.h" #include "WM_types.h" @@ -256,6 +258,19 @@ static void get_keyframe_extents(bAnimContext *ac, float *min, float *max, const *max = MAX2(*max, gpf->framenum); } } + else if (ale->datatype == ALE_MASKLAY) { + MaskLayer *masklay = ale->data; + MaskLayerShape *masklay_shape; + + /* find mask layer which is less than or equal to cframe */ + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + *min = MIN2(*min, masklay_shape->frame); + *max = MAX2(*max, masklay_shape->frame); + } + } else { FCurve *fcu = (FCurve *)ale->key_data; float tmin, tmax; @@ -476,11 +491,16 @@ static int actkeys_copy_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* copy keyframes */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { // FIXME... BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil mode"); return OPERATOR_CANCELLED; } + else if (ac.datatype == ANIMCONT_MASK) { + // FIXME... + BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for mask mode"); + return OPERATOR_CANCELLED; + } else { if (copy_action_keys(&ac)) { BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer"); @@ -521,9 +541,9 @@ static int actkeys_paste_exec(bContext *C, wmOperator *op) ac.reports = op->reports; /* paste keyframes */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { // FIXME... - BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil mode"); + BKE_report(op->reports, RPT_ERROR, "Keyframe pasting is not available for Grease Pencil or Mask mode"); return OPERATOR_CANCELLED; } else { @@ -625,7 +645,7 @@ static int actkeys_insertkey_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_CANCELLED; /* what channels to affect? */ @@ -671,7 +691,7 @@ static void duplicate_action_keys(bAnimContext *ac) int filter; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -681,8 +701,12 @@ static void duplicate_action_keys(bAnimContext *ac) for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_FCURVE) duplicate_fcurve_keys((FCurve *)ale->key_data); + else if (ale->type == ANIMTYPE_GPLAYER) + ED_gplayer_frames_duplicate((bGPDlayer *)ale->data); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_duplicate((MaskLayer *)ale->data); else - duplicate_gplayer_frames((bGPDlayer *)ale->data); + BLI_assert(0); } /* free filtered list */ @@ -703,7 +727,7 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) duplicate_action_keys(&ac); /* validate keyframes after editing */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* set notifier that keyframes have changed */ @@ -744,7 +768,7 @@ static void delete_action_keys(bAnimContext *ac) int filter; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -752,7 +776,13 @@ 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) { + if (ale->type == ANIMTYPE_GPLAYER) { + ED_gplayer_frames_delete((bGPDlayer *)ale->data); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_masklayer_frames_delete((MaskLayer *)ale->data); + } + else { FCurve *fcu = (FCurve *)ale->key_data; AnimData *adt = ale->adt; @@ -763,8 +793,6 @@ static void delete_action_keys(bAnimContext *ac) if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0)) ANIM_fcurve_delete_from_animdata(ac, adt, fcu); } - else - delete_gplayer_frames((bGPDlayer *)ale->data); } /* free filtered list */ @@ -785,7 +813,7 @@ static int actkeys_delete_exec(bContext *C, wmOperator *UNUSED(op)) delete_action_keys(&ac); /* validate keyframes after editing */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* set notifier that keyframes have changed */ @@ -840,7 +868,7 @@ static int actkeys_clean_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get cleaning threshold */ @@ -907,7 +935,7 @@ static int actkeys_sample_exec(bContext *C, wmOperator *UNUSED(op)) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* sample keyframes */ @@ -1014,7 +1042,7 @@ static int actkeys_expo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1085,7 +1113,7 @@ static int actkeys_ipo_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1165,7 +1193,7 @@ static int actkeys_handletype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1236,7 +1264,7 @@ static int actkeys_keytype_exec(bContext *C, wmOperator *op) /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get handle setting mode */ @@ -1359,7 +1387,7 @@ static void snap_action_keys(bAnimContext *ac, short mode) KeyframeEditFunc edit_cb; /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -1404,7 +1432,7 @@ static int actkeys_snap_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; // XXX... - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get snapping mode */ @@ -1482,7 +1510,7 @@ static void mirror_action_keys(bAnimContext *ac, short mode) } /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -1518,7 +1546,7 @@ static int actkeys_mirror_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; // XXX... - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) return OPERATOR_PASS_THROUGH; /* get mirroring mode */ diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 0c6b0f5eb3d..539a32161e5 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -43,6 +43,7 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "RNA_access.h" #include "RNA_define.h" @@ -55,6 +56,7 @@ #include "ED_anim_api.h" #include "ED_gpencil.h" +#include "ED_mask.h" #include "ED_keyframes_draw.h" #include "ED_keyframes_edit.h" #include "ED_markers.h" @@ -92,7 +94,7 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) KeyframeEditFunc test_cb, sel_cb; /* determine type-based settings */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -107,7 +109,13 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) if (test) { for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) { - if (is_gplayer_frame_selected(ale->data)) { + if (ED_gplayer_frame_select_check(ale->data)) { + sel = SELECT_SUBTRACT; + break; + } + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + if (ED_masklayer_frame_select_check(ale->data)) { sel = SELECT_SUBTRACT; break; } @@ -127,7 +135,9 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel) /* Now set the flags */ for (ale = anim_data.first; ale; ale = ale->next) { if (ale->type == ANIMTYPE_GPLAYER) - set_gplayer_frame_selection(ale->data, sel); + ED_gplayer_frame_select_set(ale->data, sel); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frame_select_set(ale->data, sel); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL); } @@ -249,7 +259,9 @@ static void borderselect_action(bAnimContext *ac, rcti rect, short mode, short s { /* loop over data selecting */ if (ale->type == ANIMTYPE_GPLAYER) - borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode); + ED_gplayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_select_border(ale->data, rectf.xmin, rectf.xmax, selectmode); else ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); } @@ -398,7 +410,10 @@ static void markers_selectkeys_between(bAnimContext *ac) ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else if (ale->type == ANIMTYPE_GPLAYER) { - borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); + ED_gplayer_frames_select_border(ale->data, min, max, SELECT_ADD); + } + else if (ale->type == ANIMTYPE_MASKLAYER) { + ED_masklayer_frames_select_border(ale->data, min, max, SELECT_ADD); } else { ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); @@ -432,7 +447,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); for (ale = anim_data.first; ale; ale = ale->next) - gplayer_make_cfra_list(ale->data, &ked.list, 1); + ED_gplayer_make_cfra_list(ale->data, &ked.list, 1); } else { filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); @@ -467,7 +482,7 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/); @@ -488,7 +503,9 @@ static void columnselect_action_keys(bAnimContext *ac, short mode) /* select elements with frame number matching cfraelem */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->data, ce->cfra, SELECT_ADD); + ED_gpencil_select_frame(ale->data, ce->cfra, SELECT_ADD); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->data, ce->cfra, SELECT_ADD); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -755,7 +772,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se } /* filter data */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY*/ | ANIMFILTER_NODUPLIS); @@ -771,7 +788,9 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); } else if (ale->type == ANIMTYPE_GPLAYER) - borderselect_gplayer_frames(ale->data, ked.f1, ked.f2, select_mode); + ED_gplayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_masklayer_frames_select_border(ale->data, ked.f1, ked.f2, select_mode); else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -908,7 +927,9 @@ static void actkeys_mselect_single(bAnimContext *ac, bAnimListElem *ale, short s /* select the nominated keyframe on the given frame */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->data, selx, select_mode); + ED_gpencil_select_frame(ale->data, selx, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->data, selx, select_mode); else ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL); } @@ -933,7 +954,7 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se /* loop through all of the keys and select additional keyframes * based on the keys found to be selected above */ - if (ac->datatype == ANIMCONT_GPENCIL) + if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE /*| ANIMFILTER_CURVESONLY */ | ANIMFILTER_NODUPLIS); else filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); @@ -950,8 +971,10 @@ static void actkeys_mselect_column(bAnimContext *ac, short select_mode, float se /* select elements with frame number matching cfra */ if (ale->type == ANIMTYPE_GPLAYER) - select_gpencil_frame(ale->key_data, selx, select_mode); - else + ED_gpencil_select_frame(ale->key_data, selx, select_mode); + else if (ale->type == ANIMTYPE_MASKLAYER) + ED_mask_select_frame(ale->key_data, selx, select_mode); + else ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL); } @@ -1051,7 +1074,12 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ bGPDlayer *gpl = (bGPDlayer *)ale->data; gpl_to_keylist(ads, gpl, &anim_keys); } - + else if (ale->type == ANIMTYPE_MASKLAYER) { + // TODO: why don't we just give masklayers key_data too? + MaskLayer *masklay = (MaskLayer *)ale->data; + mask_to_keylist(ads, masklay, &anim_keys); + } + /* start from keyframe at root of BST, traversing until we find one within the range that was clicked on */ for (ak = anim_keys.root; ak; ak = akn) { if (IN_RANGE(ak->cfra, rectf.xmin, rectf.xmax)) { @@ -1120,6 +1148,18 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ //gpencil_layer_setactive(gpd, gpl); } } + else if (ac->datatype == ANIMCONT_MASK) { + /* deselect all other channels first */ + ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR); + + /* Highlight GPencil Layer */ + if ((ale && ale->data) && (ale->type == ANIMTYPE_MASKLAYER)) { + MaskLayer *masklay = ale->data; + + masklay->flag |= MASK_LAYERFLAG_SELECT; + //gpencil_layer_setactive(gpd, gpl); + } + } } /* only select keyframes if we clicked on a valid channel and hit something */ diff --git a/source/blender/editors/space_action/space_action.c b/source/blender/editors/space_action/space_action.c index ae4020aaaba..c8660179945 100644 --- a/source/blender/editors/space_action/space_action.c +++ b/source/blender/editors/space_action/space_action.c @@ -361,7 +361,7 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) case NC_SCREEN: if (wmn->data == ND_GPENCIL) { /* only handle this event in GPencil mode for performance considerations */ - if (saction->mode == SACTCONT_GPENCIL) + if (saction->mode == SACTCONT_GPENCIL) ED_area_tag_redraw(sa); } break; @@ -405,6 +405,18 @@ static void action_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + if (saction->mode == SACTCONT_MASK) { + switch (wmn->data) { + case ND_DATA: + ED_area_tag_refresh(sa); + break; + default: /* just redrawing the view will do */ + ED_area_tag_redraw(sa); + break; + } + } + break; case NC_NODE: if (wmn->action == NA_SELECTED) { /* selection changed, so force refresh to flush (needs flag set to do syncing) */ diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 956aee84fd3..fa77249a7a1 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -62,6 +62,7 @@ #include "ED_mball.h" #include "ED_logic.h" #include "ED_clip.h" +#include "ED_mask.h" /* only call once on startup, storage is global in BKE kernel listbase */ void ED_spacetypes_init(void) @@ -111,6 +112,7 @@ void ED_spacetypes_init(void) ED_operatortypes_sound(); ED_operatortypes_render(); ED_operatortypes_logic(); + ED_operatortypes_mask(); UI_view2d_operatortypes(); UI_buttons_operatortypes(); @@ -133,6 +135,7 @@ void ED_spacetypes_init(void) ED_operatormacros_action(); ED_operatormacros_clip(); ED_operatormacros_curve(); + ED_operatormacros_mask(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); @@ -164,6 +167,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_physics(keyconf); ED_keymap_metaball(keyconf); ED_keymap_paint(keyconf); + ED_keymap_mask(keyconf); ED_marker_keymap(keyconf); UI_view2d_keymap(keyconf); diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c index 5c5c24f7bc1..cdecda63432 100644 --- a/source/blender/editors/space_buttons/buttons_texture.c +++ b/source/blender/editors/space_buttons/buttons_texture.c @@ -175,7 +175,7 @@ static void buttons_texture_users_from_context(ListBase *users, const bContext * if (!(pinid || pinid == &scene->id)) { ob = (scene->basact) ? scene->basact->object : NULL; wrld = scene->world; - brush = paint_brush(paint_get_active(scene)); + brush = paint_brush(paint_get_active_from_context(C)); } if (ob && ob->type == OB_LAMP && !la) diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c index 18f191a46a6..ca2ae6e8461 100644 --- a/source/blender/editors/space_clip/clip_buttons.c +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -168,7 +168,7 @@ void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) scopes->track_preview_height = (scopes->track_preview_height <= UI_UNIT_Y)?UI_UNIT_Y : scopes->track_preview_height; uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax - rect.xmin, - scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); + scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); } /********************* Marker Template ************************/ @@ -186,12 +186,13 @@ typedef struct { MovieClip *clip; MovieClipUser *user; /* user of clip */ MovieTrackingTrack *track; + MovieTrackingMarker *marker; int framenr; /* current frame number */ float marker_pos[2]; /* position of marker in pixel coords */ - float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float marker_pat[2]; /* position and dimensions of marker pattern in pixel coords */ float track_offset[2]; /* offset of "parenting" point */ - float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */ + float marker_search_pos[2], marker_search[2]; /* position and dimensions of marker search in pixel coords */ int marker_flag; /* marker's flags */ } MarkerUpdateCb; @@ -238,60 +239,63 @@ static void marker_block_handler(bContext *C, void *arg_cb, int event) ok = TRUE; } else if (event == B_MARKER_PAT_DIM) { - float dim[2], pat_dim[2]; + float dim[2], pat_dim[2], pat_min[2], pat_max[2]; + float scale_x, scale_y; + int a; - sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min); + BKE_tracking_marker_pattern_minmax(cb->marker, pat_min, pat_max); - dim[0] = cb->track_pat[0] / width; - dim[1] = cb->track_pat[1] / height; + sub_v2_v2v2(pat_dim, pat_max, pat_min); - sub_v2_v2(dim, pat_dim); - mul_v2_fl(dim, 0.5f); + dim[0] = cb->marker_pat[0] / width; + dim[1] = cb->marker_pat[1] / height; - cb->track->pat_min[0] -= dim[0]; - cb->track->pat_min[1] -= dim[1]; + scale_x = dim[0] / pat_dim[0]; + scale_y = dim[1] / pat_dim[1]; - cb->track->pat_max[0] += dim[0]; - cb->track->pat_max[1] += dim[1]; + for (a = 0; a < 4; a++) { + cb->marker->pattern_corners[a][0] *= scale_x; + cb->marker->pattern_corners[a][1] *= scale_y; + } - BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_PAT_DIM); ok = TRUE; } else if (event == B_MARKER_SEARCH_POS) { float delta[2], side[2]; - sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(side, cb->marker->search_max, cb->marker->search_min); mul_v2_fl(side, 0.5f); - delta[0] = cb->track_search_pos[0] / width; - delta[1] = cb->track_search_pos[1] / height; + delta[0] = cb->marker_search_pos[0] / width; + delta[1] = cb->marker_search_pos[1] / height; - sub_v2_v2v2(cb->track->search_min, delta, side); - add_v2_v2v2(cb->track->search_max, delta, side); + sub_v2_v2v2(cb->marker->search_min, delta, side); + add_v2_v2v2(cb->marker->search_max, delta, side); - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_POS); ok = TRUE; } else if (event == B_MARKER_SEARCH_DIM) { float dim[2], search_dim[2]; - sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min); + sub_v2_v2v2(search_dim, cb->marker->search_max, cb->marker->search_min); - dim[0] = cb->track_search[0] / width; - dim[1] = cb->track_search[1] / height; + dim[0] = cb->marker_search[0] / width; + dim[1] = cb->marker_search[1] / height; sub_v2_v2(dim, search_dim); mul_v2_fl(dim, 0.5f); - cb->track->search_min[0] -= dim[0]; - cb->track->search_min[1] -= dim[1]; + cb->marker->search_min[0] -= dim[0]; + cb->marker->search_min[1] -= dim[1]; - cb->track->search_max[0] += dim[0]; - cb->track->search_max[1] += dim[1]; + cb->marker->search_max[0] += dim[0]; + cb->marker->search_max[1] += dim[1]; - BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(cb->marker, CLAMP_SEARCH_DIM); ok = TRUE; } @@ -337,6 +341,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P MovieTrackingMarker *marker; MarkerUpdateCb *cb; const char *tip; + float pat_min[2], pat_max[2]; if (!ptr->data) return; @@ -366,6 +371,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P cb->clip = clip; cb->user = user; cb->track = track; + cb->marker = marker; cb->marker_flag = marker->flag; cb->framenr = user->framenr; @@ -383,7 +389,7 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P } else { int width, height, step, digits; - float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2]; + float pat_dim[2], search_dim[2], search_pos[2]; uiLayout *col; BKE_movieclip_get_size(clip, user, &width, &height); @@ -399,19 +405,18 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P step = 100; digits = 2; - sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min); - sub_v2_v2v2(search_dim, track->search_max, track->search_min); + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); - add_v2_v2v2(search_pos, track->search_max, track->search_min); - mul_v2_fl(search_pos, 0.5); + sub_v2_v2v2(pat_dim, pat_max, pat_min); + sub_v2_v2v2(search_dim, marker->search_max, marker->search_min); - add_v2_v2v2(pat_pos, track->pat_max, track->pat_min); - mul_v2_fl(pat_pos, 0.5); + add_v2_v2v2(search_pos, marker->search_max, marker->search_min); + mul_v2_fl(search_pos, 0.5); to_pixel_space(cb->marker_pos, marker->pos, width, height); - to_pixel_space(cb->track_pat, pat_dim, width, height); - to_pixel_space(cb->track_search, search_dim, width, height); - to_pixel_space(cb->track_search_pos, search_pos, width, height); + to_pixel_space(cb->marker_pat, pat_dim, width, height); + to_pixel_space(cb->marker_search, search_dim, width, height); + to_pixel_space(cb->marker_search_pos, search_pos, width, height); to_pixel_space(cb->track_offset, track->offset, width, height); cb->marker_flag = marker->flag; @@ -447,19 +452,19 @@ void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, P -10*height, 10.0*height, step, digits, "Y-offset to parenting point"); uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->marker_pat[0], 3.0f, 10.0*width, step, digits, "Width of marker's pattern in screen coordinates"); - uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->marker_pat[1], 3.0f, 10.0*height, step, digits, "Height of marker's pattern in screen coordinates"); uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->marker_search_pos[0], -width, width, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->marker_search_pos[1], -height, height, step, digits, "X-position of search at frame relative to marker's position"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->marker_search[0], 3.0f, 10.0*width, step, digits, "Width of marker's search in screen soordinates"); - uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->marker_search[1], 3.0f, 10.0*height, step, digits, "Height of marker's search in screen soordinates"); uiBlockEndAlign(block); diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index e264d7f3885..67609fee653 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_draw.c +/** \file blender/editors/space_clip/clip_dopesheet_draw.c * \ingroup spclip */ @@ -200,8 +200,8 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) /* tracked segments */ for (i = 0; i < channel->tot_segment; i++) { - int start_frame = channel->segments[2 * i]; - int end_frame = channel->segments[2 * i + 1]; + int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i]); + int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, channel->segments[2 * i + 1]); if (sel) glColor4fv(selected_strip); @@ -224,8 +224,11 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) while (i < track->markersnr) { MovieTrackingMarker *marker = &track->markers[i]; - if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) - draw_keyframe_shape(marker->framenr, y, xscale, yscale, sel, alpha); + if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) { + int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + draw_keyframe_shape(framenr, y, xscale, yscale, sel, alpha); + } i++; } diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c index 0fd17523425..914e82472bb 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_ops.c +++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/editors/space_clip/clip_graph_ops.c +/** \file blender/editors/space_clip/clip_dopesheet_ops.c * \ingroup spclip */ @@ -93,6 +93,10 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op) track->flag ^= TRACK_DOPE_SEL; else track->flag |= TRACK_DOPE_SEL; + + if (track->flag & TRACK_DOPE_SEL) { + tracking->act_track = track; + } } else if (!extend) track->flag &= ~TRACK_DOPE_SEL; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index c00359f0f32..2e16a9095f0 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -33,12 +33,14 @@ #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" #include "BKE_context.h" #include "BKE_movieclip.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -124,7 +126,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc if (act_track) { MovieTrackingTrack *track = act_track; - for (i = sfra, a = 0; i <= efra; i++) { + for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) { int framenr; MovieTrackingMarker *marker; @@ -153,7 +155,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc else glColor4ub(255, 255, 0, 96); - glRecti((i - sfra) * framelen, 0, (i - sfra + 1)*framelen, 4); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4); } } } @@ -181,7 +183,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc } if (!ok) - glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 8); + glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8); } } @@ -194,6 +196,32 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc glRecti(x, 0, x + framelen, 8); clip_draw_curfra_label(sc, x, 8.0f); + + /* movie clip animation */ + if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask) { + MaskLayer *masklay = BKE_mask_layer_active(sc->mask); + if (masklay) { + MaskLayerShape *masklay_shape; + + glColor4ub(255, 175, 0, 255); + glBegin(GL_LINES); + + for (masklay_shape = masklay->splines_shapes.first; + masklay_shape; + masklay_shape = masklay_shape->next) + { + i = masklay_shape->frame; + + /* glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 4); */ + + /* use a line so we always see the keyframes */ + glVertex2i((i - sfra) * framelen, 0); + glVertex2i((i - sfra) * framelen, (i == CFRA) ? 22 : 10); + } + + glEnd(); + } + } } static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) @@ -310,17 +338,17 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin int count = sc->path_length; int i, a, b, curindex = -1; float path[102][2]; - int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr; + int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame; MovieTrackingMarker *marker; if (count == 0) return; - marker = BKE_tracking_get_marker(track, sc->user.framenr); - if (marker->framenr != sc->user.framenr || marker->flag & MARKER_DISABLED) - return; + start_frame = framenr = ED_space_clip_clip_framenr(sc); - framenr = marker->framenr; + marker = BKE_tracking_get_marker(track, framenr); + if (marker->framenr != framenr || marker->flag & MARKER_DISABLED) + return; a = count; i = framenr - 1; @@ -334,7 +362,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin add_v2_v2v2(path[--a], marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, path[a], path[a]); - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = a; } else { @@ -353,7 +381,7 @@ static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackin break; if (marker->framenr == i) { - if (marker->framenr == sc->user.framenr) + if (marker->framenr == start_frame) curindex = b; add_v2_v2v2(path[b++], marker->pos, track->offset); @@ -428,14 +456,17 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if ((marker->flag & MARKER_DISABLED) == 0) { float pos[2]; - rctf r; + float p[2]; - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (tiny) glPointSize(3.0f); else glPointSize(4.0f); glBegin(GL_POINTS); @@ -471,10 +502,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT if (sc->flag & SC_SHOW_MARKER_PATTERN) { glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -482,10 +513,10 @@ static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieT ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0); if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) { glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } glPopMatrix(); @@ -528,8 +559,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra /* marker position and offset position */ if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) { - float pos[2]; - rctf r; + float pos[2], p[2]; if (track->flag & TRACK_LOCKED) { if (act) @@ -546,11 +576,14 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glColor3fv(col); } - BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); add_v2_v2v2(pos, marker->pos, track->offset); ED_clip_point_undistorted_pos(sc, pos, pos); - if (BLI_in_rctf(&r, pos[0] - marker_pos[0], pos[1] - marker_pos[1])) { + sub_v2_v2v2(p, pos, marker_pos); + + if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1], + marker->pattern_corners[2], marker->pattern_corners[3])) + { if (!tiny) glPointSize(2.0f); @@ -623,10 +656,10 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); + glVertex2fv(marker->pattern_corners[0]); + glVertex2fv(marker->pattern_corners[1]); + glVertex2fv(marker->pattern_corners[2]); + glVertex2fv(marker->pattern_corners[3]); glEnd(); } @@ -656,70 +689,82 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } glBegin(GL_LINE_LOOP); - glVertex2f(track->search_min[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_min[1]); - glVertex2f(track->search_max[0], track->search_max[1]); - glVertex2f(track->search_min[0], track->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_min[1]); + glVertex2f(marker->search_max[0], marker->search_max[1]); + glVertex2f(marker->search_min[0], marker->search_max[1]); glEnd(); } - /* pyramid */ - if (sel && TRACK_VIEW_SELECTED(sc, track) && - (track->tracker == TRACKER_KLT) && - (marker->flag & MARKER_DISABLED) == 0) - { - if (track->flag & TRACK_LOCKED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_LOCK_MARKER, 64); - else UI_ThemeColor(TH_LOCK_MARKER); - } - else if (marker->flag & MARKER_DISABLED) { - if (act) - UI_ThemeColor(TH_ACT_MARKER); - else if (track->pat_flag & SELECT) - UI_ThemeColorShade(TH_DIS_MARKER, 128); - else UI_ThemeColor(TH_DIS_MARKER); - } - else { - if (track->pat_flag & SELECT) - glColor3fv(scol); - else - glColor3fv(col); - } - - { - int i = 0; - glPushMatrix(); - glEnable(GL_LINE_STIPPLE); - for (i = 1; i < track->pyramid_levels; ++i) { - glScalef(2.0f, 2.0f, 1.0); - } - /* only draw a pattern for the coarsest level */ - glBegin(GL_LINE_LOOP); - glVertex2f(track->pat_min[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_min[1]); - glVertex2f(track->pat_max[0], track->pat_max[1]); - glVertex2f(track->pat_min[0], track->pat_max[1]); - glEnd(); - glDisable(GL_LINE_STIPPLE); - glPopMatrix(); - } - } - if (tiny) glDisable(GL_LINE_STIPPLE); glPopMatrix(); } +static float get_shortest_pattern_side(MovieTrackingMarker *marker) +{ + int i, next; + float len = FLT_MAX; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + return len; +} + +static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx; + tdy = dy; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x - tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y + tdy, 0.0f); + glVertex3f(x + tdx, y - tdy, 0.0f); + glVertex3f(x - tdx, y - tdy, 0.0f); + glEnd(); +} + +static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2]) +{ + float tdx, tdy; + + tdx = dx * 2.0f; + tdy = dy * 2.0f; + + if (outline) { + tdx += px[0]; + tdy += px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0.0f); + glVertex3f(x - tdx, y, 0.0f); + glVertex3f(x, y + tdy, 0.0f); + glEnd(); +} + static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int outline, int sel, int act, int width, int height) { - float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; + float dx, dy, patdx, patdy, searchdx, searchdy; int tiny = sc->flag & SC_SHOW_TINY_MARKER; - float col[3], scol[3], px[2]; + float col[3], scol[3], px[2], side; if ((tiny && outline) || (marker->flag & MARKER_DISABLED)) return; @@ -740,11 +785,12 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo dx = 6.0f / width / sc->zoom; dy = 6.0f / height / sc->zoom; - patdx = MIN2(dx * 2.0f / 3.0f, (track->pat_max[0] - track->pat_min[0]) / 6.0f); - patdy = MIN2(dy * 2.0f / 3.0f, (track->pat_max[1] - track->pat_min[1]) / 6.0f); + side = get_shortest_pattern_side(marker); + patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f); + patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f); - searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f); - searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f); + searchdx = MIN2(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f); + searchdy = MIN2(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f); px[0] = 1.0f / sc->zoom / width / sc->scale; px[1] = 1.0f / sc->zoom / height / sc->scale; @@ -758,41 +804,10 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo } /* search offset square */ - x = track->search_min[0]; - y = track->search_max[1]; - - tdx = searchdx; - tdy = searchdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); + draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px); /* search re-sizing triangle */ - x = track->search_max[0]; - y = track->search_min[1]; - - tdx = searchdx * 2.0f; - tdy = searchdy * 2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; - } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); + draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px); } if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { @@ -803,42 +818,26 @@ static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, Mo glColor3fv(col); } - /* pattern offset square */ - x = track->pat_min[0]; - y = track->pat_max[1]; + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int i; - tdx = patdx; - tdy = patdy; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern's corners sliding squares */ + for (i = 0; i < 4; i++) { + draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1], + patdx / 1.5f, patdy / 1.5f, outline, px); + } } + else { + /* pattern offset square */ + draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1], + patdx, patdy, outline, px); - glBegin(GL_QUADS); - glVertex3f(x - tdx, y + tdy, 0); - glVertex3f(x + tdx, y + tdy, 0); - glVertex3f(x + tdx, y - tdy, 0); - glVertex3f(x - tdx, y - tdy, 0); - glEnd(); - - /* pattern re-sizing triangle */ - x = track->pat_max[0]; - y = track->pat_min[1]; - - tdx = patdx*2.0f; - tdy = patdy*2.0f; - - if (outline) { - tdx += px[0]; - tdy += px[1]; + /* pattern re-sizing triangle */ + draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1], + patdx, patdy, outline, px); } - - glBegin(GL_TRIANGLES); - glVertex3f(x, y, 0); - glVertex3f(x - tdx, y, 0); - glVertex3f(x, y + tdy, 0); - glEnd(); } glPopMatrix(); @@ -877,12 +876,15 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) { - dx = track->search_min[0]; - dy = track->search_min[1]; + dx = marker->search_min[0]; + dy = marker->search_min[1]; } else if (sc->flag & SC_SHOW_MARKER_PATTERN) { - dx = track->pat_min[0]; - dy = track->pat_min[1]; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + dx = pat_min[0]; + dy = pat_min[1]; } pos[0] = (marker_pos[0] + dx) * width; @@ -896,7 +898,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra if (marker->flag & MARKER_DISABLED) strcpy(state, "disabled"); - else if (marker->framenr != sc->user.framenr) + else if (marker->framenr != ED_space_clip_clip_framenr(sc)) strcpy(state, "estimated"); else if (marker->flag & MARKER_TRACKED) strcpy(state, "tracked"); @@ -944,7 +946,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track, *act_track; MovieTrackingMarker *marker; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2]; @@ -1175,8 +1177,10 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int i, j, a; float pos[2], tpos[2], grid[11][11][2]; MovieTracking *tracking = &clip->tracking; + bGPdata *gpd = NULL; float aspy = 1.0f / tracking->camera.pixel_aspect; float dx = (float)width / n, dy = (float)height / n * aspy; + float offsx = 0.0f, offsy = 0.0f; if (sc->mode != SC_MODE_DISTORTION) return; @@ -1284,8 +1288,26 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } } - if (sc->flag & SC_MANUAL_CALIBRATION && clip->gpd) { - bGPDlayer *layer = clip->gpd->layers.first; + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); + + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + offsx = marker->pos[0]; + offsy = marker->pos[1]; + + gpd = track->gpd; + } + + } + else { + gpd = clip->gpd; + } + + if (sc->flag & SC_MANUAL_CALIBRATION && gpd) { + bGPDlayer *layer = gpd->layers.first; while (layer) { bGPDframe *frame = layer->frames.first; @@ -1310,11 +1332,11 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, float npos[2], dpos[2], len; int steps; - pos[0] = stroke->points[i].x * width; - pos[1] = stroke->points[i].y * height * aspy; + pos[0] = (stroke->points[i].x + offsx) * width; + pos[1] = (stroke->points[i].y + offsy) * height * aspy; - npos[0] = stroke->points[i + 1].x * width; - npos[1] = stroke->points[i + 1].y * height * aspy; + npos[0] = (stroke->points[i + 1].x + offsx) * width; + npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy; len = len_v2v2(pos, npos); steps = ceil(len / 5.0f); @@ -1339,7 +1361,7 @@ static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, } else if (stroke->totpoints == 1) { glBegin(GL_POINTS); - glVertex2f(stroke->points[0].x, stroke->points[0].y); + glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy); glEnd(); } } @@ -1429,7 +1451,6 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - ImBuf *ibuf; if (!clip) return; @@ -1438,16 +1459,23 @@ void clip_draw_grease_pencil(bContext *C, int onlyv2d) /* if manual calibration is used then grease pencil data is already * drawed in draw_distortion */ if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) { - ibuf = ED_space_clip_get_buffer(sc); + glPushMatrix(); + glMultMatrixf(sc->unistabmat); - if (ibuf) { - glPushMatrix(); - glMultMatrixf(sc->unistabmat); - draw_gpencil_2dimage(C, ibuf); + if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) { + MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking); - IMB_freeImBuf(ibuf); - glPopMatrix(); + if (track) { + int framenr = sc->user.framenr; + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); + + glTranslatef(marker->pos[0], marker->pos[1], 0.0f); + } } + + draw_gpencil_2dimage(C); + + glPopMatrix(); } } else { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index a477a7435fd..504d96df072 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -34,10 +34,12 @@ #include "MEM_guardedalloc.h" #include "BKE_main.h" +#include "BKE_mask.h" #include "BKE_movieclip.h" #include "BKE_context.h" #include "BKE_tracking.h" +#include "DNA_mask_types.h" #include "DNA_object_types.h" /* SELECT */ #include "BLI_utildefines.h" @@ -94,33 +96,26 @@ int ED_space_clip_tracking_poll(bContext *C) return FALSE; } -int ED_space_clip_tracking_size_poll(bContext *C) +int ED_space_clip_maskedit_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { - MovieClip *clip = CTX_data_edit_movieclip(C); - - if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); - int width, height; - - BKE_movieclip_get_size(clip, &sc->user, &width, &height); + SpaceClip *sc = CTX_wm_space_clip(C); - return width > 0 && height > 0; - } + if (sc && sc->clip) { + return ED_space_clip_show_maskedit(sc); } return FALSE; } -int ED_space_clip_tracking_frame_poll(bContext *C) +int ED_space_clip_maskedit_mask_poll(bContext *C) { - if (ED_space_clip_tracking_poll(C)) { + if (ED_space_clip_maskedit_poll(C)) { MovieClip *clip = CTX_data_edit_movieclip(C); if (clip) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc= CTX_wm_space_clip(C); - return BKE_movieclip_has_frame(clip, &sc->user); + return sc->mask != NULL; } } @@ -170,6 +165,11 @@ MovieClip *ED_space_clip(SpaceClip *sc) return sc->clip; } +Mask *ED_space_clip_mask(SpaceClip *sc) +{ + return sc->mask; +} + ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) { if (sc->clip) { @@ -214,6 +214,51 @@ void ED_space_clip_size(SpaceClip *sc, int *width, int *height) } } +void ED_space_clip_mask_size(SpaceClip *sc, int *width, int *height) +{ + /* quite the same as ED_space_clip_size, but it also runs aspect correction on output resolution + * this is needed because mask should be rasterized with exactly the same resolution as + * currently displaying frame and it doesn't have access to aspect correction currently + * used for display. (sergey) + */ + + if (!sc->mask) { + *width = 0; + *height = 0; + } else { + float aspx, aspy; + + ED_space_clip_size(sc, width, height); + ED_space_clip_aspect(sc, &aspx, &aspy); + + *width *= aspx; + *height *= aspy; + } +} + +void ED_space_clip_mask_aspect(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + /* now this is not accounted for! */ +#if 0 + *aspx *= (float)w; + *aspy *= (float)h; +#endif + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) { int width, height; @@ -234,6 +279,33 @@ void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy) *aspx = *aspy = 1.0f; } +void ED_space_clip_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy) +{ + int w, h; + + /* most of tools does not require aspect to be returned with dimensions correction + * due to they're invariant to this stuff, but some transformation tools like rotation + * should be aware of aspect correction caused by different resolution in different + * directions. + * mainly this is sued for transformation stuff + */ + + ED_space_clip_aspect(sc, aspx, aspy); + ED_space_clip_size(sc, &w, &h); + + *aspx *= (float)w; + *aspy *= (float)h; + + if (*aspx < *aspy) { + *aspy= *aspy / *aspx; + *aspx= 1.0f; + } + else { + *aspx= *aspx / *aspy; + *aspy= 1.0f; + } +} + void ED_clip_update_frame(const Main *mainp, int cfra) { wmWindowManager *wm; @@ -257,6 +329,14 @@ void ED_clip_update_frame(const Main *mainp, int cfra) } } +/* return current frame number in clip space */ +int ED_space_clip_clip_framenr(SpaceClip *sc) +{ + MovieClip *clip = ED_space_clip(sc); + + return BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); +} + static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { MovieClip *clip = ED_space_clip(sc); @@ -439,7 +519,10 @@ typedef struct SpaceClipDrawContext { struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ int image_width, image_height; /* image width and height for which texture was created */ unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - int framenr; + + /* fields to check if cache is still valid */ + int framenr, start_frame; + short render_size, render_flag; } SpaceClipDrawContext; int ED_space_clip_texture_buffer_supported(SpaceClip *sc) @@ -477,6 +560,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) * so not changed image buffer pointer means unchanged image content */ need_rebind |= context->texture_ibuf != ibuf; need_rebind |= context->framenr != sc->user.framenr; + need_rebind |= context->render_size != sc->user.render_size; + need_rebind |= context->render_flag != sc->user.render_flag; + need_rebind |= context->start_frame != clip->start_frame; if (need_rebind) { int width = ibuf->x, height = ibuf->y; @@ -531,6 +617,9 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf) context->image_width = ibuf->x; context->image_height = ibuf->y; context->framenr = sc->user.framenr; + context->render_size = sc->user.render_size; + context->render_flag = sc->user.render_flag; + context->start_frame = clip->start_frame; } else { /* displaying exactly the same image which was loaded t oa texture, @@ -562,6 +651,8 @@ void ED_space_clip_free_texture_buffer(SpaceClip *sc) } } +/* ******** masking editing related functions ******** */ + int ED_space_clip_show_trackedit(SpaceClip *sc) { if (sc) { @@ -570,3 +661,25 @@ int ED_space_clip_show_trackedit(SpaceClip *sc) return FALSE; } + +int ED_space_clip_show_maskedit(SpaceClip *sc) +{ + if (sc) { + return sc->mode == SC_MODE_MASKEDIT; + } + + return FALSE; +} + +void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) +{ + sc->mask = mask; + + if (sc->mask && sc->mask->id.us==0) { + sc->clip->id.us = 1; + } + + if (C) { + WM_event_add_notifier(C, NC_MASK|NA_SELECTED, mask); + } +} diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c index 853a7d7cad1..8d30242c128 100644 --- a/source/blender/editors/space_clip/clip_graph_draw.c +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -88,9 +88,9 @@ static void draw_curve_knot(float x, float y, float xscale, float yscale, float } static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int UNUSED(coord), float val) + MovieTrackingMarker *UNUSED(marker), int UNUSED(coord), int scene_framenr, float val) { - glVertex2f(marker->framenr, val); + glVertex2f(scene_framenr, val); } void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord) @@ -123,7 +123,7 @@ void tracking_segment_end_cb(void *UNUSED(userdata)) } static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; int sel = 0, sel_flag; @@ -140,7 +140,7 @@ static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, else UI_ThemeColor(TH_HANDLE_VERTEX); - draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize); + draw_curve_knot(scene_framenr, val, data->xscale, data->yscale, data->hsize); } } diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c index 10692ada5d9..79e199a8f06 100644 --- a/source/blender/editors/space_clip/clip_graph_ops.c +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -109,10 +109,11 @@ typedef struct { } MouseSelectUserData; static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *UNUSED(marker), + int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; if (data->has_prev) { float d = dist_to_line_segment_v2(data->mouse_co, data->prev_co, co); @@ -137,14 +138,14 @@ void find_nearest_tracking_segment_end_cb(void *userdata) } static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track, - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { MouseSelectUserData *data = userdata; - float dx = marker->framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; + float dx = scene_framenr - data->mouse_co[0], dy = val - data->mouse_co[1]; float d = dx * dx + dy * dy; if (data->marker == NULL || d < data->min_dist) { - float co[2] = {marker->framenr, val}; + float co[2] = {scene_framenr, val}; data->track = track; data->marker = marker; @@ -308,11 +309,11 @@ typedef struct BorderSelectuserData { } BorderSelectuserData; static void border_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track), - MovieTrackingMarker *marker, int coord, float val) + MovieTrackingMarker *marker, int coord, int scene_framenr, float val) { BorderSelectuserData *data = (BorderSelectuserData *) userdata; - if (BLI_in_rctf(&data->rect, marker->framenr, val)) { + if (BLI_in_rctf(&data->rect, scene_framenr, val)) { int flag = 0; if (coord == 0) @@ -532,7 +533,7 @@ typedef struct { } ViewAllUserData; static void view_all_cb(void *userdata, MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *UNUSED(marker), - int UNUSED(coord), float val) + int UNUSED(coord), int UNUSED(scene_framenr), float val) { ViewAllUserData *data = (ViewAllUserData *) userdata; diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h index 00105fb8561..6908e488157 100644 --- a/source/blender/editors/space_clip/clip_intern.h +++ b/source/blender/editors/space_clip/clip_intern.h @@ -110,12 +110,12 @@ void ED_clip_tool_props_register(struct ARegionType *art); /* clip_utils.c */ void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, - void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)); diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c index 4142c30d825..6b69f316880 100644 --- a/source/blender/editors/space_clip/clip_utils.c +++ b/source/blender/editors/space_clip/clip_utils.c @@ -64,7 +64,7 @@ #include "clip_intern.h" // own include void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { @@ -104,8 +104,11 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack val = (marker->pos[coord] - prevval) * ((coord == 0) ? (width) : (height)); val /= marker->framenr - prevfra; - if (func) - func(userdata, track, marker, coord, val); + if (func) { + int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr); + + func(userdata, track, marker, coord, scene_framenr, val); + } prevval = marker->pos[coord]; prevfra = marker->framenr; @@ -119,7 +122,7 @@ void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack } void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, - void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, int scene_framenr, float val), void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), void (*segment_end) (void *userdata)) { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index a6fda200ff4..54724881e37 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -33,7 +33,9 @@ #include <stdio.h> #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" +#include "DNA_view3d_types.h" /* for pivot point */ #include "MEM_guardedalloc.h" @@ -49,6 +51,8 @@ #include "IMB_imbuf_types.h" +#include "ED_mask.h" +#include "ED_space_api.h" #include "ED_screen.h" #include "ED_clip.h" #include "ED_transform.h" @@ -237,6 +241,7 @@ static SpaceLink *clip_new(const bContext *C) sc->zoom = 1.0f; sc->path_length = 20; sc->scopes.track_preview_height = 120; + sc->around = V3D_LOCAL; /* header */ ar = MEM_callocN(sizeof(ARegion), "header for clip"); @@ -301,6 +306,9 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_preview) IMB_freeImBuf(sc->scopes.track_preview); + if (sc->scopes.track_search) + IMB_freeImBuf(sc->scopes.track_search); + ED_space_clip_free_texture_buffer(sc); } @@ -318,6 +326,7 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) SpaceClip *scn = MEM_dupallocN(sl); /* clear or remove stuff from old */ + scn->scopes.track_search = NULL; scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; scn->draw_context = NULL; @@ -361,6 +370,24 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + switch (wmn->data) { + case ND_SELECT: + case ND_DATA: + case ND_DRAW: + ED_area_tag_redraw(sa); + break; + } + switch (wmn->action) { + case NA_SELECTED: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + case NA_EDITED: + ED_area_tag_redraw(sa); + break; + } + break; case NC_GEOM: switch (wmn->data) { case ND_SELECT: @@ -369,9 +396,12 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn) break; } break; - case NC_SCREEN: - if (wmn->data == ND_ANIMPLAY) { - ED_area_tag_redraw(sa); + case NC_SCREEN: + switch (wmn->data) { + case ND_ANIMPLAY: + case ND_GPENCIL: + ED_area_tag_redraw(sa); + break; } break; case NC_SPACE: @@ -532,7 +562,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) /* ******** Hotkeys avalaible for main region only ******** */ keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); - +// keymap->poll = ED_space_clip_tracking_poll; /* ** View/navigation ** */ WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); @@ -715,7 +745,7 @@ static void clip_keymap(struct wmKeyConfig *keyconf) RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */ } -const char *clip_context_dir[] = {"edit_movieclip", NULL}; +const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL}; static int clip_context(const bContext *C, const char *member, bContextDataResult *result) { @@ -729,7 +759,11 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul else if (CTX_data_equals(member, "edit_movieclip")) { if (sc->clip) CTX_data_id_pointer_set(result, &sc->clip->id); - + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + if (sc->mask) + CTX_data_id_pointer_set(result, &sc->mask->id); return TRUE; } @@ -1020,6 +1054,9 @@ static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); /* own keymap */ + keymap = WM_keymap_find(wm->defaultconf, "Mask Editing", 0, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); @@ -1067,6 +1104,49 @@ static void clip_main_area_draw(const bContext *C, ARegion *ar) /* Grease Pencil */ clip_draw_grease_pencil((bContext *)C, 1); + if (sc->mode == SC_MODE_MASKEDIT) { + int x, y; + int width, height; + float zoomx, zoomy, aspx, aspy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_aspect(sc, &aspx, &aspy); + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + glMultMatrixf(sc->stabmat); + + ED_mask_draw((bContext *)C, sc->mask_draw_flag, sc->mask_draw_type); + + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + + glPopMatrix(); + } + /* reset view matrix */ UI_view2d_view_restore(C); @@ -1241,6 +1321,26 @@ static void clip_header_area_draw(const bContext *C, ARegion *ar) ED_region_header(C, ar); } +static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch (wmn->category) { + case NC_SCENE: + switch (wmn->data) { + /* for proportional editmode only */ + case ND_TOOLSETTINGS: + /* TODO - should do this when in mask mode only but no datas available */ + // if (sc->mode == SC_MODE_MASKEDIT) + { + ED_region_tag_redraw(ar); + } + break; + } + break; + } +} + + /****************** tools region ******************/ /* add handlers, stuff you only do once or on area/region changes */ @@ -1402,6 +1502,7 @@ void ED_spacetype_clip(void) art->init = clip_header_area_init; art->draw = clip_header_area_draw; + art->listener = clip_header_area_listener; BLI_addhead(&st->regiontypes, art); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index f6dbae596b8..f6e9622f0a5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -79,6 +79,8 @@ #include "clip_intern.h" // own include +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]); + /********************** add marker operator *********************/ static void add_marker(SpaceClip *sc, float x, float y) @@ -88,10 +90,11 @@ static void add_marker(SpaceClip *sc, float x, float y) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track; int width, height; + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); - track = BKE_tracking_add_track(tracking, tracksbase, x, y, sc->user.framenr, width, height); + track = BKE_tracking_add_track(tracking, tracksbase, x, y, framenr, width, height); BKE_tracking_select_track(tracksbase, track, TRACK_AREA_ALL, 0); @@ -106,6 +109,7 @@ static int add_marker_exec(bContext *C, wmOperator *op) int width, height; ED_space_clip_size(sc, &width, &height); + if (!width || !height) return OPERATOR_CANCELLED; @@ -143,7 +147,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) /* api callbacks */ ot->invoke = add_marker_invoke; ot->exec = add_marker_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -202,7 +206,7 @@ static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) MovieClip *clip = ED_space_clip(sc); ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track = tracksbase->first, *next; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = 0; while (track) { @@ -258,19 +262,21 @@ typedef struct { int mval[2]; int width, height; - float *min, *max, *pos, *offset; - float smin[2], smax[2], spos[2], soff[2]; + float *min, *max, *pos, *offset, (*corners)[2]; + float smin[2], smax[2], spos[2], soff[2], scorners[4][2]; float (*smarkers)[2]; - int lock, accurate; + int lock, accurate, scale; } SlideMarkerData; static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, - MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height) + MovieTrackingMarker *marker, wmEvent *event, + int area, int corner, int action, int width, int height) { SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); + int framenr = ED_space_clip_clip_framenr(sc); - marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + marker = BKE_tracking_ensure_marker(track, framenr); data->area = area; data->action = action; @@ -285,10 +291,9 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra } else if (area == TRACK_AREA_PAT) { if (action == SLIDE_ACTION_SIZE) { - data->min = track->pat_min; - data->max = track->pat_max; + data->corners = marker->pattern_corners; } - else { + else if (action == SLIDE_ACTION_OFFSET) { int a; data->pos = marker->pos; @@ -300,15 +305,28 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra for (a = 0; a < track->markersnr; a++) copy_v2_v2(data->smarkers[a], track->markers[a].pos); } + else if (action == SLIDE_ACTION_POS) { + data->corners = marker->pattern_corners; + data->pos = marker->pattern_corners[corner]; + + copy_v2_v2(data->spos, data->pos); + } } else if (area == TRACK_AREA_SEARCH) { - data->min = track->search_min; - data->max = track->search_max; + data->min = marker->search_min; + data->max = marker->search_max; } - if (area == TRACK_AREA_SEARCH || (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) { - copy_v2_v2(data->smin, data->min); - copy_v2_v2(data->smax, data->max); + if ((area == TRACK_AREA_SEARCH) || + (area == TRACK_AREA_PAT && action != SLIDE_ACTION_OFFSET)) + { + if (data->corners) { + memcpy(data->scorners, data->corners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->smin, data->min); + copy_v2_v2(data->smax, data->max); + } } data->mval[0] = event->mval[0]; @@ -323,9 +341,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra return data; } -/* corner = 0: right-bottom corner, - * corner = 1: left-top corner */ -static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, +static int mouse_on_corner(SpaceClip *sc, MovieTrackingMarker *marker, int area, float co[2], int corner, int width, int height) { int inside = 0; @@ -334,12 +350,11 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki float crn[2], dx, dy, tdx, tdy; if (area == TRACK_AREA_SEARCH) { - copy_v2_v2(min, track->search_min); - copy_v2_v2(max, track->search_max); + copy_v2_v2(min, marker->search_min); + copy_v2_v2(max, marker->search_max); } else { - copy_v2_v2(min, track->pat_min); - copy_v2_v2(max, track->pat_max); + BKE_tracking_marker_pattern_minmax(marker, min, max); } dx = size / width / sc->zoom; @@ -367,22 +382,95 @@ static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTracki return inside; } +static int get_mouse_pattern_corner(SpaceClip *sc, MovieTrackingMarker *marker, float co[2], int width, int height) +{ + int i, next; + float len = FLT_MAX, dx, dy; + + for (i = 0; i < 4; i++) { + float cur_len; + + next = (i + 1) % 4; + + cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]); + + len = MIN2(cur_len, len); + } + + dx = 6.0f / width / sc->zoom; + dy = 6.0f / height / sc->zoom; + + dx = MIN2(dx * 2.0f / 3.0f, len / 6.0f); + dy = MIN2(dy * 2.0f / 3.0f, len * width / height / 6.0f); + + for (i = 0; i < 4; i++) { + float crn[2]; + int inside; + + add_v2_v2v2(crn, marker->pattern_corners[i], marker->pos); + + inside = IN_RANGE_INCL(co[0], crn[0] - dx, crn[0] + dx) && + IN_RANGE_INCL(co[1], crn[1] - dy, crn[1] + dy); + + if (inside) + return i; + } + + return -1; +} + static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, - float co[2], int width, int height) + float co[2], int width, int height) { float pos[2], dx, dy; + float pat_min[2], pat_max[2]; + + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); add_v2_v2v2(pos, marker->pos, track->offset); dx = 12.0f / width / sc->zoom; dy = 12.0f / height / sc->zoom; - dx = MIN2(dx, (track->pat_max[0] - track->pat_min[0]) / 2.0f); - dy = MIN2(dy, (track->pat_max[1] - track->pat_min[1]) / 2.0f); + dx = MIN2(dx, (pat_max[0] - pat_min[0]) / 2.0f); + dy = MIN2(dy, (pat_max[1] - pat_min[1]) / 2.0f); return co[0] >= pos[0] - dx && co[0] <= pos[0] + dx && co[1] >= pos[1] - dy && co[1] <= pos[1] + dy; } +static int slide_check_corners(float (*corners)[2]) +{ + int i, next, prev; + float cross = 0.0f; + float p[2] = {0.0f, 0.0f}; + + if (!isect_point_quad_v2(p, corners[0], corners[1], corners[2], corners[3])) + return FALSE; + + for (i = 0; i < 4; i++) { + float v1[2], v2[2], cur_cross; + + next = (i + 1) % 4; + prev = (4 + i - 1) % 4; + + sub_v2_v2v2(v1, corners[i], corners[prev]); + sub_v2_v2v2(v2, corners[next], corners[i]); + + cur_cross = cross_v2v2(v1, v2); + + if (fabsf(cur_cross) > FLT_EPSILON) { + if (cross == 0.0f) { + cross = cur_cross; + } + else if (cross * cur_cross < 0.0f) { + return FALSE; + } + } + } + + return TRUE; +} + static void hide_cursor(bContext *C) { wmWindow *win = CTX_wm_window(C); @@ -406,6 +494,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) float co[2]; void *customdata = NULL; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + int framenr = ED_space_clip_clip_framenr(sc); ED_space_clip_size(sc, &width, &height); @@ -417,31 +506,48 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event) track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if ((marker->flag & MARKER_DISABLED) == 0) { - if (!customdata) + if (!customdata) { if (mouse_on_offset(sc, track, marker, co, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, 0, SLIDE_ACTION_POS, width, height); + } if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_OFFSET, width, height); - else if (mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, + } + else if (mouse_on_corner(sc, marker, TRACK_AREA_SEARCH, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, 0, SLIDE_ACTION_SIZE, width, height); + } } if (!customdata && (sc->flag & SC_SHOW_MARKER_PATTERN)) { - if (mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_OFFSET, width, height); - - if (!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) - customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, - SLIDE_ACTION_SIZE, width, height); + /* XXX: need to be real check if affine tracking is enabled, but for now not + * sure how to do this, so assume affine tracker is always enabled */ + if (TRUE) { + int corner = get_mouse_pattern_corner(sc, marker, co, width, height); + + if (corner != -1) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, corner, + SLIDE_ACTION_POS, width, height); + } + } + else { + if (mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 1, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_OFFSET, width, height); + } + + if (!customdata && mouse_on_corner(sc, marker, TRACK_AREA_PAT, co, 0, width, height)) { + customdata = create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, 0, + SLIDE_ACTION_SIZE, width, height); + } + } } if (customdata) @@ -489,9 +595,16 @@ static void cancel_mouse_slide(SlideMarkerData *data) copy_v2_v2(data->pos, data->spos); } else { - if (data->action == SLIDE_ACTION_SIZE) { - copy_v2_v2(data->min, data->smin); - copy_v2_v2(data->max, data->smax); + if ((data->action == SLIDE_ACTION_SIZE) || + (data->action == SLIDE_ACTION_POS && data->area == TRACK_AREA_PAT)) + { + if (data->corners) { + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + } + else { + copy_v2_v2(data->min, data->smin); + copy_v2_v2(data->max, data->smax); + } } else { int a; @@ -527,6 +640,10 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) data->lock = event->val == KM_RELEASE; + if (data->action == SLIDE_ACTION_POS) + if (ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->scale = event->val == KM_PRESS; + if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = event->val == KM_PRESS; @@ -556,8 +673,6 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) else { data->pos[0] = data->spos[0] + dx; data->pos[1] = data->spos[1] + dy; - - data->marker->flag &= ~MARKER_TRACKED; } WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); @@ -565,18 +680,33 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } else { if (data->action == SLIDE_ACTION_SIZE) { - data->min[0] = data->smin[0] - dx; - data->max[0] = data->smax[0] + dx; + if (data->corners) { + data->corners[0][0] = data->scorners[0][0] - dx; + data->corners[0][1] = data->scorners[0][1] + dy; - data->min[1] = data->smin[1] + dy; - data->max[1] = data->smax[1] - dy; + data->corners[1][0] = data->scorners[1][0] + dx; + data->corners[1][1] = data->scorners[1][1] + dy; + + data->corners[2][0] = data->scorners[2][0] + dx; + data->corners[2][1] = data->scorners[2][1] - dy; + + data->corners[3][0] = data->scorners[3][0] - dx; + data->corners[3][1] = data->scorners[3][1] - dy; + } + else { + data->min[0] = data->smin[0] - dx; + data->max[0] = data->smax[0] + dx; + + data->min[1] = data->smin[1] + dy; + data->max[1] = data->smax[1] - dy; + } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_DIM); else - BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } - else { + else if (data->action == SLIDE_ACTION_OFFSET) { float d[2] = {dx, dy}; if (data->area == TRACK_AREA_SEARCH) { @@ -593,10 +723,43 @@ static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) } if (data->area == TRACK_AREA_SEARCH) - BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); + BKE_tracking_clamp_marker(data->marker, CLAMP_SEARCH_POS); + } + else if (data->action == SLIDE_ACTION_POS) { + if (data->scale) { + float scale = 1.0f + 10.0f * (dx - dy); + + if (scale > 0.0f) { + int a; + + for (a = 0; a < 4; a++) { + mul_v2_v2fl(data->corners[a], data->scorners[a], scale); + } + } + } + else { + float spos[2]; + + copy_v2_v2(spos, data->pos); + + /* corners might've been scaled before, restore their original position */ + memcpy(data->corners, data->scorners, sizeof(data->scorners)); + + data->pos[0] = data->spos[0] + dx; + data->pos[1] = data->spos[1] + dy; + + if (!slide_check_corners(data->corners)) { + copy_v2_v2(data->pos, spos); + } + } + + /* currently only patterns are allowed to have such combination of event and data */ + BKE_tracking_clamp_marker(data->marker, CLAMP_PAT_DIM); } } + data->marker->flag &= ~MARKER_TRACKED; + WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, NULL); break; @@ -635,7 +798,7 @@ void CLIP_OT_slide_marker(wmOperatorType *ot) ot->idname = "CLIP_OT_slide_marker"; /* api callbacks */ - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; ot->invoke = slide_marker_invoke; ot->modal = slide_marker_modal; @@ -669,30 +832,41 @@ static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], mouse_on_side(co, pos[0] + max[0], pos[1] + min[1], pos[0] + max[0], pos[1] + max[1], epsx, epsy); } +static int mouse_on_crns(float co[2], float pos[2], float crns[4][2], float epsx, float epsy) +{ + float dist = dist_to_crns(co, pos, crns); + + return dist < MAX2(epsx, epsy); +} + static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + float pat_min[2], pat_max[2]; float epsx, epsy; int width, height; ED_space_clip_size(sc, &width, &height); - epsx = MIN4(track->pat_min[0] - track->search_min[0], track->search_max[0] - track->pat_max[0], - fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2; - epsy = MIN4(track->pat_min[1] - track->search_min[1], track->search_max[1] - track->pat_max[1], - fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2; + BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max); + + epsx = MIN4(pat_min[0] - marker->search_min[0], marker->search_max[0] - pat_max[0], + fabsf(pat_min[0]), fabsf(pat_max[0])) / 2; + epsy = MIN4(pat_min[1] - marker->search_min[1], marker->search_max[1] - pat_max[1], + fabsf(pat_min[1]), fabsf(pat_max[1])) / 2; epsx = MAX2(epsx, 2.0f / width); epsy = MAX2(epsy, 2.0f / height); if (sc->flag & SC_SHOW_MARKER_SEARCH) { - if (mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy)) + if (mouse_on_rect(co, marker->pos, marker->search_min, marker->search_max, epsx, epsy)) return TRACK_AREA_SEARCH; } if ((marker->flag & MARKER_DISABLED) == 0) { if (sc->flag & SC_SHOW_MARKER_PATTERN) - if (mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy)) + if (mouse_on_crns(co, marker->pos, marker->pattern_corners, epsx, epsy)) return TRACK_AREA_PAT; epsx = 12.0f / width; @@ -723,29 +897,45 @@ static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) return MIN4(d1, d2, d3, d4); } +static float dist_to_crns(float co[2], float pos[2], float crns[4][2]) +{ + float d1, d2, d3, d4; + float p[2] = {co[0] - pos[0], co[1] - pos[1]}; + float *v1 = crns[0], *v2 = crns[1], + *v3 = crns[2], *v4 = crns[3]; + + d1 = dist_to_line_segment_v2(p, v1, v2); + d2 = dist_to_line_segment_v2(p, v2, v3); + d3 = dist_to_line_segment_v2(p, v3, v4); + d4 = dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, ListBase *tracksbase, float co[2]) { MovieTrackingTrack *track = NULL, *cur; float mindist = 0.0f; + int framenr = ED_space_clip_clip_framenr(sc); cur = tracksbase->first; while (cur) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(cur, framenr); if (((cur->flag & TRACK_HIDDEN) == 0) && MARKER_VISIBLE(sc, cur, marker)) { float dist, d1, d2 = FLT_MAX, d3 = FLT_MAX; /* distance to marker point */ d1 = sqrtf((co[0] - marker->pos[0] - cur->offset[0]) * (co[0] - marker->pos[0] - cur->offset[0]) + - (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); + (co[1] - marker->pos[1] - cur->offset[1]) * (co[1] - marker->pos[1] - cur->offset[1])); /* distance to pattern boundbox */ if (sc->flag & SC_SHOW_MARKER_PATTERN) - d2 = dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max); + d2 = dist_to_crns(co, marker->pos, marker->pattern_corners); /* distance to search boundbox */ if (sc->flag & SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur)) - d3 = dist_to_rect(co, marker->pos, cur->search_min, cur->search_max); + d3 = dist_to_rect(co, marker->pos, marker->search_min, marker->search_max); /* choose minimal distance. useful for cases of overlapped markers. */ dist = MIN3(d1, d2, d3); @@ -855,7 +1045,8 @@ void CLIP_OT_select(wmOperatorType *ot) /* api callbacks */ ot->exec = select_exec; ot->invoke = select_invoke; - ot->poll = ED_space_clip_tracking_poll; + //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers + ot->poll = ED_space_clip_view_clip_poll; /* flags */ ot->flag = OPTYPE_UNDO; @@ -879,6 +1070,7 @@ static int border_select_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; int change = FALSE, mode, extend; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ rect.xmin = RNA_int_get(op->ptr, "xmin"); @@ -896,7 +1088,7 @@ static int border_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { if (BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { @@ -955,6 +1147,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho ListBase *tracksbase = BKE_tracking_get_tracks(tracking); rcti rect; int change = FALSE; + int framenr = ED_space_clip_clip_framenr(sc); /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); @@ -963,7 +1156,7 @@ static int do_lasso_select_marker(bContext *C, int mcords[][2], short moves, sho track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker)) { float screen_co[2]; @@ -1057,6 +1250,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int x, y, radius, width, height, mode, change = FALSE; float zoomx, zoomy, offset[2], ellipse[2]; + int framenr = ED_space_clip_clip_framenr(sc); /* get operator properties */ x = RNA_int_get(op->ptr, "x"); @@ -1078,7 +1272,7 @@ static int circle_select_exec(bContext *C, wmOperator *op) track = tracksbase->first; while (track) { if ((track->flag & TRACK_HIDDEN) == 0) { - MovieTrackingMarker *marker = BKE_tracking_get_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); if (MARKER_VISIBLE(sc, track, marker) && marker_inside_ellipse(marker, offset, ellipse)) { BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode != GESTURE_MODAL_SELECT); @@ -1135,7 +1329,7 @@ static int select_all_exec(bContext *C, wmOperator *op) MovieTrackingMarker *marker; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int action = RNA_enum_get(op->ptr, "action"); - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int has_selection = FALSE; if (action == SEL_TOGGLE) { @@ -1225,21 +1419,22 @@ static int select_groped_exec(bContext *C, wmOperator *op) MovieTracking *tracking = &clip->tracking; ListBase *tracksbase = BKE_tracking_get_tracks(tracking); int group = RNA_enum_get(op->ptr, "group"); + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { int ok = FALSE; - marker = BKE_tracking_get_marker(track, sc->user.framenr); + marker = BKE_tracking_get_marker(track, framenr); if (group == 0) { /* Keyframed */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED) == 0; + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED) == 0; } else if (group == 1) { /* Estimated */ - ok = marker->framenr != sc->user.framenr; + ok = marker->framenr != framenr; } else if (group == 2) { /* tracked */ - ok = marker->framenr == sc->user.framenr && (marker->flag & MARKER_TRACKED); + ok = marker->framenr == framenr && (marker->flag & MARKER_TRACKED); } else if (group == 3) { /* locked */ ok = track->flag & TRACK_LOCKED; @@ -1299,7 +1494,7 @@ void CLIP_OT_select_grouped(wmOperatorType *ot) /* api callbacks */ ot->exec = select_groped_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -1332,7 +1527,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip) int tot = 0; ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); track = tracksbase->first; while (track) { @@ -1376,7 +1571,7 @@ static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit { ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int frames_limit = 0; clear_invisible_track_selection(sc, clip); @@ -1426,7 +1621,7 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward track_init_markers(sc, clip, &frames_limit); - tmj->sfra = sc->user.framenr; + tmj->sfra = ED_space_clip_clip_framenr(sc); tmj->clip = clip; tmj->backwards = backwards; @@ -1443,6 +1638,8 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward tmj->efra = MIN2(tmj->efra, tmj->sfra + frames_limit); } + tmj->efra = BKE_movieclip_remap_scene_to_clip_frame(clip, tmj->efra); + if (settings->speed != TRACKING_SPEED_FASTEST) { tmj->delay = 1.0f / scene->r.frs_sec * 1000.0f; @@ -1527,7 +1724,7 @@ static void track_markers_freejob(void *tmv) TrackMarkersJob *tmj = (TrackMarkersJob *)tmv; tmj->clip->tracking_context = NULL; - tmj->scene->r.cfra = tmj->lastfra; + tmj->scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(tmj->clip, tmj->lastfra); ED_update_for_newframe(tmj->main, tmj->scene, 0); BKE_tracking_sync(tmj->context); @@ -1544,7 +1741,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip(sc); Scene *scene = CTX_data_scene(C); struct MovieTrackingContext *context; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); int sfra = framenr, efra; int backwards = RNA_boolean_get(op->ptr, "backwards"); int sequence = RNA_boolean_get(op->ptr, "sequence"); @@ -1568,6 +1765,8 @@ static int track_markers_exec(bContext *C, wmOperator *op) efra = MIN2(efra, sfra + frames_limit); } + efra = BKE_movieclip_remap_scene_to_clip_frame(clip, efra); + if (!track_markers_check_direction(backwards, framenr, efra)) return OPERATOR_CANCELLED; @@ -1589,7 +1788,7 @@ static int track_markers_exec(bContext *C, wmOperator *op) BKE_tracking_context_free(context); /* update scene current frame to the lastes tracked frame */ - scene->r.cfra = framenr; + scene->r.cfra = BKE_movieclip_remap_clip_to_scene_frame(clip, framenr); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -1680,7 +1879,7 @@ void CLIP_OT_track_markers(wmOperatorType *ot) /* api callbacks */ ot->exec = track_markers_exec; ot->invoke = track_markers_invoke; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; ot->modal = track_markers_modal; /* flags */ @@ -1967,16 +2166,17 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); int action = RNA_enum_get(op->ptr, "action"); int clear_active = RNA_boolean_get(op->ptr, "clear_active"); + int framenr = ED_space_clip_clip_framenr(sc); if (clear_active) { track = BKE_tracking_active_track(&clip->tracking); - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); } else { track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) - BKE_tracking_clear_path(track, sc->user.framenr, action); + BKE_tracking_clear_path(track, framenr, action); track = track->next; } @@ -2023,10 +2223,11 @@ static int disable_markers_exec(bContext *C, wmOperator *op) ListBase *tracksbase = BKE_tracking_get_tracks(tracking); MovieTrackingTrack *track = tracksbase->first; int action = RNA_enum_get(op->ptr, "action"); + int framenr = ED_space_clip_clip_framenr(sc); while (track) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); if (action == 0) marker->flag |= MARKER_DISABLED; @@ -2119,18 +2320,22 @@ static Object *get_orientation_object(bContext *C) static int set_orientation_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { Scene *scene = CTX_data_scene(C); - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { - return TRUE; - } - else { - return OBACT != NULL; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { + return TRUE; + } + else { + return OBACT != NULL; + } } } @@ -2729,16 +2934,20 @@ void CLIP_OT_set_scale(wmOperatorType *ot) static int set_solution_scale_poll(bContext *C) { - if (ED_space_clip_tracking_size_poll(C)) { - SpaceClip *sc = CTX_wm_space_clip(C); + SpaceClip *sc = CTX_wm_space_clip(C); + + if (sc) { MovieClip *clip = ED_space_clip(sc); - MovieTracking *tracking = &clip->tracking; - MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); - return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + if (clip) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object = BKE_tracking_active_object(tracking); + + return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; + } } - return 0; + return FALSE; } static int set_solution_scale_exec(bContext *C, wmOperator *op) @@ -2945,8 +3154,14 @@ static int detect_features_exec(bContext *C, wmOperator *op) int min_trackability = RNA_int_get(op->ptr, "min_trackability"); int min_distance = RNA_int_get(op->ptr, "min_distance"); int place_outside_layer = 0; + int framenr = ED_space_clip_clip_framenr(sc); bGPDlayer *layer = NULL; + if (!ibuf) { + BKE_report(op->reports, RPT_ERROR, "Feature detection requires valid clip frame"); + return OPERATOR_CANCELLED; + } + if (placement != 0) { layer = detect_get_layer(clip); place_outside_layer = placement == 2; @@ -2961,7 +3176,7 @@ static int detect_features_exec(bContext *C, wmOperator *op) track = track->next; } - BKE_tracking_detect_fast(tracking, tracksbase, ibuf, sc->user.framenr, margin, + BKE_tracking_detect_fast(tracking, tracksbase, ibuf, framenr, margin, min_trackability, min_distance, layer, place_outside_layer); IMB_freeImBuf(ibuf); @@ -2987,7 +3202,7 @@ void CLIP_OT_detect_features(wmOperatorType *ot) /* api callbacks */ ot->exec = detect_features_exec; - ot->poll = ED_space_clip_tracking_frame_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3019,7 +3234,8 @@ static int frame_jump_exec(bContext *C, wmOperator *op) delta = pos == 1 ? 1 : -1; while (sc->user.framenr + delta >= SFRA && sc->user.framenr + delta <= EFRA) { - MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, sc->user.framenr + delta); + int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr + delta); + MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr); if (!marker || marker->flag & MARKER_DISABLED) break; @@ -3029,7 +3245,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) } else { /* to to failed frame */ if (clip->tracking.reconstruction.flag & TRACKING_RECONSTRUCTED) { - int a = sc->user.framenr; + int a = ED_space_clip_clip_framenr(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *object = BKE_tracking_active_object(tracking); @@ -3043,7 +3259,7 @@ static int frame_jump_exec(bContext *C, wmOperator *op) cam = BKE_tracking_get_reconstructed_camera(tracking, object, a); if (!cam) { - sc->user.framenr = a; + sc->user.framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, a); break; } @@ -3139,7 +3355,7 @@ void CLIP_OT_join_tracks(wmOperatorType *ot) /* api callbacks */ ot->exec = join_tracks_exec; - ot->poll = ED_space_clip_tracking_size_poll; + ot->poll = ED_space_clip_tracking_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_console/console_intern.h b/source/blender/editors/space_console/console_intern.h index c0abd094e62..3d30dcad710 100644 --- a/source/blender/editors/space_console/console_intern.h +++ b/source/blender/editors/space_console/console_intern.h @@ -54,6 +54,9 @@ void CONSOLE_OT_move(struct wmOperatorType *ot); void CONSOLE_OT_delete(struct wmOperatorType *ot); void CONSOLE_OT_insert(struct wmOperatorType *ot); +void CONSOLE_OT_indent(struct wmOperatorType *ot); +void CONSOLE_OT_unindent(struct wmOperatorType *ot); + void CONSOLE_OT_history_append(struct wmOperatorType *ot); void CONSOLE_OT_scrollback_append(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 5ed384d22af..7efcbcceb3c 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -364,9 +364,8 @@ static int console_insert_exec(bContext *C, wmOperator *op) char *str = RNA_string_get_alloc(op->ptr, "text", NULL, 0); int len; - // XXX, alligned tab key hack if (str[0] == '\t' && str[1] == '\0') { - len = TAB_LENGTH - (ci->cursor % TAB_LENGTH); + len = TAB_LENGTH; MEM_freeN(str); str = MEM_mallocN(len + 1, "insert_exec"); memset(str, ' ', len); @@ -430,6 +429,95 @@ void CONSOLE_OT_insert(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } +static int console_indent_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceConsole *sc = CTX_wm_space_console(C); + ARegion *ar = CTX_wm_region(C); + ConsoleLine *ci = console_history_verify(C); + int spaces; + int len; + + for (spaces = 0; spaces < ci->len; spaces++) { + if (ci->line[spaces] != ' ') + break; + } + + len = TAB_LENGTH - spaces % TAB_LENGTH; + + console_line_verify_length(ci, ci->len + len); + + memmove(ci->line + len, ci->line, ci->len); + memset(ci->line, ' ', len); + ci->len += len; + console_line_cursor_set(ci, ci->cursor + len); + + console_textview_update_rect(sc, ar); + ED_area_tag_redraw(CTX_wm_area(C)); + + console_scroll_bottom(ar); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_indent(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Indent"; + ot->description = "Add 4 spaces at line beginning"; + ot->idname = "CONSOLE_OT_indent"; + + /* api callbacks */ + ot->exec = console_indent_exec; + ot->poll = ED_operator_console_active; +} + +static int console_unindent_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceConsole *sc = CTX_wm_space_console(C); + ARegion *ar = CTX_wm_region(C); + ConsoleLine *ci = console_history_verify(C); + int spaces; + int len; + + for (spaces = 0; spaces < ci->len; spaces++) { + if (ci->line[spaces] != ' ') + break; + } + + if (spaces == 0) + return OPERATOR_CANCELLED; + + len = spaces % TAB_LENGTH; + if (len == 0) + len = TAB_LENGTH; + + console_line_verify_length(ci, ci->len - len); + + memmove(ci->line, ci->line + len, (ci->len - len) + 1); + ci->len -= len; + console_line_cursor_set(ci, ci->cursor - len); + + //console_select_offset(sc, -4); + + console_textview_update_rect(sc, ar); + ED_area_tag_redraw(CTX_wm_area(C)); + + console_scroll_bottom(ar); + + return OPERATOR_FINISHED; +} + +void CONSOLE_OT_unindent(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Unindent"; + ot->description = "Delete 4 spaces from line beginning"; + ot->idname = "CONSOLE_OT_unindent"; + + /* api callbacks */ + ot->exec = console_unindent_exec; + ot->poll = ED_operator_console_active; +} static EnumPropertyItem console_delete_type_items[] = { {DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""}, @@ -757,7 +845,8 @@ void CONSOLE_OT_scrollback_append(wmOperatorType *ot) {CONSOLE_LINE_INPUT, "INPUT", 0, "Input", ""}, {CONSOLE_LINE_INFO, "INFO", 0, "Information", ""}, {CONSOLE_LINE_ERROR, "ERROR", 0, "Error", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Scrollback Append"; diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c index a25606db2b3..460b31d69bd 100644 --- a/source/blender/editors/space_console/space_console.c +++ b/source/blender/editors/space_console/space_console.c @@ -246,6 +246,9 @@ static void console_operatortypes(void) WM_operatortype_append(CONSOLE_OT_move); WM_operatortype_append(CONSOLE_OT_delete); WM_operatortype_append(CONSOLE_OT_insert); + + WM_operatortype_append(CONSOLE_OT_indent); + WM_operatortype_append(CONSOLE_OT_unindent); /* for use by python only */ WM_operatortype_append(CONSOLE_OT_history_append); @@ -332,7 +335,11 @@ static void console_keymap(struct wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CONSOLE_OT_select_set", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, 0, 0)->ptr, "text", "\t"); /* fake tabs */ + RNA_string_set(WM_keymap_add_item(keymap, "CONSOLE_OT_insert", TABKEY, KM_PRESS, KM_CTRL, 0)->ptr, "text", "\t"); /* fake tabs */ + + WM_keymap_add_item(keymap, "CONSOLE_OT_indent", TABKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_unindent", TABKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CONSOLE_OT_insert", KM_TEXTINPUT, KM_ANY, KM_ANY, 0); // last! } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 27f8ae59919..afd04697e5e 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -102,8 +102,7 @@ typedef struct ThumbnailJob { ReportList reports; } ThumbnailJob; -typedef struct FileList -{ +typedef struct FileList { struct direntry *filelist; int *fidx; int numfiles; @@ -124,8 +123,7 @@ typedef struct FileList } FileList; -typedef struct FolderList -{ +typedef struct FolderList { struct FolderList *next, *prev; char *foldername; } FolderList; diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index fac6a387b9f..7a37c5fb3c5 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -53,8 +53,7 @@ typedef enum FileSelType { FILE_SEL_TOGGLE = 2 } FileSelType; -typedef enum FileCheckType -{ +typedef enum FileCheckType { CHECK_DIRS = 1, CHECK_FILES = 2, CHECK_ALL = 3 diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 6e52056ff2b..332a2ecada4 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -637,6 +637,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char ima = imaptr.data; iuser = userptr->data; + BKE_image_user_check_frame_calc(iuser, (int)scene->r.cfra, 0); + cb = MEM_callocN(sizeof(RNAUpdateCb), "RNAUpdateCb"); cb->ptr = *ptr; cb->prop = prop; diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index aab628180c8..998ebac1cb9 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -564,16 +564,9 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) { /* draw in View2D space? */ if (onlyv2d) { - /* assume that UI_view2d_ortho(C) has been called... */ - SpaceImage *sima = (SpaceImage *)CTX_wm_space_data(C); - void *lock; - ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock); - /* draw grease-pencil ('image' strokes) */ //if (sima->flag & SI_DISPGP) - draw_gpencil_2dimage(C, ibuf); - - ED_space_image_release_buffer(sima, lock); + draw_gpencil_2dimage(C); } else { /* assume that UI_view2d_restore(C) has been called... */ @@ -585,6 +578,28 @@ void draw_image_grease_pencil(bContext *C, short onlyv2d) } } +void draw_image_sample_line(SpaceImage *sima) +{ + if (sima->sample_line_hist.flag & HISTO_FLAG_SAMPLELINE) { + Histogram *hist = &sima->sample_line_hist; + + glBegin(GL_LINES); + glColor3ub(0, 0, 0); + glVertex2fv(hist->co[0]); + glVertex2fv(hist->co[1]); + glEnd(); + + setlinestyle(1); + glBegin(GL_LINES); + glColor3ub(255, 255, 255); + glVertex2fv(hist->co[0]); + glVertex2fv(hist->co[1]); + glEnd(); + setlinestyle(0); + + } +} + /* XXX becomes WM paint cursor */ #if 0 static void draw_image_view_tool(Scene *scene) diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 121130ec536..0d3a7614f10 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -54,6 +54,7 @@ extern const char *image_context_dir[]; /* doc access */ /* image_draw.c */ void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); +void draw_image_sample_line(struct SpaceImage *sima); /* image_ops.c */ int space_image_main_area_poll(struct bContext *C); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 2cb36841082..97f3bd744dc 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2137,13 +2137,20 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) hist->x_resolution = 256; hist->xmax = 1.0f; hist->ymax = 1.0f; - + + /* persistent draw */ + hist->co[0][0] = x1f; + hist->co[0][1] = y1f; + hist->co[1][0] = x2f; + hist->co[1][1] = y2f; + hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */ + for (i = 0; i < 256; i++) { x = (int)(0.5f + x1 + (float)i * (x2 - x1) / 255.0f); y = (int)(0.5f + y1 + (float)i * (y2 - y1) / 255.0f); if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { - hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = 0.0f; + hist->data_luma[i] = hist->data_r[i] = hist->data_g[i] = hist->data_b[i] = hist->data_a[i] = 0.0f; } else { if (ibuf->rect_float) { @@ -2154,17 +2161,19 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) else copy_v3_v3(rgb, fp); - hist->data_r[i] = rgb[0]; - hist->data_g[i] = rgb[1]; - hist->data_b[i] = rgb[2]; - hist->data_luma[i] = rgb_to_luma(rgb); + hist->data_luma[i] = rgb_to_luma(rgb); + hist->data_r[i] = rgb[0]; + hist->data_g[i] = rgb[1]; + hist->data_b[i] = rgb[2]; + hist->data_a[i] = fp[3]; } else if (ibuf->rect) { cp = (unsigned char *)(ibuf->rect + y * ibuf->x + x); - hist->data_r[i] = (float)cp[0] / 255.0f; - hist->data_g[i] = (float)cp[1] / 255.0f; - hist->data_b[i] = (float)cp[2] / 255.0f; - hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; + hist->data_luma[i] = (float)rgb_to_luma_byte(cp) / 255.0f; + hist->data_r[i] = (float)cp[0] / 255.0f; + hist->data_g[i] = (float)cp[1] / 255.0f; + hist->data_b[i] = (float)cp[2] / 255.0f; + hist->data_a[i] = (float)cp[3] / 255.0f; } } } @@ -2179,7 +2188,10 @@ static int image_sample_line_exec(bContext *C, wmOperator *op) static int image_sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceImage *sima = CTX_wm_space_image(C); - + + Histogram *hist = &sima->sample_line_hist; + hist->flag &= ~HISTO_FLAG_SAMPLELINE; + if (!ED_space_image_has_buffer(sima)) return OPERATOR_CANCELLED; @@ -2443,56 +2455,15 @@ void IMAGE_OT_cycle_render_slot(wmOperatorType *ot) /* goes over all ImageUsers, and sets frame numbers if auto-refresh is set */ +static void image_update_frame(struct Image *UNUSED(ima), struct ImageUser *iuser, void *customdata) +{ + int cfra = *(int*)customdata; + + BKE_image_user_check_frame_calc(iuser, cfra, 0); +} + void ED_image_update_frame(const Main *mainp, int cfra) { - wmWindowManager *wm; - wmWindow *win; - Tex *tex; - - /* texture users */ - for (tex = mainp->tex.first; tex; tex = tex->id.next) { - if (tex->type == TEX_IMAGE && tex->ima) { - if (ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { - if (tex->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&tex->iuser, cfra, 0); - } - } - } - - /* image window, compo node users */ - for (wm = mainp->wm.first; wm; wm = wm->id.next) { /* only 1 wm */ - for (win = wm->windows.first; win; win = win->next) { - ScrArea *sa; - for (sa = win->screen->areabase.first; sa; sa = sa->next) { - if (sa->spacetype == SPACE_VIEW3D) { - View3D *v3d = sa->spacedata.first; - BGpic *bgpic; - for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) - if (bgpic->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&bgpic->iuser, cfra, 0); - } - else if (sa->spacetype == SPACE_IMAGE) { - SpaceImage *sima = sa->spacedata.first; - if (sima->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&sima->iuser, cfra, 0); - } - else if (sa->spacetype == SPACE_NODE) { - SpaceNode *snode = sa->spacedata.first; - if ((snode->treetype == NTREE_COMPOSIT) && (snode->nodetree)) { - bNode *node; - for (node = snode->nodetree->nodes.first; node; node = node->next) { - if (node->id && node->type == CMP_NODE_IMAGE) { - Image *ima = (Image *)node->id; - ImageUser *iuser = node->storage; - if (ELEM(ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) - if (iuser->flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(iuser, cfra, 0); - } - } - } - } - } - } - } + BKE_image_walk_all_users(mainp, &cfra, image_update_frame); } diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index a8d83500cc1..6652a7470c2 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -590,8 +590,7 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) ima = ED_space_image(sima); - if (sima->iuser.flag & IMA_ANIM_ALWAYS) - BKE_image_user_frame_calc(&sima->iuser, scene->r.cfra, 0); + BKE_image_user_check_frame_calc(&sima->iuser, scene->r.cfra, 0); /* check if we have to set the image from the editmesh */ if (ima && (ima->source == IMA_SRC_VIEWER || sima->pin)) ; @@ -825,15 +824,18 @@ static void image_main_area_draw(const bContext *C, ARegion *ar) draw_uvedit_main(sima, ar, scene, obedit, obact); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - + /* Grease Pencil too (in addition to UV's) */ draw_image_grease_pencil((bContext *)C, 1); + /* sample line */ + draw_image_sample_line(sima); + UI_view2d_view_restore(C); /* draw Grease Pencil - screen space only */ draw_image_grease_pencil((bContext *)C, 0); - + /* scrollers? */ #if 0 scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_UNIT_VALUES, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c index dd21fca93ce..0eec61f599e 100644 --- a/source/blender/editors/space_logic/logic_window.c +++ b/source/blender/editors/space_logic/logic_window.c @@ -1151,155 +1151,155 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short uiBut *but; short ysize; const char *str; - + /* yco is at the top of the rect, draw downwards */ - + set_col_sensor(sens->type, 0); - + switch (sens->type) { - case SENS_ALWAYS: + case SENS_ALWAYS: { ysize= 24; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); - + yco-= ysize; - + break; } - case SENS_TOUCH: + case SENS_TOUCH: { - ysize= 48; - - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + ysize= 48; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); - - ts= sens->data; - + + ts= sens->data; + // uiDefBut(block, TEX, 1, "Property:", xco, yco-22, width, 19, &ts->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); uiDefIDPoinBut(block, test_matpoin_but, ID_MA, 1, "MA:", (short)(xco + 10), (short)(yco-44), (short)(width - 20), 19, &ts->ma, "Only look for floors with this Material"); // uiDefButF(block, NUM, 1, "Margin:", xco+width/2, yco-44, width/2, 19, &ts->dist, 0.0, 10.0, 100, 0, "Extra margin (distance) for larger sensitivity"); - yco-= ysize; - break; + yco-= ysize; + break; } - case SENS_COLLISION: + case SENS_COLLISION: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); cs= sens->data; - + /* The collision sensor will become a generic collision (i.e. it */ /* absorb the old touch sensor). */ uiDefButBitS(block, TOG, SENS_COLLISION_PULSE, B_REDR, "Pulse", (short)(xco + 10), (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Changes to the set of colliding objects generated pulses"); - + (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, + "Changes to the set of colliding objects generated pulses"); + uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P", (short)(xco + 10 + (0.20 * (width-20))), (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property"); - + (short)(0.20 * (width-20)), 19, &cs->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property"); + if (cs->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", (short)(xco + 10 + 0.40 * (width-20)), - (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, MAX_NAME, 0, 0, - "Only look for Objects with this material"); + (short)(yco-44), (short)(0.6*(width-20)), 19, &cs->materialName, 0, MAX_NAME, 0, 0, + "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", (short)(xco + 10 + 0.40 * (width-20)), (short)(yco-44), - (short)(0.6*(width-20)), 19, &cs->name, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + (short)(0.6*(width-20)), 19, &cs->name, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); } - + /* uiDefButS(block, NUM, 1, "Damp:", xco+10+width-90, yco-24, 70, 19, &cs->damp, 0, 250, 0, 0, "For 'damp' time don't detect another collision"); */ - + yco-= ysize; break; } - case SENS_NEAR: + case SENS_NEAR: { ysize= 72; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); ns= sens->data; - + uiDefBut(block, TEX, 1, "Property:", (short)(10+xco), (short)(yco-44), (short)(width-20), 19, - &ns->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); + &ns->name, 0, MAX_NAME, 0, 0, "Only look for Objects with this property"); uiDefButF(block, NUM, 1, "Dist", (short)(10+xco), (short)(yco-68), (short)((width-22)/2), 19, - &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); + &ns->dist, 0.0, 1000.0, 1000, 0, "Trigger distance"); uiDefButF(block, NUM, 1, "Reset", (short)(10+xco+(width-22)/2), (short)(yco-68), (short)((width-22)/2), 19, - &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); + &ns->resetdist, 0.0, 1000.0, 1000, 0, "Reset distance"); yco-= ysize; break; } - case SENS_RADAR: + case SENS_RADAR: { - ysize= 72; - + ysize= 72; + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); - + rs= sens->data; - + uiDefBut(block, TEX, 1, "Prop:", - (short)(10+xco), (short)(yco-44), (short)(0.7 * (width-20)), 19, - &rs->name, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + (short)(10+xco), (short)(yco-44), (short)(0.7 * (width-20)), 19, + &rs->name, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); - str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; + str = "Type %t|+X axis %x0|+Y axis %x1|+Z axis %x2|-X axis %x3|-Y axis %x4|-Z axis %x5"; uiDefButS(block, MENU, B_REDR, str, - (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19, - &rs->axis, 2.0, 31, 0, 0, - "Specify along which axis the radar cone is cast"); - + (short)(10+xco+0.7 * (width-20)), (short)(yco-44), (short)(0.3 * (width-22)), 19, + &rs->axis, 2.0, 31, 0, 0, + "Specify along which axis the radar cone is cast"); + uiDefButF(block, NUM, 1, "Ang:", - (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, - &rs->angle, 0.0, 179.9, 10, 0, - "Opening angle of the radar cone"); + (short)(10+xco), (short)(yco-68), (short)((width-20)/2), 19, + &rs->angle, 0.0, 179.9, 10, 0, + "Opening angle of the radar cone"); uiDefButF(block, NUM, 1, "Dist:", - (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, - &rs->range, 0.01, 10000.0, 100, 0, - "Depth of the radar cone"); + (short)(xco+10 + (width-20)/2), (short)(yco-68), (short)((width-20)/2), 19, + &rs->range, 0.01, 10000.0, 100, 0, + "Depth of the radar cone"); yco-= ysize; break; } - case SENS_KEYBOARD: + case SENS_KEYBOARD: { ks= sens->data; - + /* 5 lines: 120 height */ ysize= (ks->type&1) ? 96:120; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* header line */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* part of line 1 */ uiDefBut(block, LABEL, 0, "Key", xco, yco-44, 40, 19, NULL, 0, 0, 0, 0, ""); uiDefButBitS(block, TOG, 1, B_REDR, "All keys", xco+40+(width/2), yco-44, (width/2)-50, 19, - &ks->type, 0, 0, 0, 0, ""); - - + &ks->type, 0, 0, 0, 0, ""); + + if ((ks->type&1)==0) { /* is All Keys option off? */ /* line 2: hotkey and allkeys toggle */ but = uiDefKeyevtButS(block, 0, "", xco+40, yco-44, (width)/2, 19, &ks->key, "Key code"); uiButSetFunc(but, test_keyboard_event, ks, NULL); - + /* line 3: two key modifyers (qual1, qual2) */ uiDefBut(block, LABEL, 0, "Hold", xco, yco-68, 40, 19, NULL, 0, 0, 0, 0, ""); but = uiDefKeyevtButS(block, 0, "", xco+40, yco-68, (width-50)/2, 19, &ks->qual, "Modifier key code"); @@ -1307,50 +1307,50 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short but = uiDefKeyevtButS(block, 0, "", xco+40+(width-50)/2, yco-68, (width-50)/2, 19, &ks->qual2, "Second Modifier key code"); uiButSetFunc(but, test_keyboard_event, ks, NULL); } - + /* line 4: toggle property for string logging mode */ uiDefBut(block, TEX, 1, "LogToggle: ", - xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, - ks->toggleName, 0, MAX_NAME, 0, 0, - "Property that indicates whether to log " - "keystrokes as a string"); - + xco+10, yco-((ks->type&1) ? 68:92), (width-20), 19, + ks->toggleName, 0, MAX_NAME, 0, 0, + "Property that indicates whether to log " + "keystrokes as a string"); + /* line 5: target property for string logging mode */ uiDefBut(block, TEX, 1, "Target: ", - xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, - ks->targetName, 0, MAX_NAME, 0, 0, - "Property that receives the keystrokes in case " - "a string is logged"); - + xco+10, yco-((ks->type&1) ? 92:116), (width-20), 19, + ks->targetName, 0, MAX_NAME, 0, 0, + "Property that receives the keystrokes in case " + "a string is logged"); + yco-= ysize; break; } - case SENS_PROPERTY: + case SENS_PROPERTY: { ysize= 96; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); ps= sens->data; - - str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; + + str= "Type %t|Equal %x0|Not Equal %x1|Interval %x2|Changed %x3"; /* str= "Type %t|Equal %x0|Not Equal %x1"; */ uiDefButI(block, MENU, B_REDR, str, xco+30, yco-44, width-60, 19, - &ps->type, 0, 31, 0, 0, "Type"); - + &ps->type, 0, 31, 0, 0, "Type"); + if (ps->type != SENS_PROP_EXPRESSION) { uiDefBut(block, TEX, 1, "Prop: ", xco+30, yco-68, width-60, 19, - ps->name, 0, MAX_NAME, 0, 0, "Property name"); + ps->name, 0, MAX_NAME, 0, 0, "Property name"); } - + if (ps->type == SENS_PROP_INTERVAL) { uiDefBut(block, TEX, 1, "Min: ", xco, yco-92, width/2, 19, - ps->value, 0, MAX_NAME, 0, 0, "check for min value"); + ps->value, 0, MAX_NAME, 0, 0, "check for min value"); uiDefBut(block, TEX, 1, "Max: ", xco+width/2, yco-92, width/2, 19, - ps->maxvalue, 0, MAX_NAME, 0, 0, "check for max value"); + ps->maxvalue, 0, MAX_NAME, 0, 0, "check for max value"); } else if (ps->type == SENS_PROP_CHANGED) { /* pass */ @@ -1359,199 +1359,199 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short uiDefBut(block, TEX, 1, "Value: ", xco+30, yco-92, width-60, 19, ps->value, 0, MAX_NAME, 0, 0, "check for value"); } - + yco-= ysize; break; } - case SENS_ARMATURE: + case SENS_ARMATURE: { ysize= 70; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); arm= sens->data; if (ob->type == OB_ARMATURE) { uiBlockBeginAlign(block); but = uiDefBut(block, TEX, 1, "Bone: ", - (xco+10), (yco-44), (width-20)/2, 19, - arm->posechannel, 0, MAX_NAME, 0, 0, - "Bone on which you want to check a constraint"); + (xco+10), (yco-44), (width-20)/2, 19, + arm->posechannel, 0, MAX_NAME, 0, 0, + "Bone on which you want to check a constraint"); uiButSetFunc(but, check_armature_sensor, but, arm); but = uiDefBut(block, TEX, 1, "Cons: ", - (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19, - arm->constraint, 0, MAX_NAME, 0, 0, - "Name of the constraint you want to control"); + (xco+10)+(width-20)/2, (yco-44), (width-20)/2, 19, + arm->constraint, 0, MAX_NAME, 0, 0, + "Name of the constraint you want to control"); uiButSetFunc(but, check_armature_sensor, but, arm); uiBlockEndAlign(block); - str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4"; + str= "Type %t|State changed %x0|Lin error below %x1|Lin error above %x2|Rot error below %x3|Rot error above %x4"; uiDefButI(block, MENU, B_REDR, str, xco+10, yco-66, 0.4*(width-20), 19, - &arm->type, 0, 31, 0, 0, "Type"); - + &arm->type, 0, 31, 0, 0, "Type"); + if (arm->type != SENS_ARM_STATE_CHANGED) { uiDefButF(block, NUM, 1, "Value: ", xco+10+0.4*(width-20), yco-66, 0.6*(width-20), 19, - &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value"); + &arm->value, -10000.0, 10000.0, 100, 0, "Test the error against this value"); } } yco-= ysize; break; } - case SENS_ACTUATOR: + case SENS_ACTUATOR: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); as= sens->data; - + uiDefBut(block, TEX, 1, "Act: ", xco+30, yco-44, width-60, 19, - as->name, 0, MAX_NAME, 0, 0, "Actuator name, actuator active state modifications will be detected"); + as->name, 0, MAX_NAME, 0, 0, "Actuator name, actuator active state modifications will be detected"); yco-= ysize; break; } - case SENS_DELAY: + case SENS_DELAY: { ysize= 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + draw_default_sensor_header(sens, block, xco, yco, width); ds = sens->data; - + uiDefButS(block, NUM, 0, "Delay", (short)(10+xco), (short)(yco-44), (short)((width-22)*0.4+10), 19, - &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of logic tics before the positive trigger (default 60 per second)"); + &ds->delay, 0.0, 5000.0, 0, 0, "Delay in number of logic tics before the positive trigger (default 60 per second)"); uiDefButS(block, NUM, 0, "Dur", (short)(10+xco+(width-22)*0.4+10), (short)(yco-44), (short)((width-22)*0.4-10), 19, - &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of logic tics before the negative trigger following the positive trigger"); + &ds->duration, 0.0, 5000.0, 0, 0, "If >0, delay in number of logic tics before the negative trigger following the positive trigger"); uiDefButBitS(block, TOG, SENS_DELAY_REPEAT, 0, "REP", (short)(xco + 10 + (width-22)*0.8), (short)(yco - 44), - (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0, - "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics"); + (short)(0.20 * (width-22)), 19, &ds->flag, 0.0, 0.0, 0, 0, + "Toggle repeat option. If selected, the sensor restarts after Delay+Dur logic tics"); yco-= ysize; break; } - case SENS_MOUSE: + case SENS_MOUSE: { ms= sens->data; /* Two lines: 48 pixels high. */ ysize = 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* line 1: header */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* Line 2: type selection. The number are a bit mangled to get * proper compatibility with older .blend files. */ /* Any sensor type default is 0 but the ms enum starts in 1. * Therefore the mouse sensor is initialized to 1 in sca.c */ str= "Type %t|Left button %x1|Middle button %x2|" - "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; + "Right button %x4|Wheel Up %x5|Wheel Down %x6|Movement %x8|Mouse over %x16|Mouse over any%x32"; uiDefButS(block, MENU, B_REDR, str, xco+10, yco-44, (width*0.8f)-20, 19, - &ms->type, 0, 31, 0, 0, - "Specify the type of event this mouse sensor should trigger on"); - + &ms->type, 0, 31, 0, 0, + "Specify the type of event this mouse sensor should trigger on"); + if (ms->type==32) { uiDefButBitS(block, TOG, SENS_MOUSE_FOCUS_PULSE, B_REDR, "Pulse", (short)(xco + 10) + (width*0.8f)-20, (short)(yco - 44), - (short)(0.20 * (width-20)), 19, &ms->flag, 0.0, 0.0, 0, 0, - "Moving the mouse over a different object generates a pulse"); + (short)(0.20 * (width-20)), 19, &ms->flag, 0.0, 0.0, 0, 0, + "Moving the mouse over a different object generates a pulse"); } - + yco-= ysize; break; } - case SENS_RANDOM: + case SENS_RANDOM: { ysize = 48; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); randomSensor = sens->data; /* some files were wrongly written, avoid crash now */ if (randomSensor) { uiDefButI(block, NUM, 1, "Seed: ", xco+10, yco-44, (width-20), 19, - &randomSensor->seed, 0, 1000, 0, 0, - "Initial seed of the generator. (Choose 0 for not random)"); + &randomSensor->seed, 0, 1000, 0, 0, + "Initial seed of the generator. (Choose 0 for not random)"); } yco-= ysize; break; } - case SENS_RAY: + case SENS_RAY: { ysize = 72; glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + draw_default_sensor_header(sens, block, xco, yco, width); raySens = sens->data; - + /* 1. property or material */ uiDefButBitS(block, TOG, SENS_COLLISION_MATERIAL, B_REDR, "M/P", - xco + 10, yco - 44, 0.20 * (width-20), 19, - &raySens->mode, 0.0, 0.0, 0, 0, - "Toggle collision on material or property"); - + xco + 10, yco - 44, 0.20 * (width-20), 19, + &raySens->mode, 0.0, 0.0, 0, 0, + "Toggle collision on material or property"); + if (raySens->mode & SENS_COLLISION_MATERIAL) { uiDefBut(block, TEX, 1, "Material:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->matname, 0, MAX_NAME, 0, 0, - "Only look for Objects with this material"); + &raySens->matname, 0, MAX_NAME, 0, 0, + "Only look for Objects with this material"); } else { uiDefBut(block, TEX, 1, "Property:", xco + 10 + 0.20 * (width-20), yco-44, 0.8*(width-20), 19, - &raySens->propname, 0, MAX_NAME, 0, 0, - "Only look for Objects with this property"); + &raySens->propname, 0, MAX_NAME, 0, 0, + "Only look for Objects with this property"); } /* X-Ray option */ uiDefButBitS(block, TOG, SENS_RAY_XRAY, 1, "X", - xco + 10, yco - 68, 0.10 * (width-20), 19, - &raySens->mode, 0.0, 0.0, 0, 0, - "Toggle X-Ray option (see through objects that don't have the property)"); + xco + 10, yco - 68, 0.10 * (width-20), 19, + &raySens->mode, 0.0, 0.0, 0, 0, + "Toggle X-Ray option (see through objects that don't have the property)"); /* 2. sensing range */ uiDefButF(block, NUM, 1, "Range", xco+10 + 0.10 * (width-20), yco-68, 0.5 * (width-20), 19, - &raySens->range, 0.01, 10000.0, 100, 0, - "Sense objects no farther than this distance"); - + &raySens->range, 0.01, 10000.0, 100, 0, + "Sense objects no farther than this distance"); + /* 3. axis choice */ - str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; + str = "Type %t|+ X axis %x1|+ Y axis %x0|+ Z axis %x2|- X axis %x3|- Y axis %x4|- Z axis %x5"; uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &raySens->axisflag, 2.0, 31, 0, 0, - "Specify along which axis the ray is cast"); - - yco-= ysize; + &raySens->axisflag, 2.0, 31, 0, 0, + "Specify along which axis the ray is cast"); + + yco-= ysize; break; } - case SENS_MESSAGE: + case SENS_MESSAGE: { mes = sens->data; ysize = 2 * 24; /* total number of lines * 24 pixels/line */ - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - + (float)xco+width, (float)yco, 1); + /* line 1: header line */ draw_default_sensor_header(sens, block, xco, yco, width); - + /* line 2: Subject filter */ uiDefBut(block, TEX, 1, "Subject: ", - (xco+10), (yco-44), (width-20), 19, - mes->subject, 0, MAX_NAME, 0, 0, - "Optional subject filter: only accept messages with this subject" - ", or empty for all"); - + (xco+10), (yco-44), (width-20), 19, + mes->subject, 0, MAX_NAME, 0, 0, + "Optional subject filter: only accept messages with this subject" + ", or empty for all"); + yco -= ysize; break; } @@ -1559,96 +1559,96 @@ static short draw_sensorbuttons(Object *ob, bSensor *sens, uiBlock *block, short { ysize = 72; - + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - + /* line 1: header */ draw_default_sensor_header(sens, block, xco, yco, width); joy= sens->data; uiDefButC(block, NUM, 1, "Index:", xco+10, yco-44, 0.33 * (width-20), 19, - &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0, - "Specify which joystick to use"); + &joy->joyindex, 0, SENS_JOY_MAXINDEX-1, 100, 0, + "Specify which joystick to use"); - str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; + str= "Type %t|Button %x0|Axis %x1|Single Axis %x3|Hat%x2"; uiDefButC(block, MENU, B_REDR, str, xco+87, yco-44, 0.26 * (width-20), 19, - &joy->type, 0, 31, 0, 0, - "The type of event this joystick sensor is triggered on"); - + &joy->type, 0, 31, 0, 0, + "The type of event this joystick sensor is triggered on"); + if (joy->type != SENS_JOY_AXIS_SINGLE) { if (joy->flag & SENS_JOY_ANY_EVENT) { switch (joy->type) { - case SENS_JOY_AXIS: - str = "All Axis Events"; - break; - case SENS_JOY_BUTTON: - str = "All Button Events"; - break; - default: - str = "All Hat Events"; - break; + case SENS_JOY_AXIS: + str = "All Axis Events"; + break; + case SENS_JOY_BUTTON: + str = "All Button Events"; + break; + default: + str = "All Hat Events"; + break; } } else { str = "All"; } - + uiDefButBitS(block, TOG, SENS_JOY_ANY_EVENT, B_REDR, str, - xco+10 + 0.475 * (width-20), yco-68, ((joy->flag & SENS_JOY_ANY_EVENT) ? 0.525 : 0.12) * (width-20), 19, - &joy->flag, 0, 0, 0, 0, - "Triggered by all events on this joysticks current type (axis/button/hat)"); + xco+10 + 0.475 * (width-20), yco-68, ((joy->flag & SENS_JOY_ANY_EVENT) ? 0.525 : 0.12) * (width-20), 19, + &joy->flag, 0, 0, 0, 0, + "Triggered by all events on this joysticks current type (axis/button/hat)"); } if (joy->type == SENS_JOY_BUTTON) { if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { uiDefButI(block, NUM, 1, "Number:", xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->button, 0, 18, 100, 0, - "Specify which button to use"); + &joy->button, 0, 18, 100, 0, + "Specify which button to use"); } } else if (joy->type == SENS_JOY_AXIS) { uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->axis, 1, 8.0, 100, 0, - "Specify which axis pair to use, 1 is useually the main direction input"); + &joy->axis, 1, 8.0, 100, 0, + "Specify which axis pair to use, 1 is useually the main direction input"); uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20), yco-44, 0.4 * (width-20), 19, - &joy->precision, 0, 32768.0, 100, 0, - "Specify the precision of the axis"); + &joy->precision, 0, 32768.0, 100, 0, + "Specify the precision of the axis"); if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { - str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; + str = "Type %t|Up Axis %x1 |Down Axis %x3|Left Axis %x2|Right Axis %x0"; uiDefButI(block, MENU, B_REDR, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->axisf, 2.0, 31, 0, 0, - "The direction of the axis, use 'All Events' to receive events on any direction"); + &joy->axisf, 2.0, 31, 0, 0, + "The direction of the axis, use 'All Events' to receive events on any direction"); } } else if (joy->type == SENS_JOY_HAT) { uiDefButI(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->hat, 1, 4.0, 100, 0, - "Specify which hat to use"); - + &joy->hat, 1, 4.0, 100, 0, + "Specify which hat to use"); + if ((joy->flag & SENS_JOY_ANY_EVENT)==0) { - str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; + str = "Direction%t|Up%x1|Down%x4|Left%x8|Right%x2|%l|Up/Right%x3|Down/Left%x12|Up/Left%x9|Down/Right%x6"; uiDefButI(block, MENU, 0, str, xco+10 + 0.6 * (width-20), yco-68, 0.4 * (width-20), 19, - &joy->hatf, 2.0, 31, 0, 0, - "The direction of the hat, use 'All Events' to receive events on any direction"); + &joy->hatf, 2.0, 31, 0, 0, + "The direction of the hat, use 'All Events' to receive events on any direction"); } } else { /* (joy->type == SENS_JOY_AXIS_SINGLE)*/ uiDefButS(block, NUM, 1, "Number:", xco+10, yco-68, 0.46 * (width-20), 19, - &joy->axis_single, 1, 16.0, 100, 0, - "Specify a single axis (verticle/horizontal/other) to detect"); - + &joy->axis_single, 1, 16.0, 100, 0, + "Specify a single axis (verticle/horizontal/other) to detect"); + uiDefButI(block, NUM, 1, "Threshold:", xco+10 + 0.6 * (width-20), yco-44, 0.4 * (width-20), 19, - &joy->precision, 0, 32768.0, 100, 0, - "Specify the precision of the axis"); + &joy->precision, 0, 32768.0, 100, 0, + "Specify the precision of the axis"); } yco-= ysize; break; } } - + return yco-4; } @@ -1859,7 +1859,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo set_col_actuator(act->type, 0); switch (act->type) { - case ACT_OBJECT: + case ACT_OBJECT: { oa = act->data; wval = (width-100)/3; @@ -1890,7 +1890,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButBitS(block, TOG, ACT_DLOC_LOCAL, 0, "L", xco+45+3*wval, yco-45, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_DROT_LOCAL, 0, "L", xco+45+3*wval, yco-64, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - + if (ob->gameflag & OB_DYNAMIC) { uiDefBut(block, LABEL, 0, "Force", xco, yco-87, 55, 19, NULL, 0, 0, 0, 0, "Sets the force"); uiBlockBeginAlign(block); @@ -1903,7 +1903,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiBlockBeginAlign(block); uiDefButF(block, NUM, 0, "", xco+45, yco-106, wval, 19, oa->forcerot, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-106, wval, 19, oa->forcerot+1, -10000.0, 10000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-106, wval, 19, oa->forcerot+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); } @@ -1914,14 +1914,14 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButF(block, NUM, 0, "", xco+45+wval, yco-129, wval, 19, oa->linearvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-129, wval, 19, oa->linearvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); - + uiDefBut(block, LABEL, 0, "AngV", xco, yco-148, 45, 19, NULL, 0, 0, 0, 0, "Sets the angular velocity"); uiBlockBeginAlign(block); uiDefButF(block, NUM, 0, "", xco+45, yco-148, wval, 19, oa->angularvelocity, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+wval, yco-148, wval, 19, oa->angularvelocity+1, -10000.0, 10000.0, 10, 0, ""); uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-148, wval, 19, oa->angularvelocity+2, -10000.0, 10000.0, 10, 0, ""); uiBlockEndAlign(block); - + uiDefBut(block, LABEL, 0, "Damp", xco, yco-171, 45, 19, NULL, 0, 0, 0, 0, "Number of frames to reach the target velocity"); uiDefButS(block, NUM, 0, "", xco+45, yco-171, wval, 19, &oa->damping, 0.0, 1000.0, 100, 0, ""); @@ -1929,9 +1929,9 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButBitS(block, TOG, ACT_TORQUE_LOCAL, 0, "L", xco+45+3*wval, yco-106, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_LIN_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-129, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); uiDefButBitS(block, TOG, ACT_ANG_VEL_LOCAL, 0, "L", xco+45+3*wval, yco-148, 15, 19, &oa->flag, 0.0, 0.0, 0, 0, "Local transformation"); - + uiDefButBitS(block, TOG, ACT_ADD_LIN_VEL, 0, "use_additive", xco+45+3*wval+15, yco-129, 35, 19, &oa->flag, 0.0, 0.0, 0, 0, "Toggles between ADD and SET linV"); - } + } } else if (oa->type == ACT_OBJECT_SERVO) { ysize= 195; @@ -1984,8 +1984,8 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo yco-= ysize; break; } - case ACT_ACTION: - case ACT_SHAPEACTION: + case ACT_ACTION: + case ACT_SHAPEACTION: { /* DrawAct */ #ifdef __NLA_ACTION_BY_MOTION_ACTUATOR @@ -2010,7 +2010,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefIDPoinBut(block, test_actionpoin_but, ID_AC, 1, "AC: ", xco+10+ (width/3), yco-24, ((width/3)*2) - (20 + 60), 19, &aa->act, "Action name"); uiDefButBitS(block, TOGN, 1, 0, "Continue", xco+((width/3)*2)+20, yco-24, 60, 19, - &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time"); + &aa->end_reset, 0.0, 0.0, 0, 0, "Restore last frame when switching on/off, otherwise play from the start each time"); if (aa->type == ACT_ACTION_FROM_PROP) { @@ -2020,7 +2020,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButF(block, NUM, 0, "Sta: ", xco+10, yco-44, (width-20)/2, 19, &aa->sta, 1.0, MAXFRAMEF, 0, 0, "Start frame"); uiDefButF(block, NUM, 0, "End: ", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &aa->end, 1.0, MAXFRAMEF, 0, 0, "End frame"); } - + uiDefButS(block, NUM, 0, "Blendin: ", xco+10, yco-64, (width-20)/2, 19, &aa->blendin, 0.0, 32767, 0.0, 0.0, "Number of frames of motion blending"); uiDefButS(block, NUM, 0, "Priority: ", xco+10+(width-20)/2, yco-64, (width-20)/2, 19, &aa->priority, 0.0, 100.0, 0.0, 0.0, "Execution priority - lower numbers will override actions with higher numbers, With 2 or more actions at once, the overriding channels must be lower in the stack"); @@ -2038,7 +2038,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo yco-=ysize; break; } - case ACT_IPO: + case ACT_IPO: { ia= act->data; @@ -2051,55 +2051,55 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo uiDefButS(block, MENU, B_REDR, str, xco+10, yco-24, (width-20)/2, 19, &ia->type, 0, 0, 0, 0, ""); - but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, - "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, - &ia->flag, 0, 0, 0, 0, - "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); + but = uiDefButBitS(block, TOG, ACT_IPOFORCE, ACT_IPOFORCE, + "Force", xco+10+(width-20)/2, yco-24, (width-20)/4-10, 19, + &ia->flag, 0, 0, 0, 0, + "Apply Ipo as a global or local force depending on the local option (dynamic objects only)"); uiButSetFunc(but, change_ipo_actuator, but, ia); - but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, - "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, - &ia->flag, 0, 0, 0, 0, - "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); + but = uiDefButBitS(block, TOG, ACT_IPOADD, ACT_IPOADD, + "Add", xco+3*(width-20)/4, yco-24, (width-20)/4-10, 19, + &ia->flag, 0, 0, 0, 0, + "Ipo is added to the current loc/rot/scale in global or local coordinate according to Local flag"); uiButSetFunc(but, change_ipo_actuator, but, ia); /* Only show the do-force-local toggle if force is requested */ if (ia->flag & (ACT_IPOFORCE|ACT_IPOADD)) { - uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, - "L", xco+width-30, yco-24, 20, 19, - &ia->flag, 0, 0, 0, 0, - "Let the ipo acts in local coordinates, used in Force and Add mode"); + uiDefButBitS(block, TOG, ACT_IPOLOCAL, 0, + "L", xco+width-30, yco-24, 20, 19, + &ia->flag, 0, 0, 0, 0, + "Let the ipo acts in local coordinates, used in Force and Add mode"); } if (ia->type==ACT_IPO_FROM_PROP) { - uiDefBut(block, TEX, 0, - "Prop: ", xco+10, yco-44, width-80, 19, - ia->name, 0.0, MAX_NAME, 0, 0, - "Use this property to define the Ipo position"); + uiDefBut(block, TEX, 0, + "Prop: ", xco+10, yco-44, width-80, 19, + ia->name, 0.0, MAX_NAME, 0, 0, + "Use this property to define the Ipo position"); } else { - uiDefButF(block, NUM, 0, - "Sta", xco+10, yco-44, (width-80)/2, 19, - &ia->sta, 1.0, MAXFRAMEF, 0, 0, - "Start frame"); - uiDefButF(block, NUM, 0, - "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19, - &ia->end, 1.0, MAXFRAMEF, 0, 0, - "End frame"); + uiDefButF(block, NUM, 0, + "Sta", xco+10, yco-44, (width-80)/2, 19, + &ia->sta, 1.0, MAXFRAMEF, 0, 0, + "Start frame"); + uiDefButF(block, NUM, 0, + "End", xco+10+(width-80)/2, yco-44, (width-80)/2, 19, + &ia->end, 1.0, MAXFRAMEF, 0, 0, + "End frame"); } - uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, - "Child", xco+10+(width-80), yco-44, 60, 19, - &ia->flag, 0, 0, 0, 0, - "Update IPO on all children Objects as well"); - uiDefBut(block, TEX, 0, - "FrameProp: ", xco+10, yco-64, width-20, 19, - ia->frameProp, 0.0, MAX_NAME, 0, 0, - "Assign the action's current frame number to this property"); + uiDefButBitS(block, TOG, ACT_IPOCHILD, B_REDR, + "Child", xco+10+(width-80), yco-44, 60, 19, + &ia->flag, 0, 0, 0, 0, + "Update IPO on all children Objects as well"); + uiDefBut(block, TEX, 0, + "FrameProp: ", xco+10, yco-64, width-20, 19, + ia->frameProp, 0.0, MAX_NAME, 0, 0, + "Assign the action's current frame number to this property"); yco-= ysize; break; } - case ACT_PROPERTY: + case ACT_PROPERTY: { ysize= 68; @@ -2129,7 +2129,7 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo break; } - case ACT_SOUND: + case ACT_SOUND: { sa = act->data; sa->sndnr = 0; @@ -2193,743 +2193,743 @@ static short draw_actuatorbuttons(Main *bmain, Object *ob, bActuator *act, uiBlo } } MEM_freeN((void *)str); - } + } else { uiDefButO(block, BUT, "sound.open", 0, "Load Sound", xco+10, yco-22, width-20, 19, "Load a sound file"); } - + yco-= ysize; break; } - case ACT_CAMERA: + case ACT_CAMERA: - ysize= 48; + ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - ca= act->data; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object"); - uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, ""); - - uiDefButF(block, NUM, 0, "Min:", xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, ""); - - if (ca->axis==0) ca->axis= 'x'; - uiDefButS(block, ROW, 0, "X", xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis"); - uiDefButS(block, ROW, 0, "Y", xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis"); - - uiDefButF(block, NUM, 0, "Max:", xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, ""); + ca= act->data; - yco-= ysize; + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-24, (width-20)/2, 19, &(ca->ob), "Look at this Object"); + uiDefButF(block, NUM, 0, "Height:", xco+10+(width-20)/2, yco-24, (width-20)/2, 19, &ca->height, 0.0, 20.0, 0, 0, ""); - break; + uiDefButF(block, NUM, 0, "Min:", xco+10, yco-44, (width-60)/2, 19, &ca->min, 0.0, 20.0, 0, 0, ""); - case ACT_EDIT_OBJECT: - - eoa= act->data; + if (ca->axis==0) ca->axis= 'x'; + uiDefButS(block, ROW, 0, "X", xco+10+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'x', 0, 0, "Camera tries to get behind the X axis"); + uiDefButS(block, ROW, 0, "Y", xco+30+(width-60)/2, yco-44, 20, 19, &ca->axis, 4.0, (float)'y', 0, 0, "Camera tries to get behind the Y axis"); - if (eoa->type==ACT_EDOB_ADD_OBJECT) { - ysize = 92; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefButF(block, NUM, 0, "Max:", xco+20+(width)/2, yco-44, (width-60)/2, 19, &ca->max, 0.0, 20.0, 0, 0, ""); + + yco-= ysize; + + break; + + case ACT_EDIT_OBJECT: + + eoa= act->data; + + if (eoa->type==ACT_EDOB_ADD_OBJECT) { + ysize = 92; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); + + wval= (width-60)/3; + uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, + NULL, 0, 0, 0, 0, + "Velocity upon creation"); + uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, + eoa->linVelocity, -100.0, 100.0, 10, 0, + "Velocity upon creation, x component"); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, + eoa->linVelocity+1, -100.0, 100.0, 10, 0, + "Velocity upon creation, y component"); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, + eoa->linVelocity+2, -100.0, 100.0, 10, 0, + "Velocity upon creation, z component"); + uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19, + &eoa->localflag, 0.0, 0.0, 0, 0, + "Apply the transformation locally"); + + + uiDefBut(block, LABEL, 0, "AngV", xco, yco-90, 45, 19, + NULL, 0, 0, 0, 0, + "Angular velocity upon creation"); + uiDefButF(block, NUM, 0, "", xco+45, yco-90, wval, 19, + eoa->angVelocity, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, x component"); + uiDefButF(block, NUM, 0, "", xco+45+wval, yco-90, wval, 19, + eoa->angVelocity+1, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, y component"); + uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-90, wval, 19, + eoa->angVelocity+2, -10000.0, 10000.0, 10, 0, + "Angular velocity upon creation, z component"); + uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19, + &eoa->localflag, 0.0, 0.0, 0, 0, + "Apply the rotation locally"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Add this Object and all its children (cant be on an visible layer)"); - uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the new Object lives"); - - wval= (width-60)/3; - uiDefBut(block, LABEL, 0, "linV", xco, yco-68, 45, 19, - NULL, 0, 0, 0, 0, - "Velocity upon creation"); - uiDefButF(block, NUM, 0, "", xco+45, yco-68, wval, 19, - eoa->linVelocity, -100.0, 100.0, 10, 0, - "Velocity upon creation, x component"); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-68, wval, 19, - eoa->linVelocity+1, -100.0, 100.0, 10, 0, - "Velocity upon creation, y component"); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-68, wval, 19, - eoa->linVelocity+2, -100.0, 100.0, 10, 0, - "Velocity upon creation, z component"); - uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_LINV, 0, "L", xco+45+3*wval, yco-68, 15, 19, - &eoa->localflag, 0.0, 0.0, 0, 0, - "Apply the transformation locally"); - - - uiDefBut(block, LABEL, 0, "AngV", xco, yco-90, 45, 19, - NULL, 0, 0, 0, 0, - "Angular velocity upon creation"); - uiDefButF(block, NUM, 0, "", xco+45, yco-90, wval, 19, - eoa->angVelocity, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, x component"); - uiDefButF(block, NUM, 0, "", xco+45+wval, yco-90, wval, 19, - eoa->angVelocity+1, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, y component"); - uiDefButF(block, NUM, 0, "", xco+45+2*wval, yco-90, wval, 19, - eoa->angVelocity+2, -10000.0, 10000.0, 10, 0, - "Angular velocity upon creation, z component"); - uiDefButBitS(block, TOG, ACT_EDOB_LOCAL_ANGV, 0, "L", xco+45+3*wval, yco-90, 15, 19, - &eoa->localflag, 0.0, 0.0, 0, 0, - "Apply the rotation locally"); - - } - else if (eoa->type==ACT_EDOB_END_OBJECT) { - ysize= 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - else if (eoa->type==ACT_EDOB_REPLACE_MESH) { - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh"); - - uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, 0, "Gfx", xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh"); - uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, 0, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)"); - } - else if (eoa->type==ACT_EDOB_TRACK_TO) { - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object"); - uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); - uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); - } - else if (eoa->type==ACT_EDOB_DYNAMICS) { - ysize= 69; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, ""); - if (eoa->dyn_operation==4) { - uiDefButF(block, NUM, 0, "", xco+40, yco-63, width-80, 19, - &eoa->mass, 0.0, 10000.0, 10, 0, - "Mass for object"); } - } - str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); + else if (eoa->type==ACT_EDOB_END_OBJECT) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if (eoa->type==ACT_EDOB_REPLACE_MESH) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; + uiDefIDPoinBut(block, test_meshpoin_but, ID_ME, 1, "ME:", xco+40, yco-44, (width-80)/2, 19, &(eoa->me), "replace the existing, when left blank 'Phys' will remake the existing physics mesh"); - break; + uiDefButBitS(block, TOGN, ACT_EDOB_REPLACE_MESH_NOGFX, 0, "Gfx", xco+40 + (width-80)/2, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the display mesh"); + uiDefButBitS(block, TOG, ACT_EDOB_REPLACE_MESH_PHYS, 0, "Phys", xco+40 + (width-80)/2 +(width-80)/4, yco-44, (width-80)/4, 19, &eoa->flag, 0, 0, 0, 0, "Replace the physics mesh (triangle bounds only. compound shapes not supported)"); + } + else if (eoa->type==ACT_EDOB_TRACK_TO) { + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - case ACT_CONSTRAINT: - coa= act->data; - - if (coa->type == ACT_CONST_TYPE_LOC) { - ysize= 69; + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+10, yco-44, (width-20)/2, 19, &(eoa->ob), "Track to this Object"); + uiDefButI(block, NUM, 0, "Time:", xco+10+(width-20)/2, yco-44, (width-20)/2-40, 19, &eoa->time, 0.0, 2000.0, 0, 0, "Duration the tracking takes"); + uiDefButS(block, TOG, 0, "3D", xco+width-50, yco-44, 40, 19, &eoa->flag, 0.0, 0.0, 0, 0, "Enable 3D tracking"); + } + else if (eoa->type==ACT_EDOB_DYNAMICS) { + ysize= 69; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ - /* coa->flag &= ~(63); */ - str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; - coa->flag &= 7; - coa->time = 0; - uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); - - if (coa->flag & ACT_CONST_LOCX) fp= coa->minloc; - else if (coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; - else if (coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; - else if (coa->flag & ACT_CONST_ROTX) fp= coa->minrot; - else if (coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; - else fp= coa->minrot+2; - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); - uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); - } - else if (coa->type == ACT_CONST_TYPE_DIST) { - ysize= 106; + str= "Dynamic Operation %t|Restore Dynamics %x0|Suspend Dynamics %x1|Enable Rigid Body %x2|Disable Rigid Body %x3|Set Mass %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-44, (width-80), 19, &(eoa->dyn_operation), 0.0, 0.0, 0, 0, ""); + if (eoa->dyn_operation==4) { + uiDefButF(block, NUM, 0, "", xco+40, yco-63, width-80, 19, + &eoa->mass, 0.0, 10000.0, 10, 0, + "Mass for object"); + } + } + str= "Edit Object %t|Add Object %x0|End Object %x1|Replace Mesh %x2|Track to %x3|Dynamics %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &eoa->type, 0.0, 0.0, 0, 0, ""); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); - uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); - uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis"); - - if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; - else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; - else fp= coa->minloc+2; - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); - if (coa->flag & ACT_CONST_DISTANCE) - uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target"); - uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position"); - uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); - if (coa->flag & ACT_CONST_MATERIAL) { - uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detects only Objects with this material"); + yco-= ysize; + + break; + + case ACT_CONSTRAINT: + coa= act->data; + + if (coa->type == ACT_CONST_TYPE_LOC) { + ysize= 69; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + /* str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4|Rot X %x8|Rot Y %x16|Rot Z %x32"; */ + /* coa->flag &= ~(63); */ + str= "Limit %t|None %x0|Loc X %x1|Loc Y %x2|Loc Z %x4"; + coa->flag &= 7; + coa->time = 0; + uiDefButS(block, MENU, 1, str, xco+10, yco-65, 70, 19, &coa->flag, 0.0, 0.0, 0, 0, ""); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "Min", xco+80, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Max", xco+80+(width-90)/2, yco-45, (width-90)/2, 19, NULL, 0.0, 0.0, 0, 0, ""); + + if (coa->flag & ACT_CONST_LOCX) fp= coa->minloc; + else if (coa->flag & ACT_CONST_LOCY) fp= coa->minloc+1; + else if (coa->flag & ACT_CONST_LOCZ) fp= coa->minloc+2; + else if (coa->flag & ACT_CONST_ROTX) fp= coa->minrot; + else if (coa->flag & ACT_CONST_ROTY) fp= coa->minrot+1; + else fp= coa->minrot+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-90)/2, 19, fp, -2000.0, 2000.0, 10, 0, ""); + uiDefButF(block, NUM, 0, "", xco+80+(width-90)/2, yco-65, (width-90)/2, 19, fp+3, -2000.0, 2000.0, 10, 0, ""); } - else { - uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detect only Objects with this property"); + else if (coa->type == ACT_CONST_TYPE_DIST) { + ysize= 106; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray"); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "Range", xco+80, yco-45, (width-115)/2, 19, NULL, 0.0, 0.0, 0, 0, "Set the maximum length of ray"); + uiDefButBitS(block, TOG, ACT_CONST_DISTANCE, B_REDR, "Dist", xco+80+(width-115)/2, yco-45, (width-115)/2, 19, &coa->flag, 0.0, 0.0, 0, 0, "Force distance of object to point of impact of ray"); + uiDefButBitS(block, TOG, ACT_CONST_LOCAL, 0, "L", xco+80+(width-115), yco-45, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Set ray along object's axis or global axis"); + + if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; + else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; + else fp= coa->minloc+2; + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/2, 19, fp+3, 0.0, 2000.0, 10, 0, "Maximum length of ray"); + if (coa->flag & ACT_CONST_DISTANCE) + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/2, yco-65, (width-115)/2, 19, fp, -2000.0, 2000.0, 10, 0, "Keep this distance to target"); + uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Set object axis along (local axis) or parallel (global axis) to the normal at hit position"); + uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); + if (coa->flag & ACT_CONST_MATERIAL) { + uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detects only Objects with this material"); + } + else { + uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detect only Objects with this property"); + } + uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); + uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation"); } - uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); - uiDefButS(block, NUM, 0, "time", xco+50, yco-103, (width-60)/2, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButS(block, NUM, 0, "rotDamp", xco+50+(width-60)/2, yco-103, (width-60)/2, 19, &(coa->rotdamp), 0.0, 100.0, 0, 0, "Use a different damping for orientation"); - } - else if (coa->type == ACT_CONST_TYPE_ORI) { - ysize= 87; + else if (coa->type == ACT_CONST_TYPE_ORI) { + ysize= 87; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); - - uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); - uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); - - uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction"); - uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); - uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); - - uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max"); - uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max"); - } - else if (coa->type == ACT_CONST_TYPE_FH) { - ysize= 106; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; - uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)"); - - if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; - else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; - else fp= coa->minloc+2; - - uiDefButF(block, NUM, 0, "damp", xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force"); - uiDefButF(block, NUM, 0, "dist", xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area"); - uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh", xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal"); - - uiDefButF(block, NUMSLI, 0, "Fh ", xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area"); - uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes"); - uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); - if (coa->flag & ACT_CONST_MATERIAL) { - uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detects only Objects with this material"); + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Select the axis to be aligned along the reference direction"); + + uiDefButS(block, NUM, 0, "damp", xco+10, yco-45, 70, 19, &coa->damp, 0.0, 100.0, 0, 0, "Damping factor: time constant (in frame) of low pass filter"); + uiDefBut(block, LABEL, 0, "X", xco+80, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Y", xco+80+(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "Z", xco+80+2*(width-115)/3, yco-45, (width-115)/3, 19, NULL, 0.0, 0.0, 0, 0, ""); + + uiDefButF(block, NUM, 0, "", xco+80, yco-65, (width-115)/3, 19, &coa->maxrot[0], -2000.0, 2000.0, 10, 0, "X component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[1], -2000.0, 2000.0, 10, 0, "Y component of reference direction"); + uiDefButF(block, NUM, 0, "", xco+80+2*(width-115)/3, yco-65, (width-115)/3, 19, &coa->maxrot[2], -2000.0, 2000.0, 10, 0, "Z component of reference direction"); + + uiDefButS(block, NUM, 0, "time", xco+10, yco-84, 70, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButF(block, NUM, 0, "min", xco+80, yco-84, (width-115)/2, 19, &(coa->minloc[0]), 0.0, 180.0, 10, 1, "Minimum angle (in degree) to maintain with target direction. No correction is done if angle with target direction is between min and max"); + uiDefButF(block, NUM, 0, "max", xco+80+(width-115)/2, yco-84, (width-115)/2, 19, &(coa->maxloc[0]), 0.0, 180.0, 10, 1, "Maximum angle (in degree) allowed with target direction. No correction is done if angle with target direction is between min and max"); } - else { - uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, - coa->matprop, 0, MAX_NAME, 0, 0, - "Ray detect only Objects with this property"); + else if (coa->type == ACT_CONST_TYPE_FH) { + ysize= 106; + + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + str= "Direction %t|None %x0|X axis %x1|Y axis %x2|Z axis %x4|-X axis %x8|-Y axis %x16|-Z axis %x32"; + uiDefButS(block, MENU, B_REDR, str, xco+10, yco-65, 70, 19, &coa->mode, 0.0, 0.0, 0, 0, "Set the direction of the ray (in world coordinate)"); + + if (coa->mode & (ACT_CONST_DIRPX|ACT_CONST_DIRNX)) fp= coa->minloc; + else if (coa->mode & (ACT_CONST_DIRPY|ACT_CONST_DIRNY)) fp= coa->minloc+1; + else fp= coa->minloc+2; + + uiDefButF(block, NUM, 0, "damp", xco+10, yco-45, (width-70)/2, 19, &coa->maxrot[0], 0.0, 1.0, 1, 0, "Damping factor of the Fh spring force"); + uiDefButF(block, NUM, 0, "dist", xco+10+(width-70)/2, yco-45, (width-70)/2, 19, fp, 0.010, 2000.0, 10, 0, "Height of the Fh area"); + uiDefButBitS(block, TOG, ACT_CONST_DOROTFH, 0, "Rot Fh", xco+10+(width-70), yco-45, 50, 19, &coa->flag, 0.0, 0.0, 0, 0, "Keep object axis parallel to normal"); + + uiDefButF(block, NUMSLI, 0, "Fh ", xco+80, yco-65, (width-115), 19, fp+3, 0.0, 1.0, 0, 0, "Spring force within the Fh area"); + uiDefButBitS(block, TOG, ACT_CONST_NORMAL, 0, "N", xco+80+(width-115), yco-65, 25, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Add a horizontal spring force on slopes"); + uiDefButBitS(block, TOG, ACT_CONST_MATERIAL, B_REDR, "M/P", xco+10, yco-84, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Detect material instead of property"); + if (coa->flag & ACT_CONST_MATERIAL) { + uiDefBut(block, TEX, 1, "Material:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detects only Objects with this material"); + } + else { + uiDefBut(block, TEX, 1, "Property:", xco + 50, yco-84, (width-60), 19, + coa->matprop, 0, MAX_NAME, 0, 0, + "Ray detect only Objects with this property"); + } + uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, + &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); + uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); + uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation"); } - uiDefButBitS(block, TOG, ACT_CONST_PERMANENT, 0, "PER", xco+10, yco-103, 40, 19, - &coa->flag, 0.0, 0.0, 0, 0, "Persistent actuator: stays active even if ray does not reach target"); - uiDefButS(block, NUM, 0, "time", xco+50, yco-103, 90, 19, &(coa->time), 0.0, 1000.0, 0, 0, "Maximum activation time in frame, 0 for unlimited"); - uiDefButF(block, NUM, 0, "rotDamp", xco+140, yco-103, (width-150), 19, &coa->maxrot[1], 0.0, 1.0, 1, 0, "Use a different damping for rotation"); - } - str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3"; - but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); - yco-= ysize; - break; + str= "Constraint Type %t|Location %x0|Distance %x1|Orientation %x2|Force field %x3"; + but = uiDefButS(block, MENU, B_REDR, str, xco+40, yco-23, (width-80), 19, &coa->type, 0.0, 0.0, 0, 0, ""); + yco-= ysize; + break; - case ACT_SCENE: - sca= act->data; - - if (sca->type==ACT_SCENE_RESTART) { - ysize= 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - else if (sca->type==ACT_SCENE_CAMERA) { + case ACT_SCENE: + sca= act->data; - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + if (sca->type==ACT_SCENE_RESTART) { + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + else if (sca->type==ACT_SCENE_CAMERA) { - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera. Leave empty to refer to self object"); - } - else if (sca->type==ACT_SCENE_SET) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); - } - else if (sca->type==ACT_SCENE_ADD_FRONT) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+40, yco-44, (width-80), 19, &(sca->camera), "Set this Camera. Leave empty to refer to self object"); + } + else if (sca->type==ACT_SCENE_SET) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); - } - else if (sca->type==ACT_SCENE_ADD_BACK) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); - } - else if (sca->type==ACT_SCENE_REMOVE) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Set this Scene"); + } + else if (sca->type==ACT_SCENE_ADD_FRONT) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene"); - } - else if (sca->type==ACT_SCENE_SUSPEND) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene"); - } - else if (sca->type==ACT_SCENE_RESUME) { - - ysize= 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add an Overlay Scene"); + } + else if (sca->type==ACT_SCENE_ADD_BACK) { - uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene"); - } + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Add a Background Scene"); + } + else if (sca->type==ACT_SCENE_REMOVE) { - yco-= ysize; - break; - case ACT_GAME: + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Remove a Scene"); + } + else if (sca->type==ACT_SCENE_SUSPEND) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Pause a Scene"); + } + else if (sca->type==ACT_SCENE_RESUME) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 1, "SCE:", xco+40, yco-44, (width-80), 19, &(sca->scene), "Unpause a Scene"); + } + + str= "Scene %t|Restart %x0|Set Scene %x1|Set Camera %x2|Add OverlayScene %x3|Add BackgroundScene %x4|Remove Scene %x5|Suspend Scene %x6|Resume Scene %x7"; + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &sca->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + break; + case ACT_GAME: { gma = act->data; if (gma->type == ACT_GAME_LOAD) { //ysize = 68; ysize = 48; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); -// uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this blend file, use the \"//\" prefix for a path relative to the current blend file"); + // uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } #if 0 else if (gma->type == ACT_GAME_START) { - ysize = 68; - glRects(xco, yco-ysize, xco+width, yco); + ysize = 68; + glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file"); + uiDefBut(block, TEX, 1, "File: ", xco+10, yco-44, width-20, 19, &(gma->filename), 0, sizeof(gma->filename), 0, 0, "Load this file"); uiDefBut(block, TEX, 1, "Anim: ", xco+10, yco-64, width-20, 19, &(gma->loadaniname), 0, sizeof(gma->loadaniname), 0, 0, "Use this loadinganimation"); } #endif else if (ELEM4(gma->type, ACT_GAME_RESTART, ACT_GAME_QUIT, ACT_GAME_SAVECFG, ACT_GAME_LOADCFG)) { - ysize = 28; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + ysize = 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); } //str = "Scene %t|Load game%x0|Start loaded game%x1|Restart this game%x2|Quit this game %x3"; str = "Scene %t|Start new game%x0|Restart this game%x2|Quit this game %x3|Save bge.logic.globalDict %x4|Load bge.logic.globalDict %x5"; - uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); + uiDefButS(block, MENU, B_REDR, str, xco+40, yco-24, (width-80), 19, &gma->type, 0.0, 0.0, 0, 0, ""); - yco -= ysize; - break; + yco -= ysize; + break; } - case ACT_GROUP: - ga= act->data; + case ACT_GROUP: + ga= act->data; - ysize= 52; + ysize= 52; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - str= "GroupKey types %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5"; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); - if (ga->type==ACT_GROUP_SET) { - uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set"); - uiDefButI(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); - } - else if (ga->type==ACT_GROUP_FROM_PROP) { - uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position"); - } - else { - uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); - uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); - } - yco-= ysize; - break; + str= "GroupKey types %t|Set Key %x6|Play %x0|Ping Pong %x1|Flipper %x2|Loop Stop %x3|Loop End %x4|Property %x5"; - case ACT_VISIBILITY: - ysize = 24; + uiDefButS(block, MENU, 1, str, xco+20, yco-24, width-40, 19, &ga->type, 0, 0, 0, 0, ""); + if (ga->type==ACT_GROUP_SET) { + uiDefBut(block, TEX, 0, "Key: ", xco+20, yco-44, (width-10)/2, 19, ga->name, 0.0, MAX_NAME, 0, 0, "This name defines groupkey to be set"); + uiDefButI(block, NUM, 0, "Frame:", xco+20+(width-10)/2, yco-44, (width-70)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Set this frame"); + } + else if (ga->type==ACT_GROUP_FROM_PROP) { + uiDefBut(block, TEX, 0, "Prop: ", xco+20, yco-44, width-40, 19, ga->name, 0.0, MAX_NAME, 0, 0, "Use this property to define the Group position"); + } + else { + uiDefButI(block, NUM, 0, "State", xco+20, yco-44, (width-40)/2, 19, &ga->sta, 0.0, 2500.0, 0, 0, "Start frame"); + uiDefButI(block, NUM, 0, "End", xco+20+(width-40)/2, yco-44, (width-40)/2, 19, &ga->end, 0.0, 2500.0, 0, 0, "End frame"); + } + yco-= ysize; + break; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - visAct = act->data; + case ACT_VISIBILITY: + ysize = 24; - uiBlockBeginAlign(block); - uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR, - "Visible", - xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)"); - uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR, - "Occlusion", - xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Set the object to occlude objects behind it. Initialized from the object type in physics button"); - uiBlockEndAlign(block); - - uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0, - "Children", - xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag, - 0.0, 0.0, 0, 0, - "Sets all the children of this object to the same visibility/occlusion recursively"); + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; + visAct = act->data; - break; - - case ACT_STATE: - ysize = 34; + uiBlockBeginAlign(block); + uiDefButBitI(block, TOGN, ACT_VISIBILITY_INVISIBLE, B_REDR, + "Visible", + xco + 10, yco - 20, (width - 20)/3, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Set the objects visible. Initialized from the objects render restriction toggle (access in the outliner)"); + uiDefButBitI(block, TOG, ACT_VISIBILITY_OCCLUSION, B_REDR, + "Occlusion", + xco + 10 + ((width - 20)/3), yco - 20, (width - 20)/3, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Set the object to occlude objects behind it. Initialized from the object type in physics button"); + uiBlockEndAlign(block); - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - staAct = act->data; + uiDefButBitI(block, TOG, ACT_VISIBILITY_RECURSIVE, 0, + "Children", + xco + 10 + (((width - 20)/3)*2)+10, yco - 20, ((width - 20)/3)-10, 19, &visAct->flag, + 0.0, 0.0, 0, 0, + "Sets all the children of this object to the same visibility/occlusion recursively"); - str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3"; + yco-= ysize; - uiDefButI(block, MENU, B_REDR, str, - xco + 10, yco - 24, 65, 19, &staAct->type, - 0.0, 0.0, 0, 0, - "Select the bit operation on object state mask"); + break; - for (wval=0; wval<15; wval+=5) { - uiBlockBeginAlign(block); - for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+wval), stbit+wval, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval))); - uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); - } - for (stbit=0; stbit<5; stbit++) { - but = uiDefButBitI(block, TOG, 1<<(stbit+wval+15), stbit+wval+15, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval+15))); - uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); - } - } - uiBlockEndAlign(block); + case ACT_STATE: + ysize = 34; - yco-= ysize; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); - break; + staAct = act->data; - case ACT_RANDOM: - ysize = 69; + str= "Operation %t|Cpy %x0|Add %x1|Sub %x2|Inv %x3"; + + uiDefButI(block, MENU, B_REDR, str, + xco + 10, yco - 24, 65, 19, &staAct->type, + 0.0, 0.0, 0, 0, + "Select the bit operation on object state mask"); + + for (wval=0; wval<15; wval+=5) { + uiBlockBeginAlign(block); + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+wval), stbit+wval, "", (short)(xco+85+12*stbit+13*wval), yco-17, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval))); + uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); + } + for (stbit=0; stbit<5; stbit++) { + but = uiDefButBitI(block, TOG, 1<<(stbit+wval+15), stbit+wval+15, "", (short)(xco+85+12*stbit+13*wval), yco-29, 12, 12, (int *)&(staAct->mask), 0, 0, 0, 0, get_state_name(ob, (short)(stbit+wval+15))); + uiButSetFunc(but, check_state_mask, but, &(staAct->mask)); + } + } + uiBlockEndAlign(block); + + yco-= ysize; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, - (float)yco-ysize, (float)xco+width, (float)yco, 1); - - randAct = act->data; - - /* 1. seed */ - uiDefButI(block, NUM, 1, "Seed: ", (xco+10), yco-24, 0.4 *(width-20), 19, - &randAct->seed, 0, 1000, 0, 0, - "Initial seed of the random generator. Use Python for more freedom. " - " (Choose 0 for not random)"); - - /* 2. distribution type */ - /* One pick per distribution. These numbers MUST match the #defines */ - /* in game.h !!! */ - str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1" - "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4" - "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7" - "|Float Normal %x8|Float Neg. Exp. %x9"; - uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19, - &randAct->distribution, 0.0, 0.0, 0, 0, - "Choose the type of distribution"); - - /* 3. property */ - uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, - &randAct->propname, 0, MAX_NAME, 0, 0, - "Assign the random value to this property"); - - /*4. and 5. arguments for the distribution*/ - switch (randAct->distribution) { - case ACT_RANDOM_BOOL_CONST: - uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19, - &randAct->int_arg_1, 2.0, 1, 0, 0, - "Always false or always true"); - break; - case ACT_RANDOM_BOOL_UNIFORM: - uiDefBut(block, LABEL, 0, " Do a 50-50 pick", (xco+10), yco-64, (width-20), 19, - NULL, 0, 0, 0, 0, - "Choose between true and false, 50% chance each"); - break; - case ACT_RANDOM_BOOL_BERNOUILLI: - uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.0, 1.0, 0, 0, - "Pick a number between 0 and 1. Success if you stay " - "below this value"); - break; - case ACT_RANDOM_INT_CONST: - uiDefButI(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, - &randAct->int_arg_1, -1000, 1000, 0, 0, - "Always return this number"); - break; - case ACT_RANDOM_INT_UNIFORM: - uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->int_arg_1, -1000, 1000, 0, 0, - "Choose a number from a range. " - "Lower boundary of the range"); - uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->int_arg_2, -1000, 1000, 0, 0, - "Choose a number from a range. " - "Upper boundary of the range"); - break; - case ACT_RANDOM_INT_POISSON: - uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.01, 100.0, 0, 0, - "Expected mean value of the distribution"); - break; - case ACT_RANDOM_FLOAT_CONST: - uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.0, 1.0, 0, 0, - "Always return this number"); - break; - case ACT_RANDOM_FLOAT_UNIFORM: - uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "Choose a number from a range" - "Lower boundary of the range"); - uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, - "Choose a number from a range" - "Upper boundary of the range"); - break; - case ACT_RANDOM_FLOAT_NORMAL: - uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, - &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, - "A normal distribution. Mean of the distribution"); - uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, - &randAct->float_arg_2, 0.0, 10000.0, 0, 0, - "A normal distribution. Standard deviation of the " - "distribution"); - break; - case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: - uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, - &randAct->float_arg_1, 0.001, 10000.0, 0, 0, - "Negative exponential dropoff"); break; - default: - ; /* don't know what this distro is... can be useful for testing */ - /* though :) */ - } - yco-= ysize; - break; - case ACT_MESSAGE: - ma = act->data; + case ACT_RANDOM: + ysize = 69; - ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */ - - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, - (float)xco+width, (float)yco, 1); - - myline=1; - - /* line 1: To */ - uiDefBut(block, TEX, 1, "To: ", - (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->toPropName, 0, MAX_NAME, 0, 0, - "Optional send message to objects with this name only, or empty to broadcast"); - - /* line 2: Message Subject */ - uiDefBut(block, TEX, 1, "Subject: ", - (xco+10), (yco-(myline++*24)), (width-20), 19, - &ma->subject, 0, MAX_NAME, 0, 0, - "Optional message subject. This is what can be filtered on"); - - /* line 3: Text/Property */ - uiDefButBitS(block, TOG, 1, B_REDR, "T/P", - (xco+10), (yco-(myline*24)), (0.20 * (width-20)), 19, - &ma->bodyType, 0.0, 0.0, 0, 0, - "Toggle message type: either Text or a PropertyName"); - - if (ma->bodyType == ACT_MESG_MESG) { - /* line 3: Message Body */ - uiDefBut(block, TEX, 1, "Body: ", - (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, - &ma->body, 0, MAX_NAME, 0, 0, - "Optional message body Text"); - } - else { - /* line 3: Property body (set by property) */ - uiDefBut(block, TEX, 1, "Propname: ", - (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, - &ma->body, 0, MAX_NAME, 0, 0, - "The message body will be set by the Property Value"); - } - - yco -= ysize; - break; - case ACT_2DFILTER: - tdfa = act->data; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, + (float)yco-ysize, (float)xco+width, (float)yco, 1); + + randAct = act->data; + + /* 1. seed */ + uiDefButI(block, NUM, 1, "Seed: ", (xco+10), yco-24, 0.4 *(width-20), 19, + &randAct->seed, 0, 1000, 0, 0, + "Initial seed of the random generator. Use Python for more freedom. " + " (Choose 0 for not random)"); + + /* 2. distribution type */ + /* One pick per distribution. These numbers MUST match the #defines */ + /* in game.h !!! */ + str= "Distribution %t|Bool Constant %x0|Bool Uniform %x1" + "|Bool Bernoulli %x2|Int Constant %x3|Int Uniform %x4" + "|Int Poisson %x5|Float Constant %x6|Float Uniform %x7" + "|Float Normal %x8|Float Neg. Exp. %x9"; + uiDefButI(block, MENU, B_REDR, str, (xco+10) + 0.4 * (width-20), yco-24, 0.6 * (width-20), 19, + &randAct->distribution, 0.0, 0.0, 0, 0, + "Choose the type of distribution"); + + /* 3. property */ + uiDefBut(block, TEX, 1, "Property:", (xco+10), yco-44, (width-20), 19, + &randAct->propname, 0, MAX_NAME, 0, 0, + "Assign the random value to this property"); + + /*4. and 5. arguments for the distribution*/ + switch (randAct->distribution) { + case ACT_RANDOM_BOOL_CONST: + uiDefButBitI(block, TOG, 1, 1, "Always true", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, 2.0, 1, 0, 0, + "Always false or always true"); + break; + case ACT_RANDOM_BOOL_UNIFORM: + uiDefBut(block, LABEL, 0, " Do a 50-50 pick", (xco+10), yco-64, (width-20), 19, + NULL, 0, 0, 0, 0, + "Choose between true and false, 50% chance each"); + break; + case ACT_RANDOM_BOOL_BERNOUILLI: + uiDefButF(block, NUM, 1, "Chance", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Pick a number between 0 and 1. Success if you stay " + "below this value"); + break; + case ACT_RANDOM_INT_CONST: + uiDefButI(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_INT_UNIFORM: + uiDefButI(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->int_arg_1, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Lower boundary of the range"); + uiDefButI(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->int_arg_2, -1000, 1000, 0, 0, + "Choose a number from a range. " + "Upper boundary of the range"); + break; + case ACT_RANDOM_INT_POISSON: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.01, 100.0, 0, 0, + "Expected mean value of the distribution"); + break; + case ACT_RANDOM_FLOAT_CONST: + uiDefButF(block, NUM, 1, "Value: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.0, 1.0, 0, 0, + "Always return this number"); + break; + case ACT_RANDOM_FLOAT_UNIFORM: + uiDefButF(block, NUM, 1, "Min: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "Choose a number from a range" + "Lower boundary of the range"); + uiDefButF(block, NUM, 1, "Max: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, -10000.0, 10000.0, 0, 0, + "Choose a number from a range" + "Upper boundary of the range"); + break; + case ACT_RANDOM_FLOAT_NORMAL: + uiDefButF(block, NUM, 1, "Mean: ", (xco+10), yco-64, (width-20)/2, 19, + &randAct->float_arg_1, -10000.0, 10000.0, 0, 0, + "A normal distribution. Mean of the distribution"); + uiDefButF(block, NUM, 1, "SD: ", (xco+10) + (width-20)/2, yco-64, (width-20)/2, 19, + &randAct->float_arg_2, 0.0, 10000.0, 0, 0, + "A normal distribution. Standard deviation of the " + "distribution"); + break; + case ACT_RANDOM_FLOAT_NEGATIVE_EXPONENTIAL: + uiDefButF(block, NUM, 1, "Half-life time: ", (xco+10), yco-64, (width-20), 19, + &randAct->float_arg_1, 0.001, 10000.0, 0, 0, + "Negative exponential dropoff"); + break; + default: + ; /* don't know what this distro is... can be useful for testing */ + /* though :) */ + } - ysize = 50; - if (tdfa->type == ACT_2DFILTER_CUSTOMFILTER) { - ysize +=20; - } - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + yco-= ysize; + break; + case ACT_MESSAGE: + ma = act->data; - switch (tdfa->type) { - case ACT_2DFILTER_MOTIONBLUR: - if (!tdfa->flag) { - uiDefButS(block, TOG, B_REDR, "D", xco+30, yco-44, 19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur"); - uiDefButF(block, NUM, B_REDR, "Value:", xco+52, yco-44, width-82, 19, &tdfa->float_arg, 0.0, 1.0, 0.0, 0.0, "Set motion blur value"); - } - else { - uiDefButS(block, TOG, B_REDR, "Disabled", xco+30, yco-44, width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur"); - } - break; - case ACT_2DFILTER_BLUR: - case ACT_2DFILTER_SHARPEN: - case ACT_2DFILTER_DILATION: - case ACT_2DFILTER_EROSION: - case ACT_2DFILTER_LAPLACIAN: - case ACT_2DFILTER_SOBEL: - case ACT_2DFILTER_PREWITT: - case ACT_2DFILTER_GRAYSCALE: - case ACT_2DFILTER_SEPIA: - case ACT_2DFILTER_INVERT: - case ACT_2DFILTER_NOFILTER: - case ACT_2DFILTER_DISABLED: - case ACT_2DFILTER_ENABLED: - uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); - break; - case ACT_2DFILTER_CUSTOMFILTER: - uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); - uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30, yco-64, width-60, 19, &tdfa->text, ""); - break; - } - - str= "2D Filter %t|Motion Blur %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|" - "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|" - "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|"; - uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type"); - - yco -= ysize; - break; - case ACT_PARENT: - parAct = act->data; + ysize = 4 + (3 * 24); /* footer + number of lines * 24 pixels/line */ - if (parAct->type==ACT_PARENT_SET) { - - ysize= 48; glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent"); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, - "Compound", - xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag, - 0.0, 0.0, 0, 0, - "Add this object shape to the parent shape (only if the parent shape is already compound)"); - uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, - "Ghost", - xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag, - 0.0, 0.0, 0, 0, - "Make this object ghost while parented (only if not compound)"); - uiBlockEndAlign(block); - } - else if (parAct->type==ACT_PARENT_REMOVE) { + uiEmboss((float)xco, (float)yco-ysize, + (float)xco+width, (float)yco, 1); + + myline=1; + + /* line 1: To */ + uiDefBut(block, TEX, 1, "To: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->toPropName, 0, MAX_NAME, 0, 0, + "Optional send message to objects with this name only, or empty to broadcast"); + + /* line 2: Message Subject */ + uiDefBut(block, TEX, 1, "Subject: ", + (xco+10), (yco-(myline++*24)), (width-20), 19, + &ma->subject, 0, MAX_NAME, 0, 0, + "Optional message subject. This is what can be filtered on"); + + /* line 3: Text/Property */ + uiDefButBitS(block, TOG, 1, B_REDR, "T/P", + (xco+10), (yco-(myline*24)), (0.20 * (width-20)), 19, + &ma->bodyType, 0.0, 0.0, 0, 0, + "Toggle message type: either Text or a PropertyName"); + + if (ma->bodyType == ACT_MESG_MESG) { + /* line 3: Message Body */ + uiDefBut(block, TEX, 1, "Body: ", + (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, + &ma->body, 0, MAX_NAME, 0, 0, + "Optional message body Text"); + } + else { + /* line 3: Property body (set by property) */ + uiDefBut(block, TEX, 1, "Propname: ", + (xco+10+(0.20*(width-20))), (yco-(myline++*24)), (0.8*(width-20)), 19, + &ma->body, 0, MAX_NAME, 0, 0, + "The message body will be set by the Property Value"); + } - ysize= 28; + yco -= ysize; + break; + case ACT_2DFILTER: + tdfa = act->data; + + ysize = 50; + if (tdfa->type == ACT_2DFILTER_CUSTOMFILTER) { + ysize +=20; + } glRects(xco, yco-ysize, xco+width, yco); uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - } - str= "Parent %t|Set Parent %x0|Remove Parent %x1"; - uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); + switch (tdfa->type) { + case ACT_2DFILTER_MOTIONBLUR: + if (!tdfa->flag) { + uiDefButS(block, TOG, B_REDR, "D", xco+30, yco-44, 19, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Disable Motion Blur"); + uiDefButF(block, NUM, B_REDR, "Value:", xco+52, yco-44, width-82, 19, &tdfa->float_arg, 0.0, 1.0, 0.0, 0.0, "Set motion blur value"); + } + else { + uiDefButS(block, TOG, B_REDR, "Disabled", xco+30, yco-44, width-60, 19, &tdfa->flag, 0.0, 0.0, 0.0, 0.0, "Enable Motion Blur"); + } + break; + case ACT_2DFILTER_BLUR: + case ACT_2DFILTER_SHARPEN: + case ACT_2DFILTER_DILATION: + case ACT_2DFILTER_EROSION: + case ACT_2DFILTER_LAPLACIAN: + case ACT_2DFILTER_SOBEL: + case ACT_2DFILTER_PREWITT: + case ACT_2DFILTER_GRAYSCALE: + case ACT_2DFILTER_SEPIA: + case ACT_2DFILTER_INVERT: + case ACT_2DFILTER_NOFILTER: + case ACT_2DFILTER_DISABLED: + case ACT_2DFILTER_ENABLED: + uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); + break; + case ACT_2DFILTER_CUSTOMFILTER: + uiDefButI(block, NUM, B_REDR, "Pass Number:", xco+30, yco-44, width-60, 19, &tdfa->int_arg, 0.0, MAX_RENDER_PASS-1, 0.0, 0.0, "Set filter order"); + uiDefIDPoinBut(block, test_scriptpoin_but, ID_SCRIPT, 1, "Script: ", xco+30, yco-64, width-60, 19, &tdfa->text, ""); + break; + } - yco-= ysize; - break; - case ACT_ARMATURE: - armAct = act->data; + str= "2D Filter %t|Motion Blur %x1|Blur %x2|Sharpen %x3|Dilation %x4|Erosion %x5|" + "Laplacian %x6|Sobel %x7|Prewitt %x8|Gray Scale %x9|Sepia %x10|Invert %x11|Custom Filter %x12|" + "Enable Filter %x-2|Disable Filter %x-1|Remove Filter %x0|"; + uiDefButS(block, MENU, B_REDR, str, xco+30, yco-24, width-60, 19, &tdfa->type, 0.0, 0.0, 0.0, 0.0, "2D filter type"); - if (ob->type == OB_ARMATURE) { - str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4"; - uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); + yco -= ysize; + break; + case ACT_PARENT: + parAct = act->data; - switch (armAct->type) { - case ACT_ARM_RUN: - ysize = 28; - break; - default: + if (parAct->type==ACT_PARENT_SET) { + + ysize= 48; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "OB:", xco+95, yco-24, (width-100), 19, &(parAct->ob), "Set this object as parent"); uiBlockBeginAlign(block); - but = uiDefBut(block, TEX, 1, "Bone: ", - (xco+5), (yco-44), (width-10)/2, 19, - armAct->posechannel, 0, MAX_NAME, 0, 0, - "Bone on which the constraint is defined"); - uiButSetFunc(but, check_armature_actuator, but, armAct); - but = uiDefBut(block, TEX, 1, "Cons: ", - (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19, - armAct->constraint, 0, MAX_NAME, 0, 0, - "Name of the constraint you want to control"); - uiButSetFunc(but, check_armature_actuator, but, armAct); + uiDefButBitS(block, TOGN, ACT_PARENT_COMPOUND, B_REDR, + "Compound", + xco + 5, yco - 44, (width - 10)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Add this object shape to the parent shape (only if the parent shape is already compound)"); + uiDefButBitS(block, TOGN, ACT_PARENT_GHOST, B_REDR, + "Ghost", + xco + 5 + ((width - 10)/2), yco - 44, (width - 10)/2, 19, &parAct->flag, + 0.0, 0.0, 0, 0, + "Make this object ghost while parented (only if not compound)"); uiBlockEndAlign(block); - ysize = 48; + } + else if (parAct->type==ACT_PARENT_REMOVE) { + + ysize= 28; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + } + + str= "Parent %t|Set Parent %x0|Remove Parent %x1"; + uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, parAct->type==1?(width-80):90, 19, &parAct->type, 0.0, 0.0, 0, 0, ""); + + yco-= ysize; + break; + case ACT_ARMATURE: + armAct = act->data; + + if (ob->type == OB_ARMATURE) { + str= "Constraint %t|Run armature %x0|Enable %x1|Disable %x2|Set target %x3|Set weight %x4"; + uiDefButI(block, MENU, B_REDR, str, xco+5, yco-24, (width-10)*0.35, 19, &armAct->type, 0.0, 0.0, 0, 0, ""); + switch (armAct->type) { - case ACT_ARM_SETTARGET: - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ", xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint"); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ", xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)"); - ysize += 40; - break; - case ACT_ARM_SETWEIGHT: - uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35, yco-24, (width-10)*0.65, 19, &armAct->weight, 0.0, 1.0, 0.0, 0.0, "Set weight of this constraint"); - break; + case ACT_ARM_RUN: + ysize = 28; + break; + default: + uiBlockBeginAlign(block); + but = uiDefBut(block, TEX, 1, "Bone: ", + (xco+5), (yco-44), (width-10)/2, 19, + armAct->posechannel, 0, MAX_NAME, 0, 0, + "Bone on which the constraint is defined"); + uiButSetFunc(but, check_armature_actuator, but, armAct); + but = uiDefBut(block, TEX, 1, "Cons: ", + (xco+5)+(width-10)/2, (yco-44), (width-10)/2, 19, + armAct->constraint, 0, MAX_NAME, 0, 0, + "Name of the constraint you want to control"); + uiButSetFunc(but, check_armature_actuator, but, armAct); + uiBlockEndAlign(block); + ysize = 48; + switch (armAct->type) { + case ACT_ARM_SETTARGET: + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Target: ", xco+5, yco-64, (width-10), 19, &(armAct->target), "Set this object as the target of the constraint"); + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, 1, "Secondary Target: ", xco+5, yco-84, (width-10), 19, &(armAct->subtarget), "Set this object as the secondary target of the constraint (only IK polar target at the moment)"); + ysize += 40; + break; + case ACT_ARM_SETWEIGHT: + uiDefButF(block, NUM, B_REDR, "Weight:", xco+5+(width-10)*0.35, yco-24, (width-10)*0.65, 19, &armAct->weight, 0.0, 1.0, 0.0, 0.0, "Set weight of this constraint"); + break; + } } } - } - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - yco-= ysize; - break; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + yco-= ysize; + break; - default: - ysize= 4; + default: + ysize= 4; - glRects(xco, yco-ysize, xco+width, yco); - uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); - - yco-= ysize; - break; + glRects(xco, yco-ysize, xco+width, yco); + uiEmboss((float)xco, (float)yco-ysize, (float)xco+width, (float)yco, 1); + + yco-= ysize; + break; } uiBlockSetEmboss(block, UI_EMBOSS); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index a6578ffb3f7..7eb0f676707 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -80,26 +80,17 @@ static void nla_action_get_color(AnimData *adt, bAction *act, float color[4]) { if (adt && (adt->flag & ADT_NLA_EDIT_ON)) { - // greenish color (same as tweaking strip) - hardcoded for now - color[0] = 0.30f; - color[1] = 0.95f; - color[2] = 0.10f; - color[3] = 0.30f; + /* greenish color (same as tweaking strip) */ + UI_GetThemeColor4fv(TH_NLA_TWEAK, color); } else { if (act) { - // reddish color - hardcoded for now - color[0] = 0.8f; - color[1] = 0.2f; - color[2] = 0.0f; - color[3] = 0.4f; + /* reddish color - same as dopesheet summary */ + UI_GetThemeColor4fv(TH_ANIM_ACTIVE, color); } else { - // greyish-red color - hardcoded for now - color[0] = 0.6f; - color[1] = 0.5f; - color[2] = 0.5f; - color[3] = 0.3f; + /* greyish-red color */ + UI_GetThemeColor4fv(TH_ANIM_INACTIVE, color); } } @@ -166,17 +157,11 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col /* Transition Clip */ if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bright blue color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.18f; - color[1] = 0.46f; - color[2] = 0.86f; + UI_GetThemeColor3fv(TH_NLA_TRANSITION_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) blue tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.11f; - color[1] = 0.15f; - color[2] = 0.19f; + UI_GetThemeColor3fv(TH_NLA_TRANSITION, color); } } else if (strip->type == NLASTRIP_TYPE_META) { @@ -184,34 +169,22 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col // TODO: should temporary metas get different colors too? if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bold purple color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.41f; - color[1] = 0.13f; - color[2] = 0.59f; + UI_GetThemeColor3fv(TH_NLA_META_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) dark purple tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.20f; - color[1] = 0.15f; - color[2] = 0.26f; + UI_GetThemeColor3fv(TH_NLA_META, color); } } else if (strip->type == NLASTRIP_TYPE_SOUND) { /* Sound Clip */ if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected - use a bright teal color */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.12f; - color[1] = 0.48f; - color[2] = 0.48f; + UI_GetThemeColor3fv(TH_NLA_SOUND_SEL, color); } else { /* normal, unselected strip - use (hardly noticeable) teal tinge */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.17f; - color[1] = 0.24f; - color[2] = 0.24f; + UI_GetThemeColor3fv(TH_NLA_SOUND, color); } } else { @@ -220,19 +193,13 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col /* active strip should be drawn green when it is acting as the tweaking strip. * however, this case should be skipped for when not in EditMode... */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.3f; - color[1] = 0.95f; - color[2] = 0.1f; + UI_GetThemeColor3fv(TH_NLA_TWEAK, color); } else if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) { /* alert user that this strip is also used by the tweaking track (this is set when going into * 'editmode' for that strip), since the edits made here may not be what the user anticipated */ - // FIXME: hardcoded temp-hack colors - color[0] = 0.85f; - color[1] = 0.0f; - color[2] = 0.0f; + UI_GetThemeColor3fv(TH_NLA_TWEAK_DUPLI, color); } else if (strip->flag & NLASTRIP_FLAG_SELECT) { /* selected strip - use theme color for selected */ @@ -792,21 +759,24 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View glEnable(GL_BLEND); /* draw backing strip behind channel name */ + // FIXME: hardcoded colors!!! if (group == 5) { - /* Action Line */ - // TODO: if tweaking some action, use the same color as for the tweaked track (quick hack done for now) + float color[4]; + + /* Action Line + * The alpha values action_get_color returns are only useful for drawing + * strips backgrounds but here we're doing channel list backgrounds instead + * so we ignore that and use our own when needed + */ + nla_action_get_color(adt, (bAction *)ale->data, color); + if (adt && (adt->flag & ADT_NLA_EDIT_ON)) { - // greenish color (same as tweaking strip) - hardcoded for now - glColor3f(0.3f, 0.95f, 0.1f); + /* Yes, the color vector has 4 components, BUT we only want to be using 3 of them! */ + glColor3fv(color); } else { - /* if a track is being solo'd, action is ignored, so draw less boldly (alpha lower) */ - float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f; - - if (ale->data) - glColor4f(0.8f, 0.2f, 0.0f, alpha); // reddish color - hardcoded for now - else - glColor4f(0.6f, 0.5f, 0.5f, alpha); // greyish-red color - hardcoded for now + float alpha = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3 : 1.0f; + glColor4f(color[0], color[1], color[2], alpha); } offset += 7 * indent; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 73ca9097610..12c369874fe 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1114,7 +1114,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( glDisable(GL_BLEND); /* outline active and selected emphasis */ - if( node->flag & (NODE_ACTIVE|SELECT) ) { + if (node->flag & (NODE_ACTIVE | SELECT)) { glEnable(GL_BLEND); glEnable( GL_LINE_SMOOTH ); /* using different shades of TH_TEXT_HI for the empasis, like triangle */ @@ -1132,7 +1132,7 @@ static void node_draw_reroute(const bContext *C, ARegion *ar, SpaceNode *UNUSED( /* only draw input socket. as they all are placed on the same position. * highlight also if node itself is selected, since we don't display the node body separately! */ - for(sock= node->inputs.first; sock; sock= sock->next) { + for (sock= node->inputs.first; sock; sock= sock->next) { node_socket_circle_draw(ntree, sock, socket_size, (sock->flag & SELECT) || (node->flag & SELECT)); } @@ -1188,6 +1188,47 @@ static void node_common_set_butfunc(bNodeType *ntype) } /* ****************** BUTTON CALLBACKS FOR SHADER NODES ***************** */ + +static void node_buts_image_user(uiLayout *layout, bContext *C, PointerRNA *imaptr, PointerRNA *iuserptr) +{ + uiLayout *col; + int source; + + if(!imaptr->data) + return; + + col = uiLayoutColumn(layout, 0); + + uiItemR(col, imaptr, "source", 0, "", ICON_NONE); + + source = RNA_enum_get(imaptr, "source"); + + if (source == IMA_SRC_SEQUENCE) { + /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ + Scene *scene = CTX_data_scene(C); + ImageUser *iuser = iuserptr->data; + char numstr[32]; + const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0); + BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr); + uiItemL(layout, numstr, ICON_NONE); + } + + if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { + col = uiLayoutColumn(layout, 1); + uiItemR(col, iuserptr, "frame_duration", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "frame_start", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "frame_offset", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "use_cyclic", 0, NULL, ICON_NONE); + uiItemR(col, iuserptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE); + } + + col = uiLayoutColumn(layout, 0); + + if (RNA_enum_get(imaptr, "type") == IMA_TYPE_MULTILAYER) + uiItemR(col, iuserptr, "layer", 0, NULL, ICON_NONE); + +} + static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA *ptr) { bNode *node = ptr->data; @@ -1259,16 +1300,25 @@ static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), Po static void node_shader_buts_tex_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); -} + node_buts_image_user(layout, C, &imaptr, &iuserptr); +} static void node_shader_buts_tex_environment(uiLayout *layout, bContext *C, PointerRNA *ptr) { + PointerRNA imaptr = RNA_pointer_get(ptr, "image"); + PointerRNA iuserptr = RNA_pointer_get(ptr, "image_user"); + uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); uiItemR(layout, ptr, "color_space", 0, "", ICON_NONE); uiItemR(layout, ptr, "projection", 0, "", ICON_NONE); + + node_buts_image_user(layout, C, &imaptr, &iuserptr); } static void node_shader_buts_tex_sky(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -1391,49 +1441,17 @@ static void node_shader_set_butfunc(bNodeType *ntype) static void node_composit_buts_image(uiLayout *layout, bContext *C, PointerRNA *ptr) { - uiLayout *col; bNode *node = ptr->data; - PointerRNA imaptr; - PropertyRNA *prop; - int source; + PointerRNA imaptr, iuserptr; uiTemplateID(layout, C, ptr, "image", NULL, "IMAGE_OT_open", NULL); if (!node->id) return; - prop = RNA_struct_find_property(ptr, "image"); - if (!prop || RNA_property_type(prop) != PROP_POINTER) return; - imaptr = RNA_property_pointer_get(ptr, prop); - - col = uiLayoutColumn(layout, 0); + imaptr = RNA_pointer_get(ptr, "image"); + RNA_pointer_create((ID *)ptr->id.data, &RNA_ImageUser, node->storage, &iuserptr); - uiItemR(col, &imaptr, "source", 0, NULL, ICON_NONE); - - source = RNA_enum_get(&imaptr, "source"); - - if (source == IMA_SRC_SEQUENCE) { - /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */ - Scene *scene = CTX_data_scene(C); - ImageUser *iuser = node->storage; - char numstr[32]; - const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0); - BLI_snprintf(numstr, sizeof(numstr), IFACE_("Frame: %d"), framenr); - uiItemL(layout, numstr, ICON_NONE); - } - - if (ELEM(source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - col = uiLayoutColumn(layout, 1); - uiItemR(col, ptr, "frame_duration", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "frame_start", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_cyclic", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_auto_refresh", UI_ITEM_R_ICON_ONLY, NULL, ICON_NONE); - } - - col = uiLayoutColumn(layout, 0); - - if (RNA_enum_get(&imaptr, "type") == IMA_TYPE_MULTILAYER) - uiItemR(col, ptr, "layer", 0, NULL, ICON_NONE); + node_buts_image_user(layout, C, &imaptr, &iuserptr); } static void node_composit_buts_renderlayers(uiLayout *layout, bContext *C, PointerRNA *ptr) @@ -2274,7 +2292,7 @@ static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), void node_composit_backdrop_viewer(SpaceNode *snode, ImBuf *backdrop, bNode *node, int x, int y) { // node_composit_backdrop_canvas(snode, backdrop, node, x, y); - if (node->custom1 == 0) { /// @todo: why did we need this one? + if (node->custom1 == 0) { const float backdropWidth = backdrop->x; const float backdropHeight = backdrop->y; const float cx = x + snode->zoom * backdropWidth * node->custom3; @@ -2400,6 +2418,11 @@ static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), } } +static void node_composit_buts_mask(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "mask", NULL, NULL, NULL); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2589,7 +2612,9 @@ static void node_composit_set_butfunc(bNodeType *ntype) ntype->uifuncbut = node_composit_buts_viewer_but; ntype->uibackdropfunc = node_composit_backdrop_viewer; break; - + case CMP_NODE_MASK: + ntype->uifunc= node_composit_buts_mask; + break; default: ntype->uifunc = NULL; } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 1b229c78e0f..b4e07546fa9 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2756,11 +2756,11 @@ static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int float coord_array[LINK_RESOL+1][2]; int i, b; - if(node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { + if (node_link_bezier_points(NULL, NULL, link, coord_array, LINK_RESOL)) { - for(i=0; i<tot-1; i++) - for(b=0; b<LINK_RESOL; b++) - if(isect_line_line_v2(mcoords[i], mcoords[i+1], coord_array[b], coord_array[b+1]) > 0) { + for (i=0; i<tot-1; i++) + for (b=0; b<LINK_RESOL; b++) + if (isect_line_line_v2(mcoords[i], mcoords[i+1], coord_array[b], coord_array[b+1]) > 0) { result[0] = (mcoords[i][0]+mcoords[i+1][0])/2.0f; result[1] = (mcoords[i][1]+mcoords[i+1][1])/2.0f; return 1; @@ -2783,18 +2783,18 @@ static int add_reroute_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(&ar->v2d, (short)loc[0], (short)loc[1], &mcoords[i][0], &mcoords[i][1]); i++; - if(i>= 256) break; + if (i>= 256) break; } RNA_END; - if(i>1) { + if (i>1) { bNodeLink *link; float insertPoint[2]; ED_preview_kill_jobs(C); - for(link= snode->edittree->links.first; link; link=link->next) { - if(add_reroute_intersect_check(link, mcoords, i, insertPoint)) { + for (link= snode->edittree->links.first; link; link=link->next) { + if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) { bNodeTemplate ntemp; bNode *rerouteNode; diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 35b1583b24e..9e873799f1c 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -50,8 +50,7 @@ struct bNodeLink; struct Main; /* temp data to pass on to modal */ -typedef struct bNodeLinkDrag -{ +typedef struct bNodeLinkDrag { struct bNodeLinkDrag *next, *prev; /* List of links dragged by the operator. diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index 0a3678ca901..e7be750928d 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -76,7 +76,7 @@ static bNode *node_under_mouse_tweak(bNodeTree *ntree, int mx, int my) { bNode *node; - for(node=ntree->nodes.last; node; node=node->prev) { + for (node=ntree->nodes.last; node; node=node->prev) { if (node->typeinfo->tweak_area_func) { if (node->typeinfo->tweak_area_func(node, mx, my)) return node; diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 520a9f1cd22..66919935d48 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -245,6 +245,13 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) break; } break; + case NC_MASK: + if (wmn->action == NA_EDITED) { + if (type==NTREE_COMPOSIT) { + ED_area_tag_refresh(sa); + } + } + break; case NC_IMAGE: if (wmn->action == NA_EDITED) { diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 547e8288d20..f0ecaf3ab2c 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -69,6 +69,9 @@ #include "outliner_intern.h" +/* disable - this is far too slow - campbell */ +// #define USE_GROUP_SELECT + /* ****************************************************** */ /* Tree Size Functions */ @@ -207,6 +210,7 @@ static int group_restrict_flag(Group *gr, int flag) return 1; } +#ifdef USE_GROUP_SELECT static int group_select_flag(Group *gr) { GroupObject *gob; @@ -217,6 +221,7 @@ static int group_select_flag(Group *gr) return 0; } +#endif void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag) { @@ -422,16 +427,26 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar gr = (Group *)tselem->id; uiBlockSetEmboss(block, UI_EMBOSSN); - + +#ifndef USE_GROUP_SELECT + restrict_bool = FALSE; +#endif + +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); - + +#ifdef USE_GROUP_SELECT restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER); +#endif bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X - 1, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); @@ -1042,15 +1057,15 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto case TSE_POSEGRP_BASE: UI_icon_draw(x, y, ICON_GROUP_BONE); break; case TSE_SEQUENCE: - if (te->idcode == SEQ_MOVIE) + if (te->idcode == SEQ_TYPE_MOVIE) UI_icon_draw(x, y, ICON_SEQUENCE); - else if (te->idcode == SEQ_META) + else if (te->idcode == SEQ_TYPE_META) UI_icon_draw(x, y, ICON_DOT); - else if (te->idcode == SEQ_SCENE) + else if (te->idcode == SEQ_TYPE_SCENE) UI_icon_draw(x, y, ICON_SCENE); - else if (te->idcode == SEQ_SOUND) + else if (te->idcode == SEQ_TYPE_SOUND_RAM) UI_icon_draw(x, y, ICON_SOUND); - else if (te->idcode == SEQ_IMAGE) + else if (te->idcode == SEQ_TYPE_IMAGE) UI_icon_draw(x, y, ICON_IMAGE_COL); else UI_icon_draw(x, y, ICON_PARTICLES); @@ -1274,8 +1289,8 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene } } else if (te->idcode == ID_GR) { +#ifdef USE_GROUP_SELECT Group *gr = (Group *)tselem->id; - if (group_select_flag(gr)) { char col[4]; UI_GetThemeColorType4ubv(TH_SELECT, SPACE_VIEW3D, col); @@ -1284,6 +1299,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene active = 2; } +#endif } else if (te->idcode == ID_OB) { Object *ob = (Object *)tselem->id; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index a752a7d71ae..e5f7b8fd76d 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -1503,7 +1503,12 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) scene = (Scene *)outliner_search_back(soops, te_found, ID_SCE); if (scene == NULL) { - return OPERATOR_CANCELLED; + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + + scene = CTX_data_scene(C); } if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index b556fbf5c9d..3d01de1c67a 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -385,6 +385,18 @@ static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElemen } } +static void group_instance_cb(bContext *C, Scene *scene, TreeElement *UNUSED(te), + TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) +{ + Group *group = (Group *)tselem->id; + + Object *ob = ED_object_add_type(C, OB_EMPTY, scene->cursor, NULL, FALSE, scene->layact); + rename_id(&ob->id, group->id.name + 2); + ob->dup_group = group; + ob->transflag |= OB_DUPLIGROUP; + id_lib_extern(&group->id); +} + void outliner_do_object_operation(bContext *C, Scene *scene_act, SpaceOops *soops, ListBase *lb, void (*operation_cb)(bContext *C, Scene *scene, TreeElement *, TreeStoreElem *, TreeStoreElem *)) @@ -636,13 +648,14 @@ void OUTLINER_OT_object_operation(wmOperatorType *ot) /* **************************************** */ static EnumPropertyItem prop_group_op_types[] = { - {1, "UNLINK", 0, "Unlink", ""}, - {2, "LOCAL", 0, "Make Local", ""}, - {3, "LINK", 0, "Link Group Objects to Scene", ""}, - {4, "TOGVIS", 0, "Toggle Visible", ""}, - {5, "TOGSEL", 0, "Toggle Selectable", ""}, - {6, "TOGREN", 0, "Toggle Renderable", ""}, - {7, "RENAME", 0, "Rename", ""}, + {0, "UNLINK", 0, "Unlink Group", ""}, + {1, "LOCAL", 0, "Make Local Group", ""}, + {2, "LINK", 0, "Link Group Objects to Scene", ""}, + {3, "INSTANCE", 0, "Instance Groups in Scene", ""}, + {4, "TOGVIS", 0, "Toggle Visible Group", ""}, + {5, "TOGSEL", 0, "Toggle Selectable", ""}, + {6, "TOGREN", 0, "Toggle Renderable", ""}, + {7, "RENAME", 0, "Rename", ""}, {0, NULL, 0, NULL, NULL} }; @@ -651,45 +664,36 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); SpaceOops *soops = CTX_wm_space_outliner(C); int event; - const char *str = NULL; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event = RNA_enum_get(op->ptr, "type"); - - if (event == 1) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); - str = "Unlink group"; - } - else if (event == 2) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); - str = "Localized Data"; - } - else if (event == 3) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); - str = "Link Group Objects to Scene"; - } - else if (event == 4) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb); - str = "Toggle Visibility"; - } - else if (event == 5) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb); - str = "Toggle Selectability"; - } - else if (event == 6) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb); - str = "Toggle Renderability"; - } - else if (event == 7) { - outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); - str = "Rename"; + + switch (event) { + case 0: outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb); break; + case 1: outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb); break; + case 2: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb); break; + case 3: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_instance_cb); break; + case 4: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb); break; + case 5: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb); break; + case 6: outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb); break; + case 7: outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb); break; + default: + BLI_assert(0); + return OPERATOR_CANCELLED; } + + if (event == 3) { /* instance */ + Main *bmain = CTX_data_main(C); + + /* works without this except if you try render right after, see: 22027 */ + DAG_scene_sort(bmain, scene); + } - ED_undo_push(C, str); + ED_undo_push(C, prop_group_op_types[event].name); WM_event_add_notifier(C, NC_GROUP, NULL); return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index ff3648fc2b8..63907f530eb 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -899,14 +899,14 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->directdata = seq; te->name = seq->name + 2; - if (seq->type < SEQ_EFFECT) { + if (seq->type < SEQ_TYPE_EFFECT) { /* * This work like the sequence. * If the sequence have a name (not default name) * show it, in other case put the filename. */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { p = seq->seqbase.first; while (p) { outliner_add_element(soops, &te->subtree, (void *)p, te, TSE_SEQUENCE, index); diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c index 4d45be561c6..c78be8bd223 100644 --- a/source/blender/editors/space_outliner/space_outliner.c +++ b/source/blender/editors/space_outliner/space_outliner.c @@ -98,7 +98,16 @@ static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event) if (te_valid) { /* check that parent/child are both in the same scene */ Scene *scene = (Scene *)outliner_search_back(soops, te_valid, ID_SCE); - if (BKE_scene_base_find(scene, (Object *)id)) { + + if (!scene) { + /* currently outlier organized in a way, that if there's no parent scene + * element for object it means that all displayed objects belong to + * active scene and parenting them is allowed (sergey) + */ + return 1; + } + + if (scene && BKE_scene_base_find(scene, (Object *)id)) { return 1; } } diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 9eb4c62789e..26bedd14d6e 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -46,6 +46,7 @@ #include "BLI_utildefines.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_userdef_types.h" #include "BKE_context.h" @@ -54,6 +55,8 @@ #include "BKE_main.h" #include "BKE_sequencer.h" #include "BKE_movieclip.h" +#include "BKE_sequencer.h" +#include "BKE_mask.h" #include "BKE_report.h" #include "WM_api.h" @@ -228,8 +231,8 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op) } seq = alloc_sequence(ed->seqbasep, start_frame, channel); - seq->type = SEQ_SCENE; - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->type = SEQ_TYPE_SCENE; + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ seq->scene = sce_seq; @@ -327,8 +330,8 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) } seq = alloc_sequence(ed->seqbasep, start_frame, channel); - seq->type = SEQ_MOVIECLIP; - seq->blend_mode = SEQ_CROSS; + seq->type = SEQ_TYPE_MOVIECLIP; + seq->blend_mode = SEQ_TYPE_CROSS; seq->clip = clip; if (seq->clip->id.us == 0) @@ -360,7 +363,6 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (!ED_operator_sequencer_active(C)) { @@ -377,11 +379,10 @@ static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmE // return WM_menu_invoke(C, op, event); } - void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot) { PropertyRNA *prop; - + /* identifiers */ ot->name = "Add MovieClip Strip"; ot->idname = "SEQUENCER_OT_movieclip_strip_add"; @@ -392,16 +393,113 @@ void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot) ot->exec = sequencer_add_movieclip_strip_exec; ot->poll = ED_operator_scene_editable; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); prop = RNA_def_enum(ot->srna, "clip", DummyRNA_NULL_items, 0, "Clip", ""); RNA_def_enum_funcs(prop, RNA_movieclip_itemf); ot->prop = prop; } +static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = BKE_sequencer_editing_get(scene, TRUE); + + Mask *mask; + + Sequence *seq; /* generic strip vars */ + Strip *strip; + + int start_frame, channel; /* operator props */ + + start_frame = RNA_int_get(op->ptr, "frame_start"); + channel = RNA_int_get(op->ptr, "channel"); + + mask = BLI_findlink(&CTX_data_main(C)->mask, RNA_enum_get(op->ptr, "mask")); + + if (mask == NULL) { + BKE_report(op->reports, RPT_ERROR, "Mask not found"); + return OPERATOR_CANCELLED; + } + + seq = alloc_sequence(ed->seqbasep, start_frame, channel); + seq->type = SEQ_TYPE_MASK; + seq->blend_mode = SEQ_TYPE_CROSS; + seq->mask = mask; + + if (seq->mask->id.us == 0) + seq->mask->id.us = 1; + + /* basic defaults */ + seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); + seq->len = BKE_mask_get_duration(mask); + strip->us = 1; + + BLI_strncpy(seq->name + 2, mask->id.name + 2, sizeof(seq->name) - 2); + seqbase_unique_name_recursive(&ed->seqbase, seq); + + calc_sequence_disp(scene, seq); + BKE_sequencer_sort(scene); + + if (RNA_boolean_get(op->ptr, "replace_sel")) { + ED_sequencer_deselect_all(scene); + BKE_sequencer_active_set(scene, seq); + seq->flag |= SELECT; + } + + if (RNA_boolean_get(op->ptr, "overlap") == FALSE) { + if (seq_test_overlap(ed->seqbasep, seq)) shuffle_seq(ed->seqbasep, seq, scene); + } + + WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); + + return OPERATOR_FINISHED; +} + +static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (!ED_operator_sequencer_active(C)) { + BKE_report(op->reports, RPT_ERROR, "Sequencer area not active"); + return OPERATOR_CANCELLED; + } + + if (!RNA_struct_property_is_set(op->ptr, "mask")) + return WM_enum_search_invoke(C, op, event); + + sequencer_generic_invoke_xy__internal(C, op, event, 0); + return sequencer_add_mask_strip_exec(C, op); + // needs a menu + // return WM_menu_invoke(C, op, event); +} + + +void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Add Mask Strip"; + ot->idname = "SEQUENCER_OT_mask_strip_add"; + ot->description = "Add a mask strip to the sequencer"; + + /* api callbacks */ + ot->invoke = sequencer_add_mask_strip_invoke; + ot->exec = sequencer_add_mask_strip_exec; + + ot->poll = ED_operator_scene_editable; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); + prop = RNA_def_enum(ot->srna, "mask", DummyRNA_NULL_items, 0, "Mask", ""); + RNA_def_enum_funcs(prop, RNA_mask_itemf); + ot->prop = prop; +} + static int sequencer_add_generic_strip_exec(bContext *C, wmOperator *op, SeqLoadFunc seq_load_func) { @@ -740,14 +838,14 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op) seq->strip = strip = MEM_callocN(sizeof(Strip), "strip"); strip->us = 1; - if (seq->type == SEQ_COLOR) { + if (seq->type == SEQ_TYPE_COLOR) { SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; RNA_float_get_array(op->ptr, "color", colvars->col); - seq->blend_mode = SEQ_CROSS; /* so alpha adjustment fade to the strip below */ + seq->blend_mode = SEQ_TYPE_CROSS; /* so alpha adjustment fade to the strip below */ } - else if (seq->type == SEQ_ADJUSTMENT) { - seq->blend_mode = SEQ_CROSS; + else if (seq->type == SEQ_TYPE_ADJUSTMENT) { + seq->blend_mode = SEQ_TYPE_CROSS; } /* an unset channel is a special case where we automatically go above @@ -832,6 +930,6 @@ void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot) WM_operator_properties_filesel(ot, 0, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); - RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); + RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); RNA_def_float_vector(ot->srna, "color", 3, NULL, 0.0f, 1.0f, "Color", "Initialize the strip with this color (only used when type='COLOR')", 0.0f, 1.0f); } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 236baea01be..b674943b2dc 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -40,6 +40,7 @@ #include "IMB_imbuf_types.h" #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" @@ -58,7 +59,9 @@ #include "ED_anim_api.h" #include "ED_markers.h" +#include "ED_mask.h" #include "ED_types.h" +#include "ED_space_api.h" #include "UI_interface.h" #include "UI_resources.h" @@ -82,23 +85,27 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ SolidColorVars *colvars = (SolidColorVars *)seq->effectdata; switch (seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: UI_GetThemeColor3ubv(TH_SEQ_IMAGE, col); break; - case SEQ_META: + case SEQ_TYPE_META: UI_GetThemeColor3ubv(TH_SEQ_META, col); break; - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: UI_GetThemeColor3ubv(TH_SEQ_MOVIE, col); break; - case SEQ_MOVIECLIP: + case SEQ_TYPE_MOVIECLIP: UI_GetThemeColor3ubv(TH_SEQ_MOVIECLIP, col); break; - - case SEQ_SCENE: + + case SEQ_TYPE_MASK: + UI_GetThemeColor3ubv(TH_SEQ_MASK, col); /* TODO */ + break; + + case SEQ_TYPE_SCENE: UI_GetThemeColor3ubv(TH_SEQ_SCENE, col); if (seq->scene == curscene) { @@ -107,45 +114,45 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ break; /* transitions */ - case SEQ_CROSS: - case SEQ_GAMCROSS: - case SEQ_WIPE: + case SEQ_TYPE_CROSS: + case SEQ_TYPE_GAMCROSS: + case SEQ_TYPE_WIPE: UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, col); /* slightly offset hue to distinguish different effects */ - if (seq->type == SEQ_CROSS) rgb_byte_set_hue_float_offset(col, 0.04); - if (seq->type == SEQ_GAMCROSS) rgb_byte_set_hue_float_offset(col, 0.08); - if (seq->type == SEQ_WIPE) rgb_byte_set_hue_float_offset(col, 0.12); + if (seq->type == SEQ_TYPE_CROSS) rgb_byte_set_hue_float_offset(col, 0.04); + if (seq->type == SEQ_TYPE_GAMCROSS) rgb_byte_set_hue_float_offset(col, 0.08); + if (seq->type == SEQ_TYPE_WIPE) rgb_byte_set_hue_float_offset(col, 0.12); break; /* effects */ - case SEQ_TRANSFORM: - case SEQ_SPEED: - case SEQ_ADD: - case SEQ_SUB: - case SEQ_MUL: - case SEQ_ALPHAOVER: - case SEQ_ALPHAUNDER: - case SEQ_OVERDROP: - case SEQ_GLOW: - case SEQ_MULTICAM: - case SEQ_ADJUSTMENT: + case SEQ_TYPE_TRANSFORM: + case SEQ_TYPE_SPEED: + case SEQ_TYPE_ADD: + case SEQ_TYPE_SUB: + case SEQ_TYPE_MUL: + case SEQ_TYPE_ALPHAOVER: + case SEQ_TYPE_ALPHAUNDER: + case SEQ_TYPE_OVERDROP: + case SEQ_TYPE_GLOW: + case SEQ_TYPE_MULTICAM: + case SEQ_TYPE_ADJUSTMENT: UI_GetThemeColor3ubv(TH_SEQ_EFFECT, col); /* slightly offset hue to distinguish different effects */ - if (seq->type == SEQ_ADD) rgb_byte_set_hue_float_offset(col, 0.04); - else if (seq->type == SEQ_SUB) rgb_byte_set_hue_float_offset(col, 0.08); - else if (seq->type == SEQ_MUL) rgb_byte_set_hue_float_offset(col, 0.12); - else if (seq->type == SEQ_ALPHAOVER) rgb_byte_set_hue_float_offset(col, 0.16); - else if (seq->type == SEQ_ALPHAUNDER) rgb_byte_set_hue_float_offset(col, 0.20); - else if (seq->type == SEQ_OVERDROP) rgb_byte_set_hue_float_offset(col, 0.24); - else if (seq->type == SEQ_GLOW) rgb_byte_set_hue_float_offset(col, 0.28); - else if (seq->type == SEQ_TRANSFORM) rgb_byte_set_hue_float_offset(col, 0.36); - else if (seq->type == SEQ_MULTICAM) rgb_byte_set_hue_float_offset(col, 0.32); - else if (seq->type == SEQ_ADJUSTMENT) rgb_byte_set_hue_float_offset(col, 0.40); + if (seq->type == SEQ_TYPE_ADD) rgb_byte_set_hue_float_offset(col, 0.04); + else if (seq->type == SEQ_TYPE_SUB) rgb_byte_set_hue_float_offset(col, 0.08); + else if (seq->type == SEQ_TYPE_MUL) rgb_byte_set_hue_float_offset(col, 0.12); + else if (seq->type == SEQ_TYPE_ALPHAOVER) rgb_byte_set_hue_float_offset(col, 0.16); + else if (seq->type == SEQ_TYPE_ALPHAUNDER) rgb_byte_set_hue_float_offset(col, 0.20); + else if (seq->type == SEQ_TYPE_OVERDROP) rgb_byte_set_hue_float_offset(col, 0.24); + else if (seq->type == SEQ_TYPE_GLOW) rgb_byte_set_hue_float_offset(col, 0.28); + else if (seq->type == SEQ_TYPE_TRANSFORM) rgb_byte_set_hue_float_offset(col, 0.36); + else if (seq->type == SEQ_TYPE_MULTICAM) rgb_byte_set_hue_float_offset(col, 0.32); + else if (seq->type == SEQ_TYPE_ADJUSTMENT) rgb_byte_set_hue_float_offset(col, 0.40); break; - case SEQ_COLOR: + case SEQ_TYPE_COLOR: if (colvars->col) { rgb_float_to_uchar(col, colvars->col); } @@ -154,7 +161,7 @@ static void get_seq_color3ubv(Scene *curscene, Sequence *seq, unsigned char col[ } break; - case SEQ_SOUND: + case SEQ_TYPE_SOUND_RAM: UI_GetThemeColor3ubv(TH_SEQ_AUDIO, col); blendcol[0] = blendcol[1] = blendcol[2] = 128; if (seq->flag & SEQ_MUTE) UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20); @@ -362,7 +369,7 @@ static void draw_seq_handle(View2D *v2d, Sequence *seq, float pixelx, short dire } /* draw! */ - if (seq->type < SEQ_EFFECT || + if (seq->type < SEQ_TYPE_EFFECT || get_sequence_effect_num_inputs(seq->type) == 0) { glEnable(GL_BLEND); @@ -409,7 +416,7 @@ static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq) unsigned char col[3], blendcol[3]; View2D *v2d = &ar->v2d; - if (seq->type >= SEQ_EFFECT) return; + if (seq->type >= SEQ_TYPE_EFFECT) return; x1 = seq->startdisp; x2 = seq->enddisp; @@ -521,10 +528,10 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float if (name[0] == '\0') name = give_seqname(seq); - if (seq->type == SEQ_META || seq->type == SEQ_ADJUSTMENT) { + if (seq->type == SEQ_TYPE_META || seq->type == SEQ_TYPE_ADJUSTMENT) { BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_SCENE) { + else if (seq->type == SEQ_TYPE_SCENE) { if (seq->scene) { if (seq->scene_camera) { BLI_snprintf(str, sizeof(str), "%d | %s: %s (%s)", @@ -540,7 +547,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float seq->len, name); } } - else if (seq->type == SEQ_MOVIECLIP) { + else if (seq->type == SEQ_TYPE_MOVIECLIP) { if (seq->clip && strcmp(name, seq->clip->id.name + 2) != 0) { BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->clip->id.name + 2); @@ -550,19 +557,29 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float seq->len, name); } } - else if (seq->type == SEQ_MULTICAM) { + else if (seq->type == SEQ_TYPE_MASK) { + if (seq->mask && strcmp(name, seq->mask->id.name + 2) != 0) { + BLI_snprintf(str, sizeof(str), "%d | %s: %s", + seq->len, name, seq->mask->id.name + 2); + } + else { + BLI_snprintf(str, sizeof(str), "%d | %s", + seq->len, name); + } + } + else if (seq->type == SEQ_TYPE_MULTICAM) { BLI_snprintf(str, sizeof(str), "Cam | %s: %d", name, seq->multicam_source); } - else if (seq->type == SEQ_IMAGE) { + else if (seq->type == SEQ_TYPE_IMAGE) { BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name); } - else if (seq->type & SEQ_EFFECT) { + else if (seq->type & SEQ_TYPE_EFFECT) { BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->sound) BLI_snprintf(str, sizeof(str), "%d | %s: %s", seq->len, name, seq->sound->name); @@ -570,7 +587,7 @@ static void draw_seq_text(View2D *v2d, Sequence *seq, float x1, float x2, float BLI_snprintf(str, sizeof(str), "%d | %s", seq->len, name); } - else if (seq->type == SEQ_MOVIE) { + else if (seq->type == SEQ_TYPE_MOVIE) { BLI_snprintf(str, sizeof(str), "%d | %s: %s%s", seq->len, name, seq->strip->dir, seq->strip->stripdata->name); } @@ -696,7 +713,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline x2 = seq->enddisp; /* draw sound wave */ - if (seq->type == SEQ_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_RAM) { drawseqwave(scene, seq, x1, y1, x2, y2, (ar->v2d.cur.xmax - ar->v2d.cur.xmin) / ar->winx); } @@ -743,7 +760,7 @@ static void draw_seq_strip(Scene *scene, ARegion *ar, Sequence *seq, int outline glDisable(GL_LINE_STIPPLE); } - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { drawmeta_contents(scene, seq, x1, y1, x2, y2); } @@ -969,6 +986,59 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* ortho at pixel level */ UI_view2d_view_restore(C); + + //if (sc->mode == SC_MODE_MASKEDIT) { + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + Sequence *seq_act = BKE_sequencer_active_get(scene); + + if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { + int x, y; + int width, height; + float zoomx, zoomy; + + /* frame image */ + float maxdim; + float xofs, yofs; + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + width = v2d->tot.xmax - v2d->tot.xmin; + height = v2d->tot.ymax - v2d->tot.ymin; + + zoomx = (float)(ar->winrct.xmax - ar->winrct.xmin + 1) / (float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)); + zoomy = (float)(ar->winrct.ymax - ar->winrct.ymin + 1) / (float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)); + + x += v2d->tot.xmin * zoomx; + y += v2d->tot.ymin * zoomy; + + /* frame the image */ + maxdim = maxf(width, height); + if (width == height) { + xofs = yofs = 0; + } + else if (width < height) { + xofs = ((height - width) / -2.0f) * zoomx; + yofs = 0.0f; + } + else { /* (width > height) */ + xofs = 0.0f; + yofs = ((width - height) / -2.0f) * zoomy; + } + + /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */ + glPushMatrix(); + glTranslatef(x + xofs, y + yofs, 0); + glScalef(maxdim * zoomx, maxdim * zoomy, 0); + + ED_mask_draw((bContext *)C, 0, 0); // sc->mask_draw_flag, sc->mask_draw_type + + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); + + glPopMatrix(); + } + } + } #if 0 diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 072cfa00622..c686f8440a9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -79,21 +79,21 @@ /* XXX */ /* RNA Enums, used in multiple files */ EnumPropertyItem sequencer_prop_effect_types[] = { - {SEQ_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"}, - {SEQ_ADD, "ADD", 0, "Add", "Add effect strip type"}, - {SEQ_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"}, - {SEQ_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"}, - {SEQ_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"}, - {SEQ_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"}, - {SEQ_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"}, - {SEQ_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"}, - {SEQ_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"}, - {SEQ_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"}, - {SEQ_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"}, - {SEQ_COLOR, "COLOR", 0, "Color", "Color effect strip type"}, - {SEQ_SPEED, "SPEED", 0, "Speed", "Color effect strip type"}, - {SEQ_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, - {SEQ_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, + {SEQ_TYPE_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"}, + {SEQ_TYPE_ADD, "ADD", 0, "Add", "Add effect strip type"}, + {SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"}, + {SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"}, + {SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"}, + {SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"}, + {SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"}, + {SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"}, + {SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"}, + {SEQ_TYPE_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"}, + {SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"}, + {SEQ_TYPE_COLOR, "COLOR", 0, "Color", "Color effect strip type"}, + {SEQ_TYPE_SPEED, "SPEED", 0, "Speed", "Color effect strip type"}, + {SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""}, + {SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""}, {0, NULL, 0, NULL, NULL} }; @@ -478,7 +478,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen for (seq = ed->seqbasep->first; seq; seq = seq->next) { if (seq->flag & SELECT) { - if (seq->type == SEQ_SOUND && get_sequence_effect_num_inputs(type) != 0) { + if (seq->type == SEQ_TYPE_SOUND_RAM && get_sequence_effect_num_inputs(type) != 0) { *error_str = "Can't apply effects to audio sequence strips"; return 0; } @@ -543,7 +543,7 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) if (!seq) return NULL; - else if (!(seq->type & SEQ_EFFECT)) + else if (!(seq->type & SEQ_TYPE_EFFECT)) return ((seq->flag & SELECT) ? NULL : seq); else if (!(seq->flag & SELECT)) { /* try to find replacement for effect inputs */ @@ -584,7 +584,7 @@ static void recurs_del_seq_flag(Scene *scene, ListBase *lb, short flag, short de if ((seq->flag & flag) || deleteall) { BLI_remlink(lb, seq); if (seq == last_seq) BKE_sequencer_active_set(scene, NULL); - if (seq->type == SEQ_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1); + if (seq->type == SEQ_TYPE_META) recurs_del_seq_flag(scene, &seq->seqbase, flag, 1); seq_free_sequence(scene, seq); } seq = seqn; @@ -616,7 +616,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) if ((seq->startstill) && (cutframe < seq->start)) { /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; seq->startstill = seq->start - cutframe; } @@ -637,7 +637,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe) else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) { seq->endstill -= seq->enddisp - cutframe; /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; } } @@ -712,7 +712,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) if ((seq->startstill) && (cutframe < seq->start)) { /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; seq->startstill = seq->start - cutframe; } @@ -731,7 +731,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe) else if (((seq->start + seq->len) < cutframe) && (seq->endstill)) { seq->endstill -= seq->enddisp - cutframe; /* don't do funny things with METAs ... */ - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { skip_dup = TRUE; } } @@ -855,7 +855,7 @@ static void UNUSED_FUNCTION(touch_seq_files) (Scene * scene) SEQP_BEGIN (ed, seq) { if (seq->flag & SELECT) { - if (seq->type == SEQ_MOVIE) { + if (seq->type == SEQ_TYPE_MOVIE) { if (seq->strip && seq->strip->stripdata) { BLI_make_file_string(G.main->name, str, seq->strip->dir, seq->strip->stripdata->name); BLI_file_touch(seq->name); @@ -883,7 +883,7 @@ static void set_filter_seq(Scene *scene) SEQP_BEGIN (ed, seq) { if (seq->flag & SELECT) { - if (seq->type == SEQ_MOVIE) { + if (seq->type == SEQ_TYPE_MOVIE) { seq->flag |= SEQ_FILTERY; reload_sequence_new_file(scene, seq, FALSE); calc_sequence(scene, seq); @@ -1052,7 +1052,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op) shuffle_seq(ed->seqbasep, seq, scene); } } - else if (seq->type & SEQ_EFFECT) { + else if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && (seq->seq1->flag & SELECT)) calc_sequence(scene, seq); else if (seq->seq2 && (seq->seq2->flag & SELECT)) @@ -1368,7 +1368,7 @@ static int sequencer_effect_poll(bContext *C) if (ed) { Sequence *last_seq = BKE_sequencer_active_get(scene); - if (last_seq && (last_seq->type & SEQ_EFFECT)) { + if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) { return 1; } } @@ -1626,7 +1626,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op)) /* for effects, try to find a replacement input */ for (seq = ed->seqbasep->first; seq; seq = seq->next) - if ((seq->type & SEQ_EFFECT) && !(seq->flag & SELECT)) + if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SELECT)) del_seq_find_replace_recurs(scene, seq); /* delete all selected strips */ @@ -1679,7 +1679,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) /* for effects, try to find a replacement input */ for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->type & SEQ_EFFECT) == 0 && (seq->flag & SELECT)) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0; } } @@ -1692,7 +1692,7 @@ static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op)) } for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if ((seq->type & SEQ_EFFECT) == 0 && (seq->flag & SELECT)) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) { if (seq_test_overlap(ed->seqbasep, seq)) { shuffle_seq(ed->seqbasep, seq, scene); } @@ -1737,7 +1737,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) seq = ed->seqbasep->first; /* poll checks this is valid */ while (seq) { - if ((seq->flag & SELECT) && (seq->type == SEQ_IMAGE) && (seq->len > 1)) { + if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) { /* remove seq so overlap tests don't conflict, * see seq_free_sequence below for the real free'ing */ BLI_remlink(ed->seqbasep, seq); @@ -1755,7 +1755,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) BLI_addtail(ed->seqbasep, seq_new); seq_new->start = start_ofs; - seq_new->type = SEQ_IMAGE; + seq_new->type = SEQ_TYPE_IMAGE; seq_new->len = 1; seq_new->endstill = step - 1; @@ -1826,7 +1826,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op)) Sequence *last_seq = BKE_sequencer_active_get(scene); MetaStack *ms; - if (last_seq && last_seq->type == SEQ_META && last_seq->flag & SELECT) { + if (last_seq && last_seq->type == SEQ_TYPE_META && last_seq->flag & SELECT) { /* Enter Metastrip */ ms = MEM_mallocN(sizeof(MetaStack), "metastack"); BLI_addtail(&ed->metastack, ms); @@ -1904,7 +1904,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op) seqm = alloc_sequence(ed->seqbasep, 1, 1); /* channel number set later */ strcpy(seqm->name + 2, "MetaStrip"); - seqm->type = SEQ_META; + seqm->type = SEQ_TYPE_META; seqm->flag = SELECT; seq = ed->seqbasep->first; @@ -1970,7 +1970,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) Sequence *seq, *last_seq = BKE_sequencer_active_get(scene); /* last_seq checks (ed == NULL) */ - if (last_seq == NULL || last_seq->type != SEQ_META) + if (last_seq == NULL || last_seq->type != SEQ_TYPE_META) return OPERATOR_CANCELLED; BLI_movelisttolist(ed->seqbasep, &last_seq->seqbase); @@ -1983,7 +1983,7 @@ static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op)) /* emtpy meta strip, delete all effects depending on it */ for (seq = ed->seqbasep->first; seq; seq = seq->next) - if ((seq->type & SEQ_EFFECT) && seq_depends_on_meta(seq, last_seq)) + if ((seq->type & SEQ_TYPE_EFFECT) && seq_depends_on_meta(seq, last_seq)) seq->flag |= SEQ_FLAG_DELETE; recurs_del_seq_flag(scene, ed->seqbasep, SEQ_FLAG_DELETE, 0); @@ -2454,14 +2454,14 @@ static int sequencer_swap_exec(bContext *C, wmOperator *op) // XXX - should be a generic function for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) { - if ((iseq->type & SEQ_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { + if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { calc_sequence(scene, iseq); } } /* do this in a new loop since both effects need to be calculated first */ for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) { - if ((iseq->type & SEQ_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { + if ((iseq->type & SEQ_TYPE_EFFECT) && (seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) { /* this may now overlap */ if (seq_test_overlap(ed->seqbasep, iseq) ) { shuffle_seq(ed->seqbasep, iseq, scene); @@ -2512,16 +2512,16 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) if (active_seq->strip) { switch (active_seq->type) { - case SEQ_IMAGE: + case SEQ_TYPE_IMAGE: se = give_stripelem(active_seq, scene->r.cfra); break; - case SEQ_MOVIE: + case SEQ_TYPE_MOVIE: se = active_seq->strip->stripdata; break; - case SEQ_SCENE: - case SEQ_META: - case SEQ_RAM_SOUND: - case SEQ_HD_SOUND: + case SEQ_TYPE_SCENE: + case SEQ_TYPE_META: + case SEQ_TYPE_SOUND_RAM: + case SEQ_TYPE_SOUND_HD: default: break; } @@ -2559,7 +2559,7 @@ void SEQUENCER_OT_rendersize(wmOperatorType *ot) static void seq_copy_del_sound(Scene *scene, Sequence *seq) { - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { Sequence *iseq; for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) { seq_copy_del_sound(scene, iseq); @@ -2900,7 +2900,7 @@ static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op) /* free previous effect and init new effect */ struct SeqEffectHandle sh; - if ((seq->type & SEQ_EFFECT) == 0) { + if ((seq->type & SEQ_TYPE_EFFECT) == 0) { return OPERATOR_CANCELLED; } @@ -2947,7 +2947,7 @@ void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_CROSS, "Type", "Sequencer effect type"); + ot->prop = RNA_def_enum(ot->srna, "type", sequencer_prop_effect_types, SEQ_TYPE_CROSS, "Type", "Sequencer effect type"); } static int sequencer_change_path_exec(bContext *C, wmOperator *op) @@ -2958,7 +2958,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) Sequence *seq = BKE_sequencer_active_get(scene); const int is_relative_path = RNA_boolean_get(op->ptr, "relative_path"); - if (seq->type == SEQ_IMAGE) { + if (seq->type == SEQ_TYPE_IMAGE) { char directory[FILE_MAX]; const int len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files")); StripElem *se; @@ -3028,7 +3028,7 @@ static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UN RNA_string_set(op->ptr, "directory", seq->strip->dir); /* set default display depending on seq type */ - if (seq->type == SEQ_IMAGE) { + if (seq->type == SEQ_TYPE_IMAGE) { RNA_boolean_set(op->ptr, "filter_movie", FALSE); } else { diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 19cd7ed4ad4..25a322c6905 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -138,6 +138,7 @@ void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot); void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot); +void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot); void SEQUENCER_OT_effect_strip_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 3a02c90f99a..79ecd9f7481 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -105,6 +105,7 @@ void sequencer_operatortypes(void) /* sequencer_add.c */ WM_operatortype_append(SEQUENCER_OT_scene_strip_add); WM_operatortype_append(SEQUENCER_OT_movieclip_strip_add); + WM_operatortype_append(SEQUENCER_OT_mask_strip_add); WM_operatortype_append(SEQUENCER_OT_movie_strip_add); WM_operatortype_append(SEQUENCER_OT_sound_strip_add); WM_operatortype_append(SEQUENCER_OT_image_strip_add); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 3911ec0ef82..b03edfc61b9 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -171,11 +171,11 @@ void ED_sequencer_select_sequence_single(Scene * scene, Sequence * seq, int dese BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) { + if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { if (seq->strip) BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } - else if (seq->type == SEQ_SOUND) { + else if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->strip) BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); } @@ -409,13 +409,13 @@ static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event) if (seq) { BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_IMAGE) || (seq->type == SEQ_MOVIE)) { + if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { if (seq->strip) { BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } } else - if (seq->type == SEQ_SOUND) { + if (seq->type == SEQ_TYPE_SOUND_RAM) { if (seq->strip) { BLI_strncpy(ed->act_sounddir, seq->strip->dir, FILE_MAXDIR); } @@ -930,11 +930,11 @@ static EnumPropertyItem sequencer_prop_select_grouped_types[] = { {0, NULL, 0, NULL, NULL} }; -#define SEQ_IS_SOUND(_seq) ((_seq->type & SEQ_SOUND) && !(_seq->type & SEQ_EFFECT)) +#define SEQ_IS_SOUND(_seq) ((_seq->type & SEQ_TYPE_SOUND_RAM) && !(_seq->type & SEQ_TYPE_EFFECT)) -#define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_EFFECT) +#define SEQ_IS_EFFECT(_seq) (_seq->type & SEQ_TYPE_EFFECT) -#define SEQ_USE_DATA(_seq) (ELEM(_seq->type, SEQ_SCENE, SEQ_MOVIECLIP) || SEQ_HAS_PATH(_seq)) +#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) { @@ -1008,22 +1008,33 @@ static short select_grouped_data(Editing *ed, Sequence *actseq) } SEQ_END; } - else if (actseq->type == SEQ_SCENE) { + else if (actseq->type == SEQ_TYPE_SCENE) { Scene *sce = actseq->scene; SEQP_BEGIN (ed, seq) { - if (seq->type == SEQ_SCENE && seq->scene == sce) { + if (seq->type == SEQ_TYPE_SCENE && seq->scene == sce) { seq->flag |= SELECT; changed = TRUE; } } SEQ_END; } - else if (actseq->type == SEQ_MOVIECLIP) { + else if (actseq->type == SEQ_TYPE_MOVIECLIP) { MovieClip *clip = actseq->clip; SEQP_BEGIN (ed, seq) { - if (seq->type == SEQ_MOVIECLIP && seq->clip == clip) { + if (seq->type == SEQ_TYPE_MOVIECLIP && seq->clip == clip) { + seq->flag |= SELECT; + changed = TRUE; + } + } + SEQ_END; + } + else if (actseq->type == SEQ_TYPE_MASK) { + struct Mask *mask = actseq->mask; + SEQP_BEGIN (ed, seq) + { + if (seq->type == SEQ_TYPE_MASK && seq->mask == mask) { seq->flag |= SELECT; changed = TRUE; } @@ -1038,10 +1049,10 @@ static short select_grouped_effect(Editing *ed, Sequence *actseq) { Sequence *seq; short changed = FALSE; - short effects[SEQ_EFFECT_MAX + 1]; + short effects[SEQ_TYPE_EFFECT_MAX + 1]; int i; - for (i = 0; i <= SEQ_EFFECT_MAX; i++) + for (i = 0; i <= SEQ_TYPE_EFFECT_MAX; i++) effects[i] = FALSE; SEQP_BEGIN (ed, seq) @@ -1087,7 +1098,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) { Sequence *seq = NULL; short changed = FALSE; - short is_audio = ((actseq->type == SEQ_META) || SEQ_IS_SOUND(actseq)); + short is_audio = ((actseq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(actseq)); int startdisp = actseq->startdisp; int enddisp = actseq->enddisp; int machine = actseq->machine; @@ -1109,7 +1120,7 @@ static short select_grouped_effect_link(Editing *ed, Sequence *actseq) /* Ignore all seqs of incompatible types (audio vs video). */ if ((seq->flag & SELECT) || (seq->startdisp >= enddisp) || (seq->enddisp < startdisp) || (!is_audio && SEQ_IS_SOUND(seq)) || - (is_audio && !((seq->type == SEQ_META) || SEQ_IS_SOUND(seq)))) + (is_audio && !((seq->type == SEQ_TYPE_META) || SEQ_IS_SOUND(seq)))) { continue; } diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 4168cb9ac77..3643f92d334 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -33,6 +33,7 @@ #include <stdio.h> #include "DNA_scene_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -380,6 +381,29 @@ static void sequencer_dropboxes(void) /* ************* end drop *********** */ +const char *sequencer_context_dir[] = {"edit_mask", NULL}; + +static int sequencer_context(const bContext *C, const char *member, bContextDataResult *result) +{ + Scene *scene = CTX_data_scene(C); + + if (CTX_data_dir(member)) { + CTX_data_dir_set(result, sequencer_context_dir); + + return TRUE; + } + else if (CTX_data_equals(member, "edit_mask")) { + Sequence *seq_act = BKE_sequencer_active_get(scene); + if (seq_act && seq_act->type == SEQ_TYPE_MASK && seq_act->mask) { + CTX_data_id_pointer_set(result, &seq_act->mask->id); + } + return TRUE; + } + + return FALSE; +} + + /* add handlers, stuff you only do once or on area/region changes */ static void sequencer_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) { @@ -482,6 +506,12 @@ static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn) break; } break; + + case NC_MASK: + if (wmn->action == NA_EDITED) { + ED_region_tag_redraw(ar); + } + break; } } @@ -539,6 +569,7 @@ void ED_spacetype_sequencer(void) st->duplicate = sequencer_duplicate; st->operatortypes = sequencer_operatortypes; st->keymap = sequencer_keymap; + st->context = sequencer_context; st->dropboxes = sequencer_dropboxes; st->refresh = sequencer_refresh; @@ -591,4 +622,3 @@ void ED_spacetype_sequencer(void) sequencer_view3d_cb = ED_view3d_draw_offscreen_imbuf_simple; } } - diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index 0de7e2569c0..e51f7a312eb 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -557,7 +557,7 @@ static void draw_bone_solid_octahedral(void) /* *************** Armature drawing, bones ******************* */ -static void draw_bone_points(int dt, int armflag, unsigned int boneflag, int id) +static void draw_bone_points(const short dt, int armflag, unsigned int boneflag, int id) { /* Draw root point if we are not connected */ if ((boneflag & BONE_CONNECTED) == 0) { @@ -862,7 +862,7 @@ static void draw_sphere_bone_wire(float smat[][4], float imat[][4], } /* does wire only for outline selecting */ -static void draw_sphere_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { GLUquadricObj *qobj; @@ -1100,7 +1100,7 @@ static void draw_line_bone(int armflag, int boneflag, short constflag, unsigned glPopMatrix(); } -static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) +static void draw_b_bone_boxes(const short dt, bPoseChannel *pchan, float xwidth, float length, float zwidth) { int segments = 0; @@ -1128,7 +1128,7 @@ static void draw_b_bone_boxes(int dt, bPoseChannel *pchan, float xwidth, float l } } -static void draw_b_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_b_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { float xwidth, length, zwidth; @@ -1242,7 +1242,7 @@ static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float len } } -static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, +static void draw_wire_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone) { Mat4 *bbones = NULL; @@ -1293,7 +1293,7 @@ static void draw_wire_bone(int dt, int armflag, int boneflag, short constflag, u draw_wire_bone_segments(pchan, bbones, length, segments); } -static void draw_bone(int dt, int armflag, int boneflag, short constflag, unsigned int id, float length) +static void draw_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id, float length) { /* Draw a 3d octahedral bone, we use normalized space based on length, @@ -1364,7 +1364,7 @@ static void draw_bone(int dt, int armflag, int boneflag, short constflag, unsign } static void draw_custom_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, - int dt, int armflag, int boneflag, unsigned int id, float length) + const short dt, int armflag, int boneflag, unsigned int id, float length) { if (ob == NULL) return; @@ -1656,8 +1656,9 @@ static void bone_matrix_translate_y(float mat[][4], float y) } /* assumes object is Armature with pose */ -static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, - const short is_ghost, const short is_outline) +static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const unsigned char ob_wire_col[4], + const short do_const_color, const short is_outline) { RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; @@ -1752,8 +1753,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, if (bone == arm->act_bone) flag |= BONE_DRAW_ACTIVE; - /* set color-set to use */ - set_pchan_colorset(ob, pchan); + if (do_const_color) { + /* keep color */ + } + else { + /* set color-set to use */ + set_pchan_colorset(ob, pchan); + } if (use_custom) { /* if drawwire, don't try to draw in solid */ @@ -1827,20 +1833,13 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, } /* prepare colors */ - if (is_ghost) { + if (do_const_color) { /* 13 October 2009, Disabled this to make ghosting show the right colors (Aligorith) */ } - else if (arm->flag & ARM_POSEMODE) + else if (arm->flag & ARM_POSEMODE) set_pchan_colorset(ob, pchan); else { - if ((scene->basact) == base) { - if (base->flag & (SELECT + BA_WAS_SEL)) UI_ThemeColor(TH_ACTIVE); - else UI_ThemeColor(TH_WIRE); - } - else { - if (base->flag & (SELECT + BA_WAS_SEL)) UI_ThemeColor(TH_SELECT); - else UI_ThemeColor(TH_WIRE); - } + glColor3ubv(ob_wire_col); } /* catch exception for bone with hidden parent */ @@ -1956,7 +1955,12 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, /* extra draw service for pose mode */ /* set color-set to use */ - set_pchan_colorset(ob, pchan); + if (do_const_color) { + /* keep color */ + } + else { + set_pchan_colorset(ob, pchan); + } if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { /* custom bone shapes should not be drawn here! */ @@ -1991,20 +1995,35 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base, glDisable(GL_CULL_FACE); /* draw DoFs */ - if (arm->flag & ARM_POSEMODE) - draw_pose_dofs(ob); + if (arm->flag & ARM_POSEMODE) { + if (((base->flag & OB_FROMDUPLI) == 0)) { + draw_pose_dofs(ob); + } + } /* finally names and axes */ - if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && (is_outline == 0)) { + if ((arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) && + (is_outline == 0) && + ((base->flag & OB_FROMDUPLI) == 0)) + { /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ if ((G.f & G_PICKSEL) == 0) { float vec[3]; - + unsigned char col[4]; - float col_f[4]; - glGetFloatv(GL_CURRENT_COLOR, col_f); /* in case this is not set below */ - rgb_float_to_uchar(col, col_f); - col[3] = 255; + if (do_const_color) { + /* so we can draw bone names in current const color */ + float tcol[4]; + glGetFloatv(GL_CURRENT_COLOR, tcol); + rgb_float_to_uchar(col, tcol); + col[3] = 255; + } + else { + col[0] = ob_wire_col[0]; + col[1] = ob_wire_col[1]; + col[2] = ob_wire_col[2]; + col[3] = 255; + } if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -2063,7 +2082,7 @@ static void get_matrix_editbone(EditBone *eBone, float bmat[][4]) add_v3_v3(bmat[3], eBone->head); } -static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt) +static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) { RegionView3D *rv3d = ar->regiondata; EditBone *eBone; @@ -2353,7 +2372,7 @@ static void draw_ghost_poses_range(Scene *scene, View3D *v3d, ARegion *ar, Base BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2432,7 +2451,7 @@ static void draw_ghost_poses_keys(Scene *scene, View3D *v3d, ARegion *ar, Base * BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } glDisable(GL_BLEND); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); @@ -2502,7 +2521,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } } @@ -2517,7 +2536,7 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) if (CFRA != cfrao) { BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL); BKE_pose_where_is(scene, ob); - draw_pose_bones(scene, v3d, ar, base, OB_WIRE, TRUE, FALSE); + draw_pose_bones(scene, v3d, ar, base, OB_WIRE, NULL, TRUE, FALSE); } } } @@ -2537,8 +2556,11 @@ static void draw_ghost_poses(Scene *scene, View3D *v3d, ARegion *ar, Base *base) /* ********************************** Armature Drawing - Main ************************* */ -/* called from drawobject.c, return 1 if nothing was drawn */ -int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline) +/* called from drawobject.c, return 1 if nothing was drawn + * (ob_wire_col == NULL) when drawing ghost */ +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4], + const short is_outline) { Object *ob = base->object; bArmature *arm = ob->data; @@ -2549,11 +2571,8 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in if (dt > OB_WIRE && !ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { /* we use color for solid lighting */ - glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); - glColor3ub(255, 255, 255); // clear spec - glDisable(GL_COLOR_MATERIAL); - + const float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW); // only for lighting... } @@ -2594,7 +2613,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in if (arm->ghostep) draw_ghost_poses(scene, v3d, ar, base); } - if ((flag & DRAW_SCENESET) == 0) { + if ((dflag & DRAW_SCENESET) == 0) { if (ob == OBACT) arm->flag |= ARM_POSEMODE; else if (OBACT && (OBACT->mode & OB_MODE_WEIGHT_PAINT)) { @@ -2605,7 +2624,7 @@ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, in } } } - draw_pose_bones(scene, v3d, ar, base, dt, FALSE, is_outline); + draw_pose_bones(scene, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline); arm->flag &= ~ARM_POSEMODE; if (ob->mode & OB_MODE_POSE) diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index de1d9f22667..19696b2b0e0 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -1015,14 +1015,14 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *d if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) { if (do_light) { + const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f}; + /* enforce default material settings */ GPU_enable_material(0, NULL); /* but set default spec */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); /* according manpages needed */ - glColor3ub(120, 120, 120); - glDisable(GL_COLOR_MATERIAL); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); /* diffuse */ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 498189321be..7e84ab062ca 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -333,7 +333,7 @@ static void view3d_project_short_clip_persmat(ARegion *ar, const float vec[3], s /* check for glsl drawing */ -int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt) +int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const short dt) { if (!GPU_glsl_support()) return 0; @@ -1189,14 +1189,17 @@ static void draw_transp_spot_volume(Lamp *la, float x, float z) glCullFace(GL_BACK); } -static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4]) { Object *ob = base->object; const float pixsize = ED_view3d_pixel_size(rv3d, ob->obmat[3]); Lamp *la = ob->data; float vec[3], lvec[3], vvec[3], circrad, x, y, z; float lampsize; - float imat[4][4], curcol[4]; + float imat[4][4]; + + unsigned char curcol[4]; unsigned char col[4]; /* cone can't be drawn for duplicated lamps, because duplilist would be freed to */ /* the moment of view3d_draw_transp() call */ @@ -1210,7 +1213,7 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, if (drawcone && !v3d->transp) { /* in this case we need to draw delayed */ - add_view3d_after(&v3d->afterdraw_transp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); return; } @@ -1228,17 +1231,23 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, /* lamp center */ copy_v3_v3(vec, ob->obmat[3]); - - /* for AA effects */ - glGetFloatv(GL_CURRENT_COLOR, curcol); - curcol[3] = 0.6; - glColor4fv(curcol); - + + if ((dflag & DRAW_CONSTCOLOR) == 0) { + /* for AA effects */ + curcol[0] = ob_wire_col[0]; + curcol[1] = ob_wire_col[1]; + curcol[2] = ob_wire_col[2]; + curcol[3] = 154; + glColor4ubv(curcol); + } + if (lampsize > 0.0f) { - if (ob->id.us > 1) { - if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155); - else glColor4ub(0x77, 0xCC, 0xCC, 155); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + if (ob->id.us > 1) { + if (ob == OBACT || (ob->flag & SELECT)) glColor4ub(0x88, 0xFF, 0xFF, 155); + else glColor4ub(0x77, 0xCC, 0xCC, 155); + } } /* Inner Circle */ @@ -1248,8 +1257,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, drawcircball(GL_POLYGON, vec, lampsize, imat); /* restore */ - if (ob->id.us > 1) - glColor4fv(curcol); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + if (ob->id.us > 1) + glColor4ubv(curcol); + } /* Outer circle */ circrad = 3.0f * lampsize; @@ -1481,9 +1492,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glDisable(GL_BLEND); - /* restore for drawing extra stuff */ - glColor3fv(curcol); - + if ((dflag & DRAW_CONSTCOLOR) == 0) { + /* restore for drawing extra stuff */ + glColor3ubv(ob_wire_col); + } } static void draw_limit_line(float sta, float end, unsigned int col) @@ -1516,7 +1528,7 @@ static void draw_focus_cross(float dist, float size) } #ifdef VIEW3D_CAMERA_BORDER_HACK -float view3d_camera_border_hack_col[4]; +unsigned char view3d_camera_border_hack_col[3]; short view3d_camera_border_hack_test = FALSE; #endif @@ -1546,8 +1558,8 @@ static void draw_bundle_sphere(void) } static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D *v3d, - MovieClip *clip, MovieTrackingObject *tracking_object, int flag, - int *global_track_index, int draw_selected) + MovieClip *clip, MovieTrackingObject *tracking_object, + const short dflag, int *global_track_index, int draw_selected) { MovieTracking *tracking = &clip->tracking; MovieTrackingTrack *track; @@ -1590,7 +1602,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D if ((track->flag & TRACK_HAS_BUNDLE) == 0) continue; - if (flag & DRAW_PICKING) + if (dflag & DRAW_PICKING) glLoadName(base->selcol + (tracknr << 16)); glPushMatrix(); @@ -1656,7 +1668,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D glPopMatrix(); - if ((flag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { + if ((dflag & DRAW_PICKING) == 0 && (v3d->flag2 & V3D_SHOW_BUNDLENAME)) { float pos[3]; unsigned char tcol[4]; @@ -1670,7 +1682,7 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D tracknr++; } - if ((flag & DRAW_PICKING) == 0) { + if ((dflag & DRAW_PICKING) == 0) { if ((v3d->flag2 & V3D_SHOW_CAMERAPATH) && (tracking_object->flag & TRACKING_OBJECT_CAMERA)) { MovieTrackingReconstruction *reconstruction; reconstruction = BKE_tracking_object_reconstruction(tracking, tracking_object); @@ -1701,11 +1713,11 @@ static void draw_viewport_object_reconstruction(Scene *scene, Base *base, View3D } static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, - int flag, int draw_selected) + const short dflag, const unsigned char ob_wire_col[4], + int draw_selected) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object; - float curcol[4]; int global_track_index = 1; if ((v3d->flag2 & V3D_SHOW_RECONSTRUCTION) == 0) @@ -1714,8 +1726,6 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, if (v3d->flag2 & V3D_RENDER_OVERRIDE) return; - glGetFloatv(GL_CURRENT_COLOR, curcol); - glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); @@ -1724,7 +1734,7 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, tracking_object = tracking->objects.first; while (tracking_object) { draw_viewport_object_reconstruction(scene, base, v3d, clip, tracking_object, - flag, &global_track_index, draw_selected); + dflag, &global_track_index, draw_selected); tracking_object = tracking_object->next; } @@ -1734,14 +1744,17 @@ static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); - glColor4fv(curcol); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + glColor3ubv(ob_wire_col); + } - if (flag & DRAW_PICKING) + if (dflag & DRAW_PICKING) glLoadName(base->selcol); } /* flag similar to draw_object() */ -static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag) +static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dflag, const unsigned char ob_wire_col[4]) { /* a standing up pyramid with (0,0,0) as top */ Camera *cam; @@ -1755,13 +1768,22 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base /* draw data for movie clip set as active for scene */ if (clip) { - draw_viewport_reconstruction(scene, base, v3d, clip, flag, FALSE); - draw_viewport_reconstruction(scene, base, v3d, clip, flag, TRUE); + draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, FALSE); + draw_viewport_reconstruction(scene, base, v3d, clip, dflag, ob_wire_col, TRUE); } #ifdef VIEW3D_CAMERA_BORDER_HACK if (is_view && !(G.f & G_PICKSEL)) { - glGetFloatv(GL_CURRENT_COLOR, view3d_camera_border_hack_col); + if ((dflag & DRAW_CONSTCOLOR) == 0) { + view3d_camera_border_hack_col[0] = ob_wire_col[0]; + view3d_camera_border_hack_col[1] = ob_wire_col[1]; + view3d_camera_border_hack_col[2] = ob_wire_col[2]; + } + else { + float col[4]; + glGetFloatv(GL_CURRENT_COLOR, col); + rgb_float_to_uchar(view3d_camera_border_hack_col, col); + } view3d_camera_border_hack_test = TRUE; return; } @@ -1829,7 +1851,7 @@ static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base glEnd(); } - if (flag == 0) { + if (dflag == 0) { if (cam->flag & (CAM_SHOWLIMITS + CAM_SHOWMIST)) { float nobmat[4][4]; World *wrld; @@ -2451,7 +2473,7 @@ static void draw_dm_verts__mapFunc(void *userData, int index, const float co[3], } static void draw_dm_verts(BMEditMesh *em, DerivedMesh *dm, int sel, BMVert *eve_act, - RegionView3D *rv3d) + RegionView3D *rv3d) { drawDMVerts_userData data; data.sel = sel; @@ -3140,7 +3162,7 @@ static DMDrawOption draw_em_fancy__setGLSLFaceOpts(void *userData, int index) } static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, - Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt) + Object *ob, BMEditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, const short dt) { Mesh *me = ob->data; @@ -3361,7 +3383,8 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) } } -static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag) { Object *ob = base->object; Mesh *me = ob->data; @@ -3447,10 +3470,12 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D else if (dt == OB_SOLID) { if (draw_flags & DRAW_MODIFIERS_PREVIEW) { /* for object selection draws no shade */ - if (flag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { + if (dflag & (DRAW_PICKING | DRAW_CONSTCOLOR)) { dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material); } else { + const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f}; + /* draw outline */ if ( (v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && @@ -3468,9 +3493,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D /* set default spec */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); - glEnable(GL_COLOR_MATERIAL); /* according manpages needed */ - glColor3ub(120, 120, 120); - glDisable(GL_COLOR_MATERIAL); + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); /* diffuse */ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_LIGHTING); @@ -3549,7 +3572,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D UI_ThemeColor(TH_GROUP_ACTIVE); else if (ob->flag & OB_FROMGROUP) UI_ThemeColorShade(TH_GROUP_ACTIVE, -16); - else if (flag != DRAW_CONSTCOLOR) + else if (dflag != DRAW_CONSTCOLOR) UI_ThemeColor(is_obact ? TH_ACTIVE : TH_SELECT); else glColor3ub(80, 80, 80); @@ -3558,7 +3581,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if (ob->flag & OB_FROMGROUP) UI_ThemeColor(TH_GROUP); else { - if (ob->dtx & OB_DRAWWIRE && flag == DRAW_CONSTCOLOR) + if (ob->dtx & OB_DRAWWIRE && dflag == DRAW_CONSTCOLOR) glColor3ub(80, 80, 80); else UI_ThemeColor(TH_WIRE); @@ -3615,7 +3638,8 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } /* returns 1 if nothing was drawn, for detecting to draw an object center */ -static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, int dt, int flag) +static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const short dflag) { Object *ob = base->object; Object *obedit = scene->obedit; @@ -3679,7 +3703,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D (check_alpha) ? &do_alpha_after : NULL); } - draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, flag); + draw_mesh_fancy(scene, ar, v3d, rv3d, base, dt, dflag); GPU_end_object_materials(); @@ -3687,20 +3711,20 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } } - if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { /* GPU_begin_object_materials checked if this is needed */ if (do_alpha_after) { if (ob->dtx & OB_DRAWXRAY) { - add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xraytransp, base, dflag); } else { - add_view3d_after(&v3d->afterdraw_transp, base, flag); + ED_view3d_after_add(&v3d->afterdraw_transp, base, dflag); } } else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { /* special case xray+transp when alpha is 1.0, without this the object vanishes */ if (v3d->xray == 0 && v3d->transp == 0) { - add_view3d_after(&v3d->afterdraw_xray, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); } } } @@ -3808,17 +3832,15 @@ static int drawDispListwire(ListBase *dlbase) return 0; } -static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) +static void drawDispListsolid(ListBase *lb, Object *ob, + const unsigned char ob_wire_col[4], int use_glsl) { DispList *dl; GPUVertexAttribs gattribs; - float *data, curcol[4]; + float *data; float *ndata; if (lb == NULL) return; - - /* for drawing wire */ - glGetFloatv(GL_CURRENT_COLOR, curcol); glEnable(GL_LIGHTING); glEnableClientState(GL_VERTEX_ARRAY); @@ -3841,7 +3863,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) int nr; glDisable(GL_LIGHTING); - glColor3fv(curcol); + glColor3ubv(ob_wire_col); // glVertexPointer(3, GL_FLOAT, 0, dl->verts); // glDrawArrays(GL_LINE_STRIP, 0, dl->nr); @@ -3875,7 +3897,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) case DL_SURF: if (dl->index) { - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); if (dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); @@ -3889,7 +3911,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) break; case DL_INDEX3: - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -3909,7 +3931,7 @@ static void drawDispListsolid(ListBase *lb, Object *ob, int glsl) break; case DL_INDEX4: - GPU_enable_material(dl->col + 1, (glsl) ? &gattribs : NULL); + GPU_enable_material(dl->col + 1, (use_glsl) ? &gattribs : NULL); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_FLOAT, 0, dl->verts); @@ -3935,7 +3957,7 @@ static void drawCurveDMWired(Object *ob) } /* return 1 when nothing was drawn */ -static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, const short dt) { Object *ob = base->object; DerivedMesh *dm = ob->derivedFinal; @@ -3967,7 +3989,8 @@ static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, B } /* returns 1 when nothing was drawn */ -static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const unsigned char ob_wire_col[4]) { Object *ob = base->object; ListBase *lb = NULL; @@ -4015,12 +4038,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas else { if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } if (cu->editnurb && cu->bevobj == NULL && cu->taperobj == NULL && cu->ext1 == 0.0f && cu->ext2 == 0.0f) { @@ -4052,12 +4075,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } } @@ -4076,12 +4099,12 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas if (draw_glsl_material(scene, ob, v3d, dt)) { GPU_begin_object_materials(v3d, rv3d, scene, ob, 1, NULL); - drawDispListsolid(lb, ob, 1); + drawDispListsolid(lb, ob, ob_wire_col, TRUE); GPU_end_object_materials(); } else { GPU_begin_object_materials(v3d, rv3d, scene, ob, 0, NULL); - drawDispListsolid(lb, ob, 0); + drawDispListsolid(lb, ob, ob_wire_col, FALSE); GPU_end_object_materials(); } } @@ -5593,7 +5616,8 @@ static void draw_editnurb(Object *ob, Nurb *nurb, int sel) } } -static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, int dt) +static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb, + const short dt, const unsigned char ob_wire_col[4]) { ToolSettings *ts = scene->toolsettings; Object *ob = base->object; @@ -5602,10 +5626,13 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, BevList *bl; short hide_handles = (cu->drawflag & CU_HIDE_HANDLES); int index; + unsigned char wire_col[3]; /* DispList */ - UI_ThemeColor(TH_WIRE); - drawDispList(scene, v3d, rv3d, base, dt); + UI_GetThemeColor3ubv(TH_WIRE, wire_col); + glColor3ubv(wire_col); + + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); if (v3d->zbuf) glDisable(GL_DEPTH_TEST); @@ -5917,7 +5944,8 @@ static void drawcone(const float vec[3], float radius, float height, float tmat[ glEnd(); } /* return 1 if nothing was drawn */ -static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt) +static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, + const short dt, const unsigned char ob_wire_col[4]) { Object *ob = base->object; MetaBall *mb; @@ -5928,13 +5956,19 @@ static int drawmball(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, mb = ob->data; if (mb->editelems) { - UI_ThemeColor(TH_WIRE); - if ((G.f & G_PICKSEL) == 0) drawDispList(scene, v3d, rv3d, base, dt); + if ((G.f & G_PICKSEL) == 0) { + unsigned char wire_col[3]; + UI_GetThemeColor3ubv(TH_WIRE, wire_col); + glColor3ubv(wire_col); + + drawDispList(scene, v3d, rv3d, base, dt, wire_col); + } ml = mb->editelems->first; } else { - if ((base->flag & OB_FROMDUPLI) == 0) - drawDispList(scene, v3d, rv3d, base, dt); + if ((base->flag & OB_FROMDUPLI) == 0) { + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); + } ml = mb->elems.first; } @@ -6306,7 +6340,8 @@ static void drawtexspace(Object *ob) } /* draws wire outline */ -static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) +static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const unsigned char ob_wire_col[4]) { RegionView3D *rv3d = ar->regiondata; Object *ob = base->object; @@ -6345,7 +6380,7 @@ static void drawObjectSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base) } else if (ob->type == OB_ARMATURE) { if (!(ob->mode & OB_MODE_POSE && base == scene->basact)) - draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, TRUE); + draw_armature(scene, v3d, ar, base, OB_WIRE, FALSE, ob_wire_col, TRUE); } glLineWidth(1.0); @@ -6437,19 +6472,13 @@ static void draw_hooks(Object *ob) } } -static void drawRBpivot(bRigidBodyJointConstraint *data) +static void drawRBpivot(bRigidBodyJointConstraint *data, const unsigned char ob_wire_col[4]) { const char *axis_str[3] = {"px", "py", "pz"}; int axis; float mat[4][4]; /* color */ - float curcol[4]; - unsigned char tcol[4]; - - glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_uchar(tcol, curcol); - tcol[3] = 255; eul_to_mat4(mat, &data->axX); glLineWidth(4.0f); @@ -6468,14 +6497,89 @@ static void drawRBpivot(bRigidBodyJointConstraint *data) glVertex3fv(v); glEnd(); - view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, tcol); + view3d_cached_text_draw_add(v, axis_str[axis], 0, V3D_CACHE_TEXT_ASCII, ob_wire_col); } glLineWidth(1.0f); setlinestyle(0); } +static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_wire_col[4], + const int warning_recursive) +{ + Object *ob = base->object; + int colindex = 0; + + /* confusing logic here, there are 2 methods of setting the color + * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. + * + * note: no theme yet for 'colindex' */ + int theme_id = TH_WIRE; + int theme_shade = 0; + + if ((scene->obedit == NULL) && + (G.moving & G_TRANSFORM_OBJ) && + (base->flag & (SELECT + BA_WAS_SEL))) + { + theme_id = TH_TRANSFORM; + } + else { + /* Sets the 'colindex' */ + if (ob->id.lib) { + colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3; + } + else if (warning_recursive == 1) { + if (base->flag & (SELECT + BA_WAS_SEL)) { + colindex = (scene->basact == base) ? 8 : 7; + } + else { + colindex = 6; + } + } + /* Sets the 'theme_id' or fallback to wire */ + else { + if (ob->flag & OB_FROMGROUP) { + if (base->flag & (SELECT + BA_WAS_SEL)) { + /* uses darker active color for non-active + selected*/ + theme_id = TH_GROUP_ACTIVE; + + if (scene->basact != base) { + theme_shade = -16; + } + } + else { + theme_id = TH_GROUP; + } + } + else { + if (base->flag & (SELECT + BA_WAS_SEL)) { + theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT; + } + else { + if (ob->type == OB_LAMP) theme_id = TH_LAMP; + else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; + else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; + else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; + /* fallback to TH_WIRE */ + } + } + } + } + + /* finally set the color */ + if (colindex == 0) { + if (theme_shade == 0) UI_GetThemeColor3ubv(theme_id, r_ob_wire_col); + else UI_GetThemeColorShade3ubv(theme_id, theme_shade, r_ob_wire_col); + } + else { + cpack_cpy_3ub(r_ob_wire_col, colortab[colindex]); + } + + /* no reason to use this but some functions take col[4] */ + r_ob_wire_col[3] = 255; +} + /* flag can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET */ -void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) +void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short dflag) { static int warning_recursive = 0; ModifierData *md = NULL; @@ -6484,7 +6588,8 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) RegionView3D *rv3d = ar->regiondata; float vec1[3], vec2[3]; unsigned int col = 0; - int /*sel, drawtype,*/ colindex = 0; + unsigned char _ob_wire_col[4]; /* dont initialize this */ + unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */ int i, selstart, selend, empty_object = 0; short dt, dtx, zbufoff = 0; const short is_obact = (ob == OBACT); @@ -6508,12 +6613,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) return; /* xray delay? */ - if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + if ((dflag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { /* don't do xray in particle mode, need the z-buffer */ if (!(ob->mode & OB_MODE_PARTICLE_EDIT)) { /* xray and transp are set when it is drawing the 2nd/3rd pass */ if (!v3d->xray && !v3d->transp && (ob->dtx & OB_DRAWXRAY) && !(ob->dtx & OB_DRAWTRANSP)) { - add_view3d_after(&v3d->afterdraw_xray, base, flag); + ED_view3d_after_add(&v3d->afterdraw_xray, base, dflag); return; } } @@ -6522,9 +6627,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* no return after this point, otherwise leaks */ view3d_cached_text_draw_begin(); - /* patch? children objects with a timeoffs change the parents. How to solve! */ - /* if ( ((int)ob->ctime) != F_(scene->r.cfra)) BKE_object_where_is_calc(scene, ob); */ - /* draw motion paths (in view space) */ if (ob->mpath && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { bAnimVizSettings *avs = &ob->avs; @@ -6544,74 +6646,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) ED_view3d_init_mats_rv3d_gl(ob, rv3d); /* which wire color */ - if ((flag & DRAW_CONSTCOLOR) == 0) { - /* confusing logic here, there are 2 methods of setting the color - * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id. - * - * note: no theme yet for 'colindex' */ - int theme_id = TH_WIRE; - int theme_shade = 0; + if ((dflag & DRAW_CONSTCOLOR) == 0) { project_short(ar, ob->obmat[3], &base->sx); - if ((scene->obedit == NULL) && - (G.moving & G_TRANSFORM_OBJ) && - (base->flag & (SELECT + BA_WAS_SEL))) - { - theme_id = TH_TRANSFORM; - } - else { - /* Sets the 'colindex' */ - if (ob->id.lib) { - colindex = (base->flag & (SELECT + BA_WAS_SEL)) ? 4 : 3; - } - else if (warning_recursive == 1) { - if (base->flag & (SELECT + BA_WAS_SEL)) { - colindex = (scene->basact == base) ? 8 : 7; - } - else { - colindex = 6; - } - } - /* Sets the 'theme_id' or fallback to wire */ - else { - if (ob->flag & OB_FROMGROUP) { - if (base->flag & (SELECT + BA_WAS_SEL)) { - /* uses darker active color for non-active + selected*/ - theme_id = TH_GROUP_ACTIVE; - - if (scene->basact != base) { - theme_shade = -16; - } - } - else { - theme_id = TH_GROUP; - } - } - else { - if (base->flag & (SELECT + BA_WAS_SEL)) { - theme_id = scene->basact == base ? TH_ACTIVE : TH_SELECT; - } - else { - if (ob->type == OB_LAMP) theme_id = TH_LAMP; - else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER; - else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA; - else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY; - /* fallback to TH_WIRE */ - } - } - } - } + draw_object_wire_color(scene, base, _ob_wire_col, warning_recursive); + ob_wire_col = _ob_wire_col; - /* finally set the color */ - if (colindex == 0) { - if (theme_shade == 0) UI_ThemeColor(theme_id); - else UI_ThemeColorShade(theme_id, theme_shade); - } - else { - col = colortab[colindex]; - cpack(col); - } + glColor3ubv(ob_wire_col); } /* maximum drawtype */ @@ -6669,18 +6711,18 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw outline for selected objects, mesh does itself */ if ((v3d->flag & V3D_SELECT_OUTLINE) && ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) && ob->type != OB_MESH) { - if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (flag & DRAW_SCENESET) == 0) { - if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(flag & DRAW_PICKING)) { + if (dt > OB_WIRE && (ob->mode & OB_MODE_EDIT) == 0 && (dflag & DRAW_SCENESET) == 0) { + if (!(ob->dtx & OB_DRAWWIRE) && (ob->flag & SELECT) && !(dflag & DRAW_PICKING)) { - drawObjectSelect(scene, v3d, ar, base); + drawObjectSelect(scene, v3d, ar, base, ob_wire_col); } } } switch (ob->type) { case OB_MESH: - empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, flag); - if (flag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself + empty_object = draw_mesh_object(scene, ar, v3d, rv3d, base, dt, dflag); + if (dflag != DRAW_CONSTCOLOR) dtx &= ~OB_DRAWWIRE; // mesh draws wire itself break; case OB_FONT: @@ -6691,11 +6733,11 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (cu->flag & CU_FAST) { cpack(0xFFFFFF); set_inverted_drawing(1); - drawDispList(scene, v3d, rv3d, base, OB_WIRE); + drawDispList(scene, v3d, rv3d, base, OB_WIRE, ob_wire_col); set_inverted_drawing(0); } else { - drawDispList(scene, v3d, rv3d, base, dt); + drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); } if (cu->linewidth != 0.0f) { @@ -6770,7 +6812,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt); + empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); } break; @@ -6780,7 +6822,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (cu->editnurb) { ListBase *nurbs = BKE_curve_editNurbs_get(cu); - drawnurb(scene, v3d, rv3d, base, nurbs->first, dt); + drawnurb(scene, v3d, rv3d, base, nurbs->first, dt, ob_wire_col); } else if (dt == OB_BOUNDBOX) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) { @@ -6788,7 +6830,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } else if (ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { - empty_object = drawDispList(scene, v3d, rv3d, base, dt); + empty_object = drawDispList(scene, v3d, rv3d, base, dt, ob_wire_col); //XXX old animsys if (cu->path) // curve_draw_speed(scene, ob); @@ -6799,14 +6841,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) MetaBall *mb = ob->data; if (mb->editelems) - drawmball(scene, v3d, rv3d, base, dt); + drawmball(scene, v3d, rv3d, base, dt, ob_wire_col); else if (dt == OB_BOUNDBOX) { if (((v3d->flag2 & V3D_RENDER_OVERRIDE) && (v3d->drawtype >= OB_WIRE)) == 0) { draw_bounding_volume(scene, ob, ob->boundtype); } } else - empty_object = drawmball(scene, v3d, rv3d, base, dt); + empty_object = drawmball(scene, v3d, rv3d, base, dt, ob_wire_col); break; } case OB_EMPTY: @@ -6821,7 +6863,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; case OB_LAMP: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - drawlamp(scene, v3d, rv3d, base, dt, flag); + drawlamp(scene, v3d, rv3d, base, dt, dflag, ob_wire_col); if (dtx || (base->flag & SELECT)) glMultMatrixf(ob->obmat); } break; @@ -6829,12 +6871,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0 || (rv3d->persp == RV3D_CAMOB && v3d->camera == ob)) /* special exception for active camera */ { - drawcamera(scene, v3d, rv3d, base, flag); + drawcamera(scene, v3d, rv3d, base, dflag, ob_wire_col); break; } case OB_SPEAKER: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) - drawspeaker(scene, v3d, rv3d, ob, flag); + drawspeaker(scene, v3d, rv3d, ob, dflag); break; case OB_LATTICE: if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -6852,7 +6894,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) else { if (dt > OB_WIRE) GPU_enable_material(0, NULL); /* we use default material */ - empty_object = draw_armature(scene, v3d, ar, base, dt, flag, FALSE); + empty_object = draw_armature(scene, v3d, ar, base, dt, dflag, ob_wire_col, FALSE); if (dt > OB_WIRE) GPU_disable_material(); } @@ -6866,7 +6908,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { - if (ob->soft /*&& flag & OB_SBMOTION*/) { + if (ob->soft /*&& dflag & OB_SBMOTION*/) { float mrt[3][3], msc[3][3], mtr[3][3]; SoftBody *sb = NULL; float tipw = 0.5f, tiph = 0.5f, drawsize = 4.0f; @@ -6891,7 +6933,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* code for new particle system */ if ((warning_recursive == 0) && (ob->particlesystem.first) && - (flag & DRAW_PICKING) == 0 && + (dflag & DRAW_PICKING) == 0 && (ob != scene->obedit) ) { @@ -6925,7 +6967,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* draw edit particles last so that they can draw over child particles */ if ( (warning_recursive == 0) && - (flag & DRAW_PICKING) == 0 && + (dflag & DRAW_PICKING) == 0 && (!scene->obedit)) { @@ -7056,7 +7098,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (con->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) { bRigidBodyJointConstraint *data = (bRigidBodyJointConstraint *)con->data; if (data->flag & CONSTRAINT_DRAW_PIVOT) - drawRBpivot(data); + drawRBpivot(data, ob_wire_col); } } @@ -7083,14 +7125,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if (dtx & OB_DRAWNAME) { /* patch for several 3d cards (IBM mostly) that crash on GL_SELECT with text drawing */ /* but, we also don't draw names for sets or duplicators */ - if (flag == 0) { - float zero[3] = {0, 0, 0}; - float curcol[4]; - unsigned char tcol[4]; - glGetFloatv(GL_CURRENT_COLOR, curcol); - rgb_float_to_uchar(tcol, curcol); - tcol[3] = 255; - view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, tcol); + if (dflag == 0) { + const float zero[3] = {0, 0, 0}; + view3d_cached_text_draw_add(zero, ob->id.name + 2, 10, 0, ob_wire_col); } } /*if (dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);*/ @@ -7146,13 +7183,13 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) do_draw_center = DESELECT; if (do_draw_center != -1) { - if (flag & DRAW_PICKING) { + if (dflag & DRAW_PICKING) { /* draw a single point for opengl selection */ glBegin(GL_POINTS); glVertex3fv(ob->obmat[3]); glEnd(); } - else if ((flag & DRAW_CONSTCOLOR) == 0) { + else if ((dflag & DRAW_CONSTCOLOR) == 0) { /* we don't draw centers for duplicators and sets */ if (U.obcenter_dia > 0) { /* check > 0 otherwise grease pencil can draw into the circle select which is annoying. */ @@ -7163,7 +7200,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* not for sets, duplicators or picking */ - if (flag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { ListBase *list; /* draw hook center and offset line */ @@ -7505,7 +7542,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* helper function for drawing object instances - meshes */ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, - Object *ob, int dt, int outline) + Object *ob, const short dt, int outline) { Mesh *me = ob->data; DerivedMesh *dm = NULL, *edm = NULL; @@ -7553,7 +7590,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r if (dm) dm->release(dm); } -void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int dt, int outline) +void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline) { if (ob == NULL) return; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 28fd2c8bc74..a6948222d93 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1016,7 +1016,7 @@ static void space_view3d_listener(struct ScrArea *sa, struct wmNotifier *wmn) break; } - // removed since BKE_image_user_frame_calc is now called in draw_bgpic because screen_ops doesnt call the notifier. + // removed since BKE_image_user_frame_calc is now called in view3d_draw_bgpic because screen_ops doesnt call the notifier. #if 0 if (wmn->category == NC_SCENE && wmn->data == ND_FRAME) { View3D *v3d = area->spacedata.first; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 14afcaa855f..6d9507ebff1 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -508,8 +508,7 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) } /* set variable axis */ - vert[0][1] = vert[1][1] = - vert[2][0] = vert[3][0] = line; + vert[0][1] = vert[1][1] = vert[2][0] = vert[3][0] = line; glDrawArrays(GL_LINES, 0, 4); } @@ -1128,7 +1127,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) #ifdef VIEW3D_CAMERA_BORDER_HACK if (view3d_camera_border_hack_test == TRUE) { - glColor4fv(view3d_camera_border_hack_col); + glColor3ubv(view3d_camera_border_hack_col); glRectf(x1i + 1, y1i + 1, x2i - 1, y2i - 1); view3d_camera_border_hack_test = FALSE; } @@ -1147,7 +1146,6 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* border */ if (scene->r.mode & R_BORDER) { - cpack(0); x3 = x1 + scene->r.border.xmin * (x2 - x1); y3 = y1 + scene->r.border.ymin * (y2 - y1); @@ -1528,7 +1526,8 @@ exit: /* ************************************************************* */ -static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) +static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, + const short do_forground, const short do_camera_frame) { RegionView3D *rv3d = ar->regiondata; BGpic *bgpic; @@ -1537,7 +1536,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) ImBuf *ibuf = NULL, *freeibuf; float vec[4], fac, asp, zoomx, zoomy; float x1, y1, x2, y2, cx, cy; - int fg_flag = foreground ? V3D_BGPIC_FOREGROUND : 0; + int fg_flag = do_forground ? V3D_BGPIC_FOREGROUND : 0; for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) { @@ -1560,7 +1559,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) BKE_image_user_frame_calc(&bgpic->iuser, CFRA, 0); ibuf = BKE_image_get_ibuf(ima, &bgpic->iuser); } - else { + else if (bgpic->source == V3D_BGPIC_MOVIE) { clip = NULL; if (bgpic->flag & V3D_BGPIC_CAMERACLIP) { @@ -1595,14 +1594,21 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) IMB_rect_from_float(ibuf); if (rv3d->persp == RV3D_CAMOB) { - rctf vb; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - - x1 = vb.xmin; - y1 = vb.ymin; - x2 = vb.xmax; - y2 = vb.ymax; + if (do_camera_frame) { + rctf vb; + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + x1 = vb.xmin; + y1 = vb.ymin; + x2 = vb.xmax; + y2 = vb.ymax; + } + else { + x1 = ar->winrct.xmin; + y1 = ar->winrct.ymin; + x2 = ar->winrct.xmax; + y2 = ar->winrct.ymax; + } } else { float sco[2]; @@ -1696,7 +1702,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, int foreground) } } -static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) +static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d, + const short do_forground, const short do_camera_frame) { RegionView3D *rv3d = ar->regiondata; @@ -1708,11 +1715,11 @@ static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { if (rv3d->persp == RV3D_CAMOB) { - draw_bgpic(scene, ar, v3d, foreground); + view3d_draw_bgpic(scene, ar, v3d, do_forground, do_camera_frame); } } else { - draw_bgpic(scene, ar, v3d, foreground); + view3d_draw_bgpic(scene, ar, v3d, do_forground, do_camera_frame); } } @@ -1721,17 +1728,17 @@ static void draw_bgpics(Scene *scene, ARegion *ar, View3D *v3d, int foreground) typedef struct View3DAfter { struct View3DAfter *next, *prev; struct Base *base; - int flag; + short dflag; } View3DAfter; /* temp storage of Objects that need to be drawn as last */ -void add_view3d_after(ListBase *lb, Base *base, int flag) +void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag) { View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after"); BLI_assert((base->flag & OB_FROMDUPLI) == 0); BLI_addtail(lb, v3da); v3da->base = base; - v3da->flag = flag; + v3da->dflag = dflag; } /* disables write in zbuffer and draws it over */ @@ -1744,7 +1751,7 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) for (v3da = v3d->afterdraw_transp.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_transp, v3da); MEM_freeN(v3da); } @@ -1765,7 +1772,7 @@ static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) v3d->xray = TRUE; for (v3da = v3d->afterdraw_xray.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_xray, v3da); MEM_freeN(v3da); } @@ -1786,7 +1793,7 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int c for (v3da = v3d->afterdraw_xraytransp.first; v3da; v3da = next) { next = v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->dflag); BLI_remlink(&v3d->afterdraw_xraytransp, v3da); MEM_freeN(v3da); } @@ -2428,14 +2435,13 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4], - int draw_background) + int do_bgpic) { RegionView3D *rv3d = ar->regiondata; Base *base; float backcol[3]; int bwinx, bwiny; rcti brect; - ImBuf *bg_ibuf = NULL; glPushMatrix(); @@ -2465,66 +2471,21 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, if (draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) gpu_update_lamps_shadows(scene, v3d); - /* if scene has got active clip, use it for render backdrop */ - if (draw_background && scene->clip && rv3d->persp == RV3D_CAMOB && v3d->camera) { - MovieClipUser user = {0}; - - BKE_movieclip_user_set_frame(&user, CFRA); - bg_ibuf = BKE_movieclip_get_ibuf(scene->clip, &user); + /* set background color, fallback on the view background color + * (if active clip is set but frame is failed to load fallback to horizon color as background) */ + if (scene->world) { + if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) + linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); + else + copy_v3_v3(backcol, &scene->world->horr); + glClearColor(backcol[0], backcol[1], backcol[2], 0.0); } - - if (!bg_ibuf) { - /* set background color, fallback on the view background color - * (if active clip is set but frame is failed to load fallback to horizon color as background) */ - if (scene->world) { - if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) - linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); - else - copy_v3_v3(backcol, &scene->world->horr); - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else { - UI_ThemeClearColor(TH_BACK); - } + else { + UI_ThemeClearColor(TH_BACK); } - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if (bg_ibuf) { - unsigned char *pixels, *cp, *dst_cp; - int i; - - if (bg_ibuf->rect_float && !bg_ibuf->rect) - IMB_rect_from_float(bg_ibuf); - - dst_cp = pixels = MEM_callocN(4 * sizeof(unsigned char) * bg_ibuf->x * bg_ibuf->y, "draw offscreen clip pixels"); - cp = (unsigned char *)bg_ibuf->rect; - for (i = 0; i < bg_ibuf->x * bg_ibuf->y; i++, cp += 4, dst_cp += 4) { - dst_cp[0] = cp[0]; - dst_cp[1] = cp[1]; - dst_cp[2] = cp[2]; - dst_cp[3] = 255; - } - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - ED_region_pixelspace(ar); - - glPixelZoom((float)winx / bg_ibuf->x, (float)winy / bg_ibuf->y); - glaDrawPixelsTex(0, 0, bg_ibuf->x, bg_ibuf->y, GL_UNSIGNED_BYTE, pixels); - - glPixelZoom(1.0, 1.0); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - IMB_freeImBuf(bg_ibuf); - MEM_freeN(pixels); - } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, viewmat, winmat); @@ -2540,6 +2501,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, else v3d->zbuf = FALSE; + /* important to do before clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, FALSE, FALSE); + } + if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_set(rv3d); @@ -2581,6 +2547,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); + /* important to do after clipping */ + if (do_bgpic) { + view3d_draw_bgpic_test(scene, ar, v3d, TRUE, FALSE); + } + /* cleanup */ if (v3d->zbuf) { v3d->zbuf = FALSE; @@ -2763,12 +2734,15 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); } -static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) +static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); + +static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw_border) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); RenderEngineType *type; + GLint scissor[4]; /* create render engine */ if (!rv3d->render_engine) { @@ -2785,22 +2759,53 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); /* background draw */ + ED_region_pixelspace(ar); + + if (draw_border) { + /* for border draw, we only need to clear a subset of the 3d view */ + rctf viewborder; + rcti cliprct; + + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * (viewborder.xmax - viewborder.xmin); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * (viewborder.ymax - viewborder.ymin); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * (viewborder.xmax - viewborder.xmin); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * (viewborder.ymax - viewborder.ymin); + + cliprct.xmin += ar->winrct.xmin; + cliprct.xmax += ar->winrct.xmin; + cliprct.ymin += ar->winrct.ymin; + cliprct.ymax += ar->winrct.ymin; + + cliprct.xmin = MAX2(cliprct.xmin, ar->winrct.xmin); + cliprct.ymin = MAX2(cliprct.ymin, ar->winrct.ymin); + cliprct.xmax = MIN2(cliprct.xmax, ar->winrct.xmax); + cliprct.ymax = MIN2(cliprct.ymax, ar->winrct.ymax); + + glGetIntegerv(GL_SCISSOR_BOX, scissor); + glScissor(cliprct.xmin, cliprct.ymin, cliprct.xmax - cliprct.xmin, cliprct.ymax - cliprct.ymin); + } + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - ED_region_pixelspace(ar); - - /* render result draw */ if (v3d->flag & V3D_DISPBGPICS) - draw_bgpic(scene, ar, v3d, FALSE); + view3d_draw_bgpic(scene, ar, v3d, FALSE, TRUE); else fdrawcheckerboard(0, 0, ar->winx, ar->winy); + if (draw_border) { + /* restore scissor as it was before */ + glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); + } + + /* render result draw */ type = rv3d->render_engine->type; type->view_draw(rv3d->render_engine, C); if (v3d->flag & V3D_DISPBGPICS) - draw_bgpic(scene, ar, v3d, TRUE); + view3d_draw_bgpic(scene, ar, v3d, TRUE, TRUE); return 1; } @@ -2896,7 +2901,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - draw_bgpics(scene, ar, v3d, FALSE); + view3d_draw_bgpic_test(scene, ar, v3d, FALSE, TRUE); if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_set(rv3d); @@ -2955,8 +2960,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - draw_bgpics(scene, ar, v3d, TRUE); - // REEB_draw(); if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { @@ -2976,6 +2979,9 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_disable(); + /* important to do after clipping */ + view3d_draw_bgpic_test(scene, ar, v3d, TRUE, TRUE); + BIF_draw_manipulator(C); #if 0 @@ -3055,15 +3061,21 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha void view3d_main_area_draw(const bContext *C, ARegion *ar) { + Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; + int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); - /* draw viewport using external renderer? */ - if (!(v3d->drawtype == OB_RENDER && view3d_main_area_draw_engine(C, ar))) { - /* draw viewport using opengl */ + /* draw viewport using opengl */ + if (v3d->drawtype != OB_RENDER || draw_border) { view3d_main_area_draw_objects(C, ar, &grid_unit); ED_region_pixelspace(ar); } + + /* draw viewport using external renderer */ + if (v3d->drawtype == OB_RENDER) + view3d_main_area_draw_engine(C, ar, draw_border); view3d_main_area_draw_info(C, ar, grid_unit); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 8ba0d75c786..d632314f3ca 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -498,7 +498,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) static void viewops_data_free(bContext *C, wmOperator *op) { ARegion *ar; - Paint *p = paint_get_active(CTX_data_scene(C)); + Paint *p = paint_get_active_from_context(C); if (op->customdata) { ViewOpsData *vod = op->customdata; diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 29edc0158d6..3c6a0dd4b9f 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -53,13 +53,17 @@ struct wmWindowManager; #define BL_NEAR_CLIP 0.001 /* drawing flags: */ -#define DRAW_PICKING 1 -#define DRAW_CONSTCOLOR 2 -#define DRAW_SCENESET 4 +enum { + DRAW_PICKING = (1 << 0), + DRAW_CONSTCOLOR = (1 << 1), + DRAW_SCENESET = (1 << 2) +}; /* draw_mesh_fancy/draw_mesh_textured draw_flags */ -#define DRAW_MODIFIERS_PREVIEW 1 -#define DRAW_FACE_SELECT 2 +enum { + DRAW_MODIFIERS_PREVIEW = (1 << 0), + DRAW_FACE_SELECT = (1 << 1) +}; /* view3d_header.c */ void VIEW3D_OT_layers(struct wmOperatorType *ot); @@ -112,23 +116,28 @@ void draw_motion_paths_cleanup(View3D *v3d); /* drawobject.c */ -void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, int flag); -int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, int dt); -void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, int dt, int outline); +void draw_object(Scene *scene, struct ARegion *ar, View3D *v3d, Base *base, const short dflag); +int draw_glsl_material(Scene *scene, struct Object *ob, View3D *v3d, const short dt); +void draw_object_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const short dt, int outline); void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob); void drawaxes(float size, char drawtype); void view3d_cached_text_draw_begin(void); void view3d_cached_text_draw_add(const float co[3], const char *str, short xoffs, short flag, const unsigned char col[4]); void view3d_cached_text_draw_end(View3D * v3d, ARegion * ar, int depth_write, float mat[][4]); -#define V3D_CACHE_TEXT_ZBUF (1 << 0) -#define V3D_CACHE_TEXT_WORLDSPACE (1 << 1) -#define V3D_CACHE_TEXT_ASCII (1 << 2) -#define V3D_CACHE_TEXT_GLOBALSPACE (1 << 3) -#define V3D_CACHE_TEXT_LOCALCLIP (1 << 4) + +enum { + V3D_CACHE_TEXT_ZBUF = (1 << 0), + V3D_CACHE_TEXT_WORLDSPACE = (1 << 1), + V3D_CACHE_TEXT_ASCII = (1 << 2), + V3D_CACHE_TEXT_GLOBALSPACE = (1 << 3), + V3D_CACHE_TEXT_LOCALCLIP = (1 << 4) +}; /* drawarmature.c */ -int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline); +int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, + const short dt, const short dflag, const unsigned char ob_wire_col[4], + const short is_outline); /* drawmesh.c */ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, @@ -140,7 +149,7 @@ void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, void view3d_main_area_draw(const struct bContext *C, struct ARegion *ar); void draw_depth(Scene *scene, struct ARegion *ar, View3D *v3d, int (*func)(void *)); void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); -void add_view3d_after(ListBase *lb, Base *base, int flag); +void ED_view3d_after_add(ListBase *lb, Base *base, const short dflag); void circf(float x, float y, float rad); void circ(float x, float y, float rad); @@ -211,7 +220,7 @@ void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float * any direction it starts to fail */ #define VIEW3D_CAMERA_BORDER_HACK #ifdef VIEW3D_CAMERA_BORDER_HACK -extern float view3d_camera_border_hack_col[4]; +extern unsigned char view3d_camera_border_hack_col[3]; extern short view3d_camera_border_hack_test; #endif diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 602f790c8df..d2f2fdcaa81 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -1870,7 +1870,6 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i for (base = vc->scene->base.first; base && hits; base = base->next) { if (BASE_SELECTABLE(vc->v3d, base)) { while (base->selcol == (*col & 0xFFFF)) { /* we got an object */ - if (*col & 0xFFFF0000) { /* we got a bone */ bone = get_indexed_bone(base->object, *col & ~(BONESEL_ANY)); if (bone) { @@ -1878,16 +1877,13 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i if ((bone->flag & BONE_UNSELECTABLE) == 0) { bone->flag |= BONE_SELECTED; bone_selected = 1; -// XXX select_actionchannel_by_name(base->object->action, bone->name, 1); } } else { bArmature *arm = base->object->data; bone->flag &= ~BONE_SELECTED; -// XXX select_actionchannel_by_name(base->object->action, bone->name, 0); if (arm->act_bone == bone) arm->act_bone = NULL; - } } } @@ -1897,7 +1893,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i else ED_base_object_select(base, BA_DESELECT); } - + col += 4; /* next color */ hits--; if (hits == 0) break; @@ -1906,13 +1902,16 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i if (bone_selected) { Object *ob = base->object; - bArmature *arm = ob->data; - - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); - if (arm->flag & ARM_HAS_VIZ_DEPS) { - /* mask modifier ('armature' mode), etc. */ - DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + if (ob && (ob->type == OB_ARMATURE)) { + bArmature *arm = ob->data; + + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + + if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { + /* mask modifier ('armature' mode), etc. */ + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } } } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2a4b2f06b90..8bafce70ec4 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -49,6 +49,7 @@ #include "DNA_constraint_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_mask_types.h" #include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ @@ -162,13 +163,35 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy) else if (t->spacetype==SPACE_CLIP) { View2D *v2d = t->view; float divx, divy; + float mulx, muly; + float aspx = 1.0f, aspy = 1.0f; divx = v2d->mask.xmax-v2d->mask.xmin; divy = v2d->mask.ymax-v2d->mask.ymin; - r_vec[0] = (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - r_vec[1] = (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; + mulx = (v2d->cur.xmax-v2d->cur.xmin); + muly = (v2d->cur.ymax-v2d->cur.ymin); + + if (t->options & CTX_MASK) { + /* clamp w/h, mask only */ + divx = divy = maxf(divx, divy); + mulx = muly = minf(mulx, muly); + } + + r_vec[0] = mulx * (dx) / divx; + r_vec[1] = muly * (dy) / divy; r_vec[2] = 0.0f; + + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); + } + else if (t->options & CTX_MASK) { + /* TODO - NOT WORKING, this isnt so bad since its only display aspect */ + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + } + + r_vec[0] *= aspx; + r_vec[1] *= aspy; } else { printf("%s: called in an invalid context\n", __func__); @@ -226,9 +249,18 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) } else if (t->spacetype==SPACE_CLIP) { float v[2]; + float aspx = 1.0f, aspy = 1.0f; copy_v2_v2(v, vec); + if (t->options & CTX_MOVIECLIP) + ED_space_clip_aspect_dimension_aware(t->sa->spacedata.first, &aspx, &aspy); + else if (t->options & CTX_MASK) + ED_space_clip_mask_aspect(t->sa->spacedata.first, &aspx, &aspy); + + v[0] /= aspx; + v[1] /= aspy; + UI_view2d_to_region_no_clip(t->view, v[0], v[1], adr, adr+1); } } @@ -279,16 +311,23 @@ void applyAspectRatio(TransInfo *t, float vec[2]) vec[1] /= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; float aspx, aspy; - int width, height; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); - vec[0] *= width / aspx; - vec[1] *= height / aspy; + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + + vec[0] /= aspx; + vec[1] /= aspy; + } + else if (t->options & CTX_MASK) { + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + vec[0] /= aspx; + vec[1] /= aspy; + } } } } @@ -312,16 +351,19 @@ void removeAspectRatio(TransInfo *t, float vec[2]) vec[1] *= aspy; } else if ((t->spacetype==SPACE_CLIP) && (t->mode==TFM_TRANSLATION)) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { SpaceClip *sc = t->sa->spacedata.first; - float aspx, aspy; - int width, height; + float aspx = 1.0f, aspy = 1.0f; - ED_space_clip_size(sc, &width, &height); - ED_space_clip_aspect(sc, &aspx, &aspy); + if (t->options & CTX_MOVIECLIP) { + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + } + else if (t->options & CTX_MASK) { + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + } - vec[0] *= aspx / width; - vec[1] *= aspy / height; + vec[0] *= aspx; + vec[1] *= aspy; } } } @@ -367,12 +409,20 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) } else if (t->spacetype==SPACE_CLIP) { SpaceClip *sc = (SpaceClip*)t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - /* objects could be parented to tracking data, so send this for viewport refresh */ - WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); + + /* objects could be parented to tracking data, so send this for viewport refresh */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); - WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + WM_event_add_notifier(C, NC_MASK|NA_EDITED, mask); + } } } @@ -663,7 +713,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm } else { short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ? - t->current_orientation : V3D_MANIP_LOCAL); + t->current_orientation : V3D_MANIP_LOCAL); if (!(t->modifiers & MOD_CONSTRAINT_PLANE)) setUserConstraint(t, orientation, constraint_axis, msg2); else if (t->modifiers & MOD_CONSTRAINT_PLANE) @@ -725,7 +775,7 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= TREDRAW_HARD; } else if (t->mode == TFM_TRANSLATION) { - if (t->options & CTX_MOVIECLIP) { + if (t->options & (CTX_MOVIECLIP | CTX_MASK)) { restoreTransObjects(t); t->flag ^= T_ALT_TRANSFORM; @@ -735,7 +785,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case TFM_MODAL_ROTATE: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE) && !(t->options & (CTX_MOVIECLIP | CTX_MASK))) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -762,6 +812,14 @@ int transformEvent(TransInfo *t, wmEvent *event) initSnapping(t, NULL); // need to reinit after mode change t->redraw |= TREDRAW_HARD; } + else if (t->mode == TFM_RESIZE) { + if (t->options & CTX_MOVIECLIP) { + restoreTransObjects(t); + + t->flag ^= T_ALT_TRANSFORM; + t->redraw |= TREDRAW_HARD; + } + } break; case TFM_MODAL_SNAP_INV_ON: @@ -994,7 +1052,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case RKEY: /* only switch when... */ - if (!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { + if (!(t->options & CTX_TEXTURE)) { if ( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -1125,10 +1183,10 @@ int transformEvent(TransInfo *t, wmEvent *event) return OPERATOR_PASS_THROUGH; } -int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *cent2d) +int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int cent2d[2]) { TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data"); - int success = 1; + int success; t->state = TRANS_RUNNING; @@ -1143,10 +1201,10 @@ int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *ce t->around = centerMode; // override userdefined mode if (t->total == 0) { - success = 0; + success = FALSE; } else { - success = 1; + success = TRUE; calculateCenter(t); @@ -1456,6 +1514,8 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) { if (t->obedit) ts->proportional = proportional; + else if (t->options & CTX_MASK) + ts->proportional_mask = (proportional != PROP_EDIT_OFF); else ts->proportional_objects = (proportional != PROP_EDIT_OFF); } @@ -1665,6 +1725,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int case TFM_CURVE_SHRINKFATTEN: initCurveShrinkFatten(t); break; + case TFM_MASK_SHRINKFATTEN: + initMaskShrinkFatten(t); + break; case TFM_TRACKBALL: initTrackball(t); break; @@ -2675,6 +2738,9 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3]) { copy_v3_v3(center, td->center); } + else if (t->options & CTX_MOVIECLIP) { + copy_v3_v3(center, td->center); + } else { copy_v3_v3(center, t->center); } @@ -3048,6 +3114,10 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short { center = td->center; } + + if (t->options & CTX_MOVIECLIP) { + center = td->center; + } } if (t->flag & T_POINTS) { @@ -3860,8 +3930,77 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) continue; if (td->val) { - // *td->val= ratio; *td->val= td->ival*ratio; + /* apply PET */ + *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival); + if (*td->val <= 0.0f) *td->val = 0.001f; + } + } + + recalcData(t); + + ED_area_headerprint(t->sa, str); + + return 1; +} + + +void initMaskShrinkFatten(TransInfo *t) +{ + t->mode = TFM_MASK_SHRINKFATTEN; + t->transform = MaskShrinkFatten; + + initMouseInputMode(t, &t->mouse, INPUT_SPRING); + + t->idx_max = 0; + t->num.idx_max = 0; + t->snap[0] = 0.0f; + t->snap[1] = 0.1f; + t->snap[2] = t->snap[1] * 0.1f; + + t->num.increment = t->snap[1]; + + t->flag |= T_NO_ZERO; + t->num.flag |= NUM_NO_ZERO; + + t->flag |= T_NO_CONSTRAINT; +} + +int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) +{ + TransData *td = t->data; + float ratio; + int i; + char str[50]; + + ratio = t->values[0]; + + snapGrid(t, &ratio); + + applyNumInput(&t->num, &ratio); + + /* header print for NumInput */ + if (hasNumInput(&t->num)) { + char c[20]; + + outputNumInput(&(t->num), c); + sprintf(str, "Shrink/Fatten: %s", c); + } + else { + sprintf(str, "Shrink/Fatten: %3f", ratio); + } + + for (i = 0 ; i < t->total; i++, td++) { + if (td->flag & TD_NOACTION) + break; + + if (td->flag & TD_SKIP) + continue; + + if (td->val) { + *td->val = td->ival * ratio; + /* apply PET */ + *td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival); if (*td->val <= 0.0f) *td->val = 0.001f; } } @@ -5077,7 +5216,7 @@ void initEdgeSlide(TransInfo *t) int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event) { - if (t->flag & TFM_EDGE_SLIDE) { + if (t->mode == TFM_EDGE_SLIDE) { SlideData *sld = t->customData; if (sld) { @@ -5119,7 +5258,7 @@ int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event) void drawNonPropEdge(const struct bContext *C, TransInfo *t) { - if (t->flag & TFM_EDGE_SLIDE) { + if (t->mode == TFM_EDGE_SLIDE) { SlideData *sld = (SlideData *)t->customData; /* Non-Prop mode */ if (sld && sld->is_proportional == FALSE) { diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 6051fd2577b..fdc09c1bed0 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -494,6 +494,9 @@ int Tilt(TransInfo *t, const int mval[2]); void initCurveShrinkFatten(TransInfo *t); int CurveShrinkFatten(TransInfo *t, const int mval[2]); +void initMaskShrinkFatten(TransInfo *t); +int MaskShrinkFatten(TransInfo *t, const int mval[2]); + void initTrackball(TransInfo *t); int Trackball(TransInfo *t, const int mval[2]); @@ -552,7 +555,7 @@ struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); /*********************** transform_conversions.c ********** */ struct ListBase; -void flushTransGPactionData(TransInfo *t); +void flushTransIntFrameActionData(TransInfo *t); void flushTransGraphData(TransInfo *t); void remake_graph_transdata(TransInfo *t, struct ListBase *anim_data); void flushTransUVs(TransInfo *t); @@ -561,6 +564,7 @@ int clipUVTransform(TransInfo *t, float *vec, int resize); void flushTransNodes(TransInfo *t); void flushTransSeq(TransInfo *t); void flushTransTracking(TransInfo *t); +void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index a069194d868..007ec3c5250 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -53,6 +53,7 @@ #include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "MEM_guardedalloc.h" @@ -87,6 +88,7 @@ #include "BKE_sequencer.h" #include "BKE_tessmesh.h" #include "BKE_tracking.h" +#include "BKE_mask.h" #include "ED_anim_api.h" @@ -102,6 +104,7 @@ #include "ED_types.h" #include "ED_uvedit.h" #include "ED_clip.h" +#include "ED_mask.h" #include "ED_util.h" /* for crazyspace correction */ #include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ @@ -1333,7 +1336,7 @@ static void createTransCurveVerts(bContext *C, TransInfo *t) Object *obedit= CTX_data_edit_object(C); Curve *cu= obedit->data; TransData *td = NULL; - Nurb *nu; + Nurb *nu; BezTriple *bezt; BPoint *bp; float mtx[3][3], smtx[3][3]; @@ -1886,7 +1889,7 @@ static void get_edge_center(float cent_r[3], BMVert *eve) /* way to overwrite what data is edited with transform */ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx, - BMEditMesh *em, BMVert *eve, float *bweight) + BMEditMesh *em, BMVert *eve, float *bweight) { td->flag = 0; //if (key) @@ -2236,7 +2239,7 @@ void flushTransSeq(TransInfo *t) if ((seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ seq->start= new_frame - tdsq->start_offset; #else - if (seq->type != SEQ_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ + if (seq->type != SEQ_TYPE_META && (seq->depth != 0 || seq_tx_test(seq))) /* for meta's, their children move */ seq->start= new_frame - tdsq->start_offset; #endif if (seq->depth==0) { @@ -2279,7 +2282,7 @@ void flushTransSeq(TransInfo *t) /* calc all meta's then effects [#27953] */ for (seq = seqbasep->first; seq; seq = seq->next) { - if (seq->type == SEQ_META && seq->flag & SELECT) { + if (seq->type == SEQ_TYPE_META && seq->flag & SELECT) { calc_sequence(t->scene, seq); } } @@ -2794,6 +2797,99 @@ static void posttrans_gpd_clean (bGPdata *gpd) } } + +/* Called by special_aftertrans_update to make sure selected gp-frames replace + * any other gp-frames which may reside on that frame (that are not selected). + * It also makes sure sorted are still stored in chronological order after + * transform. + */ +static void posttrans_mask_clean(Mask *mask) +{ + MaskLayer *masklay; + + for (masklay = mask->masklayers.first; masklay; masklay= masklay->next) { + ListBase sel_buffer = {NULL, NULL}; + MaskLayerShape *masklay_shape, *masklay_shape_new; + MaskLayerShape *masklay_shape_sort, *masklay_shape_sort_new; + + /* loop 1: loop through and isolate selected gp-frames to buffer + * (these need to be sorted as they are isolated) + */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape_new) { + short added= 0; + masklay_shape_new= masklay_shape->next; + + if (masklay_shape->flag & GP_FRAME_SELECT) { + BLI_remlink(&masklay->splines_shapes, masklay_shape); + + /* find place to add them in buffer + * - go backwards as most frames will still be in order, + * so doing it this way will be faster + */ + for (masklay_shape_sort= sel_buffer.last; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort->prev) { + /* if current (masklay_shape) occurs after this one in buffer, add! */ + if (masklay_shape_sort->frame < masklay_shape->frame) { + BLI_insertlinkafter(&sel_buffer, masklay_shape_sort, masklay_shape); + added= 1; + break; + } + } + if (added == 0) + BLI_addhead(&sel_buffer, masklay_shape); + } + } + + /* error checking: it is unlikely, but may be possible to have none selected */ + if (sel_buffer.first == NULL) + continue; + + /* if all were selected (i.e. masklay->splines_shapes is empty), then just transfer sel-buf over */ + if (masklay->splines_shapes.first == NULL) { + masklay->splines_shapes.first= sel_buffer.first; + masklay->splines_shapes.last= sel_buffer.last; + + continue; + } + + /* loop 2: remove duplicates of splines_shapes in buffers */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape && sel_buffer.first; masklay_shape= masklay_shape_new) { + masklay_shape_new= masklay_shape->next; + + /* loop through sel_buffer, emptying stuff from front of buffer if ok */ + for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort && masklay_shape; masklay_shape_sort= masklay_shape_sort_new) { + masklay_shape_sort_new= masklay_shape_sort->next; + + /* if this buffer frame needs to go before current, add it! */ + if (masklay_shape_sort->frame < masklay_shape->frame) { + /* transfer buffer frame to splines_shapes list (before current) */ + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort); + } + /* if this buffer frame is on same frame, replace current with it and stop */ + else if (masklay_shape_sort->frame == masklay_shape->frame) { + /* transfer buffer frame to splines_shapes list (before current) */ + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_insertlinkbefore(&masklay->splines_shapes, masklay_shape, masklay_shape_sort); + + /* get rid of current frame */ + BKE_mask_layer_shape_unlink(masklay, masklay_shape); + } + } + } + + /* if anything is still in buffer, append to end */ + for (masklay_shape_sort= sel_buffer.first; masklay_shape_sort; masklay_shape_sort= masklay_shape_sort_new) { + masklay_shape_sort_new= masklay_shape_sort->next; + + BLI_remlink(&sel_buffer, masklay_shape_sort); + BLI_addtail(&masklay->splines_shapes, masklay_shape_sort); + } + + /* NOTE: this is the only difference to grease pencil code above */ + BKE_mask_layer_shape_sort(masklay); + } +} + /* Called during special_aftertrans_update to make sure selected keyframes replace * any other keyframes which may reside on that frame (that is not selected). */ @@ -2933,6 +3029,27 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra) return count; } +/* fully select selected beztriples, but only include if it's on the right side of cfra */ +static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra) +{ + MaskLayerShape *masklayer_shape; + int count = 0; + + if (masklay == NULL) + return count; + + /* only include points that occur on the right side of cfra */ + for (masklayer_shape= masklay->splines_shapes.first; masklayer_shape; masklayer_shape= masklayer_shape->next) { + if (masklayer_shape->flag & MASK_SHAPE_SELECT) { + if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra)) + count++; + } + } + + return count; +} + + /* This function assigns the information to transdata */ static void TimeToTransData(TransData *td, float *time, AnimData *adt) { @@ -2995,7 +3112,7 @@ typedef struct tGPFtransdata { } tGPFtransdata; /* This function helps flush transdata written to tempdata into the gp-frames */ -void flushTransGPactionData(TransInfo *t) +void flushTransIntFrameActionData(TransInfo *t) { tGPFtransdata *tfd; int i; @@ -3046,6 +3163,35 @@ static int GPLayerToTransData (TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl return count; } +/* refer to comment above #GPLayerToTransData, this is the same but for masks */ +static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra) +{ + MaskLayerShape *masklay_shape; + int count= 0; + + /* check for select frames on right side of current frame */ + for (masklay_shape= masklay->splines_shapes.first; masklay_shape; masklay_shape= masklay_shape->next) { + if (masklay_shape->flag & MASK_SHAPE_SELECT) { + if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) { + /* memory is calloc'ed, so that should zero everything nicely for us */ + td->val= &tfd->val; + td->ival= (float)masklay_shape->frame; + + tfd->val= (float)masklay_shape->frame; + tfd->sdata= &masklay_shape->frame; + + /* advance td now */ + td++; + tfd++; + count++; + } + } + } + + return count; +} + + static void createTransActionData(bContext *C, TransInfo *t) { Scene *scene= t->scene; @@ -3066,7 +3212,7 @@ static void createTransActionData(bContext *C, TransInfo *t) return; /* filter data */ - if (ac.datatype == ANIMCONT_GPENCIL) + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT); else filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT /*| ANIMFILTER_CURVESONLY*/); @@ -3099,8 +3245,12 @@ static void createTransActionData(bContext *C, TransInfo *t) if (ale->type == ANIMTYPE_FCURVE) count += count_fcurve_keys(ale->key_data, t->frame_side, cfra); - else + else if (ale->type == ANIMTYPE_GPLAYER) count += count_gplayer_frames(ale->data, t->frame_side, cfra); + else if (ale->type == ANIMTYPE_MASKLAYER) + count += count_masklayer_frames(ale->data, t->frame_side, cfra); + else + BLI_assert(0); } /* stop if trying to build list if nothing selected */ @@ -3118,7 +3268,7 @@ static void createTransActionData(bContext *C, TransInfo *t) td= t->data; td2d = t->data2d; - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { if (t->mode == TFM_TIME_SLIDE) { t->customData= MEM_callocN((sizeof(float)*2)+(sizeof(tGPFtransdata)*count), "TimeSlide + tGPFtransdata"); tfd= (tGPFtransdata *)((float *)(t->customData) + 2); @@ -3141,6 +3291,14 @@ static void createTransActionData(bContext *C, TransInfo *t) td += i; tfd += i; } + else if (ale->type == ANIMTYPE_MASKLAYER) { + MaskLayer *masklay = (MaskLayer *)ale->data; + int i; + + i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra); + td += i; + tfd += i; + } else { AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; @@ -3784,7 +3942,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *count = 0; *flag = 0; } - else if (seq->type == SEQ_META) { + else if (seq->type == SEQ_TYPE_META) { /* for meta's we only ever need to extend their children, no matter what depth * just check the meta's are in the bounds */ @@ -3841,7 +3999,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count /* Recursive */ - if ((seq->type == SEQ_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) { + if ((seq->type == SEQ_TYPE_META) && ((seq->flag & (SEQ_LEFTSEL|SEQ_RIGHTSEL)) == 0)) { /* if any handles are selected, don't recurse */ *recursive = TRUE; } @@ -3856,9 +4014,9 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count #ifdef SEQ_TX_NESTED_METAS *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL|SEQ_RIGHTSEL); *count = 1; /* ignore the selection for nested */ - *recursive = (seq->type == SEQ_META); + *recursive = (seq->type == SEQ_TYPE_META); #else - if (seq->type == SEQ_META) { + if (seq->type == SEQ_TYPE_META) { /* Meta's can only directly be moved between channels since they * don't have their start and length set directly (children affect that) * since this Meta is nested we don't need any of its data in fact. @@ -4061,7 +4219,7 @@ static void freeSeqData(TransInfo *t) seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { /* check effects strips, we cant change their time */ - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { has_effect= TRUE; } else { @@ -4120,7 +4278,7 @@ static void freeSeqData(TransInfo *t) for (a=0; a<t->total; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { calc_sequence(t->scene, seq); } } @@ -4132,7 +4290,7 @@ static void freeSeqData(TransInfo *t) for (a=0; a<t->total; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { - if ((seq->type & SEQ_EFFECT) && seq->seq1) { + if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) { if (seq_test_overlap(seqbasep, seq)) { shuffle_seq(seqbasep, seq, t->scene); } @@ -4147,7 +4305,7 @@ static void freeSeqData(TransInfo *t) for (seq= seqbasep->first; seq; seq= seq->next) { /* We might want to build a list of effects that need to be updated during transform */ - if (seq->type & SEQ_EFFECT) { + if (seq->type & SEQ_TYPE_EFFECT) { if (seq->seq1 && seq->seq1->flag & SELECT) calc_sequence(t->scene, seq); else if (seq->seq2 && seq->seq2->flag & SELECT) calc_sequence(t->scene, seq); else if (seq->seq3 && seq->seq3->flag & SELECT) calc_sequence(t->scene, seq); @@ -4216,7 +4374,7 @@ static void createTransSeqData(bContext *C, TransInfo *t) Sequence *seq; for (seq= ed->seqbasep->first; seq; seq= seq->next) { /* hack */ - if ((seq->flag & SELECT)==0 && seq->type & SEQ_EFFECT) { + if ((seq->flag & SELECT)==0 && seq->type & SEQ_TYPE_EFFECT) { Sequence *seq_user; int i; for (i=0; i<3; i++) { @@ -4897,6 +5055,24 @@ void special_aftertrans_update(bContext *C, TransInfo *t) WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); } } + else if (t->options & CTX_MASK) { + SpaceClip *sc = t->sa->spacedata.first; + Mask *mask = ED_space_clip_mask(sc); + + if (t->scene->nodetree) { + /* tracks can be used for stabilization nodes, + * flush update for such nodes */ + nodeUpdateID(t->scene->nodetree, &mask->id); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + } + + /* TODO - dont key all masks... */ + if (IS_AUTOKEY_ON(t->scene)) { + Scene *scene = t->scene; + + ED_mask_layer_shape_auto_key_select(mask, CFRA); + } + } } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; @@ -4983,6 +5159,26 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } } } + else if (ac.datatype == ANIMCONT_MASK) { + /* remove duplicate frames and also make sure points are in order! */ + /* 3 cases here for curve cleanups: + * 1) NOTRANSKEYCULL on -> cleanup of duplicates shouldn't be done + * 2) canceled == 0 -> user confirmed the transform, so duplicates should be removed + * 3) canceled + duplicate -> user canceled the transform, but we made duplicates, so get rid of these + */ + if ((saction->flag & SACTION_NOTRANSKEYCULL)==0 && + ((canceled == 0) || (duplicate))) + { + Mask *mask; + + // XXX: BAD! this get gpencil datablocks directly from main db... + // but that's how this currently works :/ + for (mask = G.main->mask.first; mask; mask = mask->id.next) { + if (ID_REAL_USERS(mask)) + posttrans_mask_clean(mask); + } + } + } /* marker transform, not especially nice but we may want to move markers * at the same time as keyframes in the dope sheet. @@ -5006,7 +5202,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } /* make sure all F-Curves are set correctly */ - if (ac.datatype != ANIMCONT_GPENCIL) + if (!ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) ANIM_editkeyframes_refresh(&ac); /* clear flag that was set for time-slide drawing */ @@ -5392,23 +5588,24 @@ typedef struct TransDataTracking { short coord; } TransDataTracking; -static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, MovieTrackingTrack *track, - int area, float loc[2], float rel[2], const float off[2]) +static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt, + MovieTrackingTrack *track, MovieTrackingMarker *marker, + int area, float loc[2], float rel[2], const float off[2], float aspx, float aspy) { int anchor = area == TRACK_AREA_POINT && off; tdt->mode = transDataTracking_ModeTracks; if (anchor) { - td2d->loc[0] = rel[0]; /* hold original location */ - td2d->loc[1] = rel[1]; + td2d->loc[0] = rel[0] * aspx; /* hold original location */ + td2d->loc[1] = rel[1] * aspy; tdt->loc= loc; td2d->loc2d = loc; /* current location */ } else { - td2d->loc[0] = loc[0]; /* hold original location */ - td2d->loc[1] = loc[1]; + td2d->loc[0] = loc[0] * aspx; /* hold original location */ + td2d->loc[1] = loc[1] * aspy; td2d->loc2d = loc; /* current location */ } @@ -5422,8 +5619,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra if (rel) { if (!anchor) { - td2d->loc[0] += rel[0]; - td2d->loc[1] += rel[1]; + td2d->loc[0] += rel[0] * aspx; + td2d->loc[1] += rel[1] * aspy; } copy_v2_v2(tdt->srelative, rel); @@ -5434,9 +5631,12 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra td->flag = 0; td->loc = td2d->loc; - copy_v3_v3(td->center, td->loc); copy_v3_v3(td->iloc, td->loc); + //copy_v3_v3(td->center, td->loc); + td->center[0] = marker->pos[0] * aspx; + td->center[1] = marker->pos[1] * aspy; + memset(td->axismtx, 0, sizeof(td->axismtx)); td->axismtx[2][2] = 1.0f; @@ -5451,26 +5651,37 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra } static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, - TransDataTracking *tdt, MovieTrackingTrack *track) + TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy) { - MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, sc->user.framenr); + int framenr = ED_space_clip_clip_framenr(sc); + MovieTrackingMarker *marker = BKE_tracking_ensure_marker(track, framenr); tdt->flag = marker->flag; - marker->flag &= ~(MARKER_DISABLED|MARKER_TRACKED); + marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + track->offset, marker->pos, track->offset, aspx, aspy); - if (track->flag & SELECT) - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL); + if (track->flag & SELECT) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT, + marker->pos, NULL, NULL, aspx, aspy); + } if (track->pat_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL); + int a; + + for (a = 0; a < 4; a++) { + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_PAT, + marker->pattern_corners[a], marker->pos, NULL, aspx, aspy); + } } if (track->search_flag & SELECT) { - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL); - markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + marker->search_min, marker->pos, NULL, aspx, aspy); + + markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH, + marker->search_max, marker->pos, NULL, aspx, aspy); } } @@ -5496,7 +5707,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) MovieTrackingTrack *track; MovieTrackingMarker *marker; TransDataTracking *tdt; - int framenr = sc->user.framenr; + int framenr = ED_space_clip_clip_framenr(sc); + float aspx, aspy; /* count */ t->total = 0; @@ -5512,7 +5724,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) t->total++; if (track->pat_flag & SELECT) - t->total+= 2; + t->total+= 4; if (track->search_flag & SELECT) t->total+= 2; @@ -5524,6 +5736,8 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (t->total == 0) return; + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); @@ -5536,25 +5750,23 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) { marker = BKE_tracking_get_marker(track, framenr); - trackToTransData(sc, td, td2d, tdt, track); + trackToTransData(sc, td, td2d, tdt, track, aspx, aspy); /* offset */ td++; td2d++; tdt++; - if ((marker->flag & MARKER_DISABLED) == 0) { - if (track->flag & SELECT) { - td++; - td2d++; - tdt++; - } + if (track->flag & SELECT) { + td++; + td2d++; + tdt++; + } - if (track->pat_flag & SELECT) { - td += 2; - td2d += 2; - tdt +=2; - } + if (track->pat_flag & SELECT) { + td += 4; + td2d += 4; + tdt += 4; } if (track->search_flag & SELECT) { @@ -5706,9 +5918,6 @@ static void createTransTrackingData(bContext *C, TransInfo *t) if (!clip || width == 0 || height == 0) return; - if (!ELEM(t->mode, TFM_RESIZE, TFM_TRANSLATION)) - return; - if (ar->regiontype == RGN_TYPE_PREVIEW) { /* transformation was called from graph editor */ createTransTrackingCurvesData(C, t); @@ -5726,7 +5935,7 @@ static void cancelTransTracking(TransInfo *t) ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); MovieTrackingTrack *track; MovieTrackingMarker *marker; - int a, framenr = sc->user.framenr; + int a, framenr = ED_space_clip_clip_framenr(sc); if (tdt->mode == transDataTracking_ModeTracks) { track = tracksbase->first; @@ -5776,10 +5985,14 @@ static void cancelTransTracking(TransInfo *t) void flushTransTracking(TransInfo *t) { + SpaceClip *sc = t->sa->spacedata.first; TransData *td; TransData2D *td2d; TransDataTracking *tdt; int a; + float aspx, aspy; + + ED_space_clip_aspect_dimension_aware(sc, &aspx, &aspy); if (t->state == TRANS_CANCEL) cancelTransTracking(t); @@ -5787,31 +6000,46 @@ void flushTransTracking(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for (a=0, td= t->data, td2d= t->data2d, tdt= t->customData; a<t->total; a++, td2d++, td++, tdt++) { if (tdt->mode == transDataTracking_ModeTracks) { - if (t->flag & T_ALT_TRANSFORM) { - if (tdt->area == TRACK_AREA_POINT && tdt->relative) { - float d[2], d2[2]; + float loc2d[2]; - if (!tdt->smarkers) { - tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); - for (a = 0; a < tdt->markersnr; a++) - copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); - } + if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) { + continue; + } - sub_v2_v2v2(d, td2d->loc, tdt->soffset); - sub_v2_v2(d, tdt->srelative); + loc2d[0] = td2d->loc[0] / aspx; + loc2d[1] = td2d->loc[1] / aspy; - sub_v2_v2v2(d2, td2d->loc, tdt->srelative); + if (t->flag & T_ALT_TRANSFORM) { + if (t->mode == TFM_RESIZE) { + if (tdt->area != TRACK_AREA_PAT) + continue; + } + else if (t->mode == TFM_TRANSLATION) { + if (tdt->area == TRACK_AREA_POINT && tdt->relative) { + float d[2], d2[2]; + + if (!tdt->smarkers) { + tdt->smarkers = MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + for (a = 0; a < tdt->markersnr; a++) + copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + } + + sub_v2_v2v2(d, loc2d, tdt->soffset); + sub_v2_v2(d, tdt->srelative); - for (a= 0; a<tdt->markersnr; a++) - add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + sub_v2_v2v2(d2, loc2d, tdt->srelative); - negate_v2_v2(td2d->loc2d, d); + for (a= 0; a<tdt->markersnr; a++) + add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + + negate_v2_v2(td2d->loc2d, d); + } } } if (tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { - td2d->loc2d[0] = td2d->loc[0]; - td2d->loc2d[1] = td2d->loc[1]; + td2d->loc2d[0] = loc2d[0]; + td2d->loc2d[1] = loc2d[1]; if (tdt->relative) sub_v2_v2(td2d->loc2d, tdt->relative); @@ -5823,6 +6051,219 @@ void flushTransTracking(TransInfo *t) } } +/* * masking * */ + +typedef struct TransDataMasking { + int is_handle; + + float handle[2], orig_handle[2]; + float vec[3][3]; + MaskSplinePoint *point; +} TransDataMasking; + +static void MaskPointToTransData(SpaceClip *sc, MaskSplinePoint *point, + TransData *td, TransData2D *td2d, TransDataMasking *tdm, int propmode) +{ + BezTriple *bezt = &point->bezt; + float aspx, aspy; + short is_sel_point = MASKPOINT_ISSEL_KNOT(point); + short is_sel_any = MASKPOINT_ISSEL_ANY(point); + + tdm->point = point; + copy_m3_m3(tdm->vec, bezt->vec); + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + + if (propmode || is_sel_point) { + int i; + for (i = 0; i < 3; i++) { + /* CV coords are scaled by aspects. this is needed for rotations and + * proportional editing to be consistent with the stretched CV coords + * that are displayed. this also means that for display and numinput, + * and when the the CV coords are flushed, these are converted each time */ + td2d->loc[0] = bezt->vec[i][0]*aspx; + td2d->loc[1] = bezt->vec[i][1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = bezt->vec[i]; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext = NULL; + + if (i == 1) { + /* scaling weights */ + td->val = &bezt->weight; + td->ival = *td->val; + } + else { + td->val = NULL; + } + + if (is_sel_any) { + td->flag |= TD_SELECTED; + } + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } + } + else { + tdm->is_handle = TRUE; + + BKE_mask_point_handle(point, tdm->handle); + + copy_v2_v2(tdm->orig_handle, tdm->handle); + + td2d->loc[0] = tdm->handle[0]*aspx; + td2d->loc[1] = tdm->handle[1]*aspy; + td2d->loc[2] = 0.0f; + td2d->loc2d = tdm->handle; + + td->flag = 0; + td->loc = td2d->loc; + copy_v3_v3(td->center, td->loc); + copy_v3_v3(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; + td->val= NULL; + + if (is_sel_any) { + td->flag |= TD_SELECTED; + } + + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); + + td++; + td2d++; + } +} + +static void createTransMaskingData(bContext *C, TransInfo *t) +{ + SpaceClip *sc = CTX_wm_space_clip(C); + Mask *mask = CTX_data_edit_mask(C); + MaskLayer *masklay; + TransData *td = NULL; + TransData2D *td2d = NULL; + TransDataMasking *tdm = NULL; + int count = 0, countsel = 0; + int propmode = t->flag & T_PROP_EDIT; + + t->total = 0; + + if (!mask) + return; + + /* count */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (MASKPOINT_ISSEL_ANY(point)) { + if (MASKPOINT_ISSEL_KNOT(point)) + countsel += 3; + else + countsel += 1; + } + + if (propmode) + count += 3; + } + } + } + + /* note: in prop mode we need at least 1 selected */ + if (countsel == 0) return; + + t->total = (propmode) ? count: countsel; + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransObData(Mask Editing)"); + /* for each 2d uv coord a 3d vector is allocated, so that they can be + * treated just as if they were 3d verts */ + td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(Mask Editing)"); + tdm = t->customData = MEM_callocN(t->total*sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); + + t->flag |= T_FREE_CUSTOMDATA; + + /* create data */ + for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { + MaskSpline *spline = masklay->splines.first; + + if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { + continue; + } + + for (spline = masklay->splines.first; spline; spline = spline->next) { + int i; + + for (i = 0; i < spline->tot_point; i++) { + MaskSplinePoint *point = &spline->points[i]; + + if (propmode || MASKPOINT_ISSEL_ANY(point)) { + MaskPointToTransData(sc, point, td, td2d, tdm, propmode); + + if (propmode || MASKPOINT_ISSEL_KNOT(point)) { + td += 3; + td2d += 3; + tdm += 3; + } + else { + td++; + td2d++; + tdm++; + } + } + } + } + } +} + +void flushTransMasking(TransInfo *t) +{ + SpaceClip *sc = t->sa->spacedata.first; + TransData2D *td; + TransDataMasking *tdm; + int a; + float aspx, aspy, invx, invy; + + ED_space_clip_mask_aspect(sc, &aspx, &aspy); + invx = 1.0f/aspx; + invy = 1.0f/aspy; + + /* flush to 2d vector from internally used 3d vector */ + for (a=0, td = t->data2d, tdm = t->customData; a<t->total; a++, td++, tdm++) { + td->loc2d[0]= td->loc[0]*invx; + td->loc2d[1]= td->loc[1]*invy; + + if (tdm->is_handle) + BKE_mask_point_set_handle(tdm->point, td->loc2d, t->flag & T_ALT_TRANSFORM, tdm->orig_handle, tdm->vec); + } +} + void createTransData(bContext *C, TransInfo *t) { Scene *scene = t->scene; @@ -5892,6 +6333,15 @@ void createTransData(bContext *C, TransInfo *t) t->flag |= T_POINTS|T_2D_EDIT; if (t->options & CTX_MOVIECLIP) createTransTrackingData(C, t); + else if (t->options & CTX_MASK) { + createTransMaskingData(C, t); + + if (t->data && (t->flag & T_PROP_EDIT)) { + sort_trans_data(t); // makes selected become first in array + set_prop_dist(t, TRUE); + sort_trans_data_dist(t); + } + } } else if (t->obedit) { t->ext = NULL; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0f742458ed3..1b8cc14ecac 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -49,6 +49,7 @@ #include "DNA_view3d_types.h" #include "DNA_modifier_types.h" #include "DNA_movieclip_types.h" +#include "DNA_mask_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -349,9 +350,9 @@ static void recalcData_actedit(TransInfo *t) ANIM_animdata_context_getdata(&ac); /* perform flush */ - if (ac.datatype == ANIMCONT_GPENCIL) { + if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { /* flush transform values back to actual coordinates */ - flushTransGPactionData(t); + flushTransIntFrameActionData(t); } else { /* get animdata blocks visible in editor, assuming that these will be the ones where things changed */ @@ -638,33 +639,49 @@ static void recalcData_spaceclip(TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; - MovieClip *clip = ED_space_clip(sc); - ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); - MovieTrackingTrack *track; + if (ED_space_clip_show_trackedit(sc)) { + MovieClip *clip = ED_space_clip(sc); + ListBase *tracksbase = BKE_tracking_get_tracks(&clip->tracking); + MovieTrackingTrack *track; + int framenr = sc->user.framenr; - flushTransTracking(t); + flushTransTracking(t); - track = tracksbase->first; - while (track) { - if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { - if (t->mode == TFM_TRANSLATION) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_POS); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); - } - else if (t->mode == TFM_RESIZE) { - if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) - BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); - if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) - BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + track = tracksbase->first; + while (track) { + if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED)==0) { + MovieTrackingMarker *marker = BKE_tracking_get_marker(track, framenr); + + if (t->mode == TFM_TRANSLATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_POS); + } + else if (t->mode == TFM_RESIZE) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_DIM); + if (TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_marker(marker, CLAMP_SEARCH_DIM); + } + else if (t->mode == TFM_ROTATION) { + if (TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_marker(marker, CLAMP_PAT_POS); + } } + + track = track->next; } - track = track->next; + DAG_id_tag_update(&clip->id, 0); } + else if (ED_space_clip_show_maskedit(sc)) { + Mask *mask = ED_space_clip_mask(sc); - DAG_id_tag_update(&clip->id, 0); + flushTransMasking(t); + + DAG_id_tag_update(&mask->id, 0); + } } /* helper for recalcData() - for 3d-view transforms */ @@ -1109,9 +1126,12 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) else if (t->spacetype==SPACE_CLIP) { SpaceClip *sclip = sa->spacedata.first; t->view = &ar->v2d; + t->around = sclip->around; if (ED_space_clip_show_trackedit(sclip)) t->options |= CTX_MOVIECLIP; + else if (ED_space_clip_show_maskedit(sclip)) + t->options |= CTX_MASK; } else { if (ar) { @@ -1174,6 +1194,15 @@ int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) t->flag |= T_PROP_CONNECTED; } } + else if (t->options & CTX_MASK) { + if (ts->proportional_mask) { + t->flag |= T_PROP_EDIT; + + if (ts->proportional == PROP_EDIT_CONNECTED) { + t->flag |= T_PROP_CONNECTED; + } + } + } else if (t->obedit == NULL && ts->proportional_objects) { t->flag |= T_PROP_EDIT; } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 6fd8e07d34a..52b32ae66fc 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -51,8 +51,7 @@ #include "transform.h" -typedef struct TransformModeItem -{ +typedef struct TransformModeItem { char *idname; int mode; void (*opfunc)(wmOperatorType*); @@ -135,6 +134,7 @@ EnumPropertyItem transform_mode_types[] = {TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""}, {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""}, {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""}, + {TFM_MASK_SHRINKFATTEN, "MASK_SHRINKFATTEN", 0, "Mask_Shrinkfatten", ""}, {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""}, {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""}, {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""}, @@ -1025,6 +1025,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0); break; default: break; |