Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/CMakeLists.txt1
-rw-r--r--source/blender/editors/SConscript1
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c177
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c59
-rw-r--r--source/blender/editors/animation/anim_filter.c118
-rw-r--r--source/blender/editors/animation/keyframes_draw.c83
-rw-r--r--source/blender/editors/animation/keyframes_general.c8
-rw-r--r--source/blender/editors/armature/editarmature.c49
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c9
-rw-r--r--source/blender/editors/curve/curve_ops.c12
-rw-r--r--source/blender/editors/curve/editcurve.c14
-rw-r--r--source/blender/editors/curve/lorem.c2
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c9
-rw-r--r--source/blender/editors/gpencil/editaction_gpencil.c53
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c29
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c10
-rw-r--r--source/blender/editors/include/ED_anim_api.h52
-rw-r--r--source/blender/editors/include/ED_clip.h14
-rw-r--r--source/blender/editors/include/ED_gpencil.h23
-rw-r--r--source/blender/editors/include/ED_keyframes_draw.h6
-rw-r--r--source/blender/editors/include/ED_mask.h74
-rw-r--r--source/blender/editors/include/ED_object.h1
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_transform.h7
-rw-r--r--source/blender/editors/include/ED_view3d.h2
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/include/UI_resources.h19
-rw-r--r--source/blender/editors/interface/interface_draw.c174
-rw-r--r--source/blender/editors/interface/interface_handlers.c7
-rw-r--r--source/blender/editors/interface/interface_panel.c13
-rw-r--r--source/blender/editors/interface/interface_templates.c20
-rw-r--r--source/blender/editors/interface/interface_widgets.c11
-rw-r--r--source/blender/editors/interface/resources.c100
-rw-r--r--source/blender/editors/mask/CMakeLists.txt52
-rw-r--r--source/blender/editors/mask/SConscript9
-rw-r--r--source/blender/editors/mask/mask_add.c711
-rw-r--r--source/blender/editors/mask/mask_draw.c425
-rw-r--r--source/blender/editors/mask/mask_edit.c342
-rw-r--r--source/blender/editors/mask/mask_editaction.c250
-rw-r--r--source/blender/editors/mask/mask_intern.h113
-rw-r--r--source/blender/editors/mask/mask_ops.c1263
-rw-r--r--source/blender/editors/mask/mask_relationships.c172
-rw-r--r--source/blender/editors/mask/mask_select.c766
-rw-r--r--source/blender/editors/mask/mask_shapekey.c276
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c22
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c61
-rw-r--r--source/blender/editors/object/object_edit.c38
-rw-r--r--source/blender/editors/object/object_lattice.c17
-rw-r--r--source/blender/editors/object/object_modifier.c6
-rw-r--r--source/blender/editors/object/object_ops.c8
-rw-r--r--source/blender/editors/object/object_relations.c1
-rw-r--r--source/blender/editors/object/object_select.c19
-rw-r--r--source/blender/editors/render/render_internal.c5
-rw-r--r--source/blender/editors/screen/screen_ops.c22
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c3
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c5
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c16
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c29
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c68
-rw-r--r--source/blender/editors/sound/sound_ops.c6
-rw-r--r--source/blender/editors/space_action/action_draw.c19
-rw-r--r--source/blender/editors/space_action/action_edit.c72
-rw-r--r--source/blender/editors/space_action/action_select.c70
-rw-r--r--source/blender/editors/space_action/space_action.c14
-rw-r--r--source/blender/editors/space_api/spacetypes.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/clip_buttons.c93
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_draw.c13
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c6
-rw-r--r--source/blender/editors/space_clip/clip_draw.c368
-rw-r--r--source/blender/editors/space_clip/clip_editor.c145
-rw-r--r--source/blender/editors/space_clip/clip_graph_draw.c8
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c17
-rw-r--r--source/blender/editors/space_clip/clip_intern.h4
-rw-r--r--source/blender/editors/space_clip/clip_utils.c11
-rw-r--r--source/blender/editors/space_clip/space_clip.c113
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c428
-rw-r--r--source/blender/editors/space_console/console_intern.h3
-rw-r--r--source/blender/editors/space_console/console_ops.c95
-rw-r--r--source/blender/editors/space_console/space_console.c9
-rw-r--r--source/blender/editors/space_file/filelist.c6
-rw-r--r--source/blender/editors/space_file/filelist.h3
-rw-r--r--source/blender/editors/space_image/image_buttons.c2
-rw-r--r--source/blender/editors/space_image/image_draw.c31
-rw-r--r--source/blender/editors/space_image/image_intern.h1
-rw-r--r--source/blender/editors/space_image/image_ops.c91
-rw-r--r--source/blender/editors/space_image/space_image.c10
-rw-r--r--source/blender/editors/space_logic/logic_window.c1802
-rw-r--r--source/blender/editors/space_nla/nla_draw.c86
-rw-r--r--source/blender/editors/space_node/drawnode.c107
-rw-r--r--source/blender/editors/space_node/node_edit.c16
-rw-r--r--source/blender/editors/space_node/node_intern.h3
-rw-r--r--source/blender/editors/space_node/node_select.c2
-rw-r--r--source/blender/editors/space_node/space_node.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c32
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c7
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c78
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c4
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c126
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c164
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c96
-rw-r--r--source/blender/editors/space_sequencer/sequencer_intern.h1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_ops.c1
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c41
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c32
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c107
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c6
-rw-r--r--source/blender/editors/space_view3d/drawobject.c417
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c198
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h41
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c21
-rw-r--r--source/blender/editors/transform/transform.c199
-rw-r--r--source/blender/editors/transform/transform.h6
-rw-r--r--source/blender/editors/transform/transform_conversions.c592
-rw-r--r--source/blender/editors/transform/transform_generics.c73
-rw-r--r--source/blender/editors/transform/transform_ops.c5
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;