2011-11-07 12:55:18 +00:00
|
|
|
/*
|
|
|
|
|
* ***** 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
|
2018-06-01 18:19:39 +02:00
|
|
|
* of the License, or (at your option) any later version.
|
2011-11-07 12:55:18 +00:00
|
|
|
*
|
|
|
|
|
* 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/space_clip/clip_graph_ops.c
|
|
|
|
|
* \ingroup spclip
|
|
|
|
|
*/
|
|
|
|
|
|
2012-01-26 09:29:49 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
#include "BLI_math.h"
|
2012-03-04 19:34:01 +00:00
|
|
|
#include "BLI_rect.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
|
#include "BKE_tracking.h"
|
2017-06-08 10:14:53 +02:00
|
|
|
|
|
|
|
|
#include "DEG_depsgraph.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_screen.h"
|
2018-08-14 10:28:41 +10:00
|
|
|
#include "ED_select_utils.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "ED_clip.h"
|
|
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
|
|
|
|
#include "UI_view2d.h"
|
|
|
|
|
|
2012-06-10 19:59:02 +00:00
|
|
|
#include "clip_intern.h" // own include
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/******************** common graph-editing utilities ********************/
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool ED_space_clip_graph_poll(bContext *C)
|
2012-01-26 09:29:49 +00:00
|
|
|
{
|
2012-04-29 12:32:26 +00:00
|
|
|
if (ED_space_clip_tracking_poll(C)) {
|
2012-04-30 16:19:20 +00:00
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-01-26 09:29:49 +00:00
|
|
|
|
2012-05-02 17:33:48 +00:00
|
|
|
return sc->view == SC_VIEW_GRAPH;
|
2012-01-26 09:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
return false;
|
2012-01-26 09:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool clip_graph_knots_poll(bContext *C)
|
2013-12-25 19:35:29 +06:00
|
|
|
{
|
|
|
|
|
if (ED_space_clip_graph_poll(C)) {
|
|
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
|
|
|
|
|
|
|
|
|
return (sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) != 0;
|
|
|
|
|
}
|
2014-04-01 11:34:00 +11:00
|
|
|
return false;
|
2013-12-25 19:35:29 +06:00
|
|
|
}
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
typedef struct {
|
|
|
|
|
int action;
|
|
|
|
|
} SelectUserData;
|
|
|
|
|
|
|
|
|
|
static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker)
|
|
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
SelectUserData *data = (SelectUserData *)userdata;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-04-28 06:31:57 +00:00
|
|
|
switch (data->action) {
|
2011-11-07 12:55:18 +00:00
|
|
|
case SEL_SELECT:
|
2012-03-25 23:19:21 +00:00
|
|
|
marker->flag |= MARKER_GRAPH_SEL;
|
2011-11-07 12:55:18 +00:00
|
|
|
break;
|
|
|
|
|
case SEL_DESELECT:
|
2012-03-25 23:19:21 +00:00
|
|
|
marker->flag &= ~MARKER_GRAPH_SEL;
|
2011-11-07 12:55:18 +00:00
|
|
|
break;
|
|
|
|
|
case SEL_INVERT:
|
2012-03-25 23:19:21 +00:00
|
|
|
marker->flag ^= MARKER_GRAPH_SEL;
|
2011-11-07 12:55:18 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************** mouse select operator ********************/
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2013-09-05 13:37:53 +00:00
|
|
|
int coord; /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */
|
|
|
|
|
bool has_prev; /* if there's valid coordinate of previous point of curve segment */
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2014-08-13 08:27:50 +10:00
|
|
|
float min_dist_sq, /* minimal distance between mouse and currently found entity */
|
2012-06-10 19:59:02 +00:00
|
|
|
mouse_co[2], /* mouse coordinate */
|
|
|
|
|
prev_co[2], /* coordinate of previeous point of segment */
|
|
|
|
|
min_co[2]; /* coordinate of entity with minimal distance */
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-10 19:59:02 +00:00
|
|
|
MovieTrackingTrack *track; /* nearest found track */
|
|
|
|
|
MovieTrackingMarker *marker; /* nearest found marker */
|
2011-11-07 12:55:18 +00:00
|
|
|
} MouseSelectUserData;
|
|
|
|
|
|
|
|
|
|
static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track,
|
2012-06-10 17:09:35 +00:00
|
|
|
MovieTrackingMarker *UNUSED(marker),
|
|
|
|
|
int coord, int scene_framenr, float val)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
MouseSelectUserData *data = userdata;
|
2012-06-10 17:09:35 +00:00
|
|
|
float co[2] = {scene_framenr, val};
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (data->has_prev) {
|
2014-08-13 08:27:50 +10:00
|
|
|
float dist_sq = dist_squared_to_line_segment_v2(data->mouse_co, data->prev_co, co);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2014-08-13 08:27:50 +10:00
|
|
|
if (data->track == NULL || dist_sq < data->min_dist_sq) {
|
2012-03-25 23:19:21 +00:00
|
|
|
data->track = track;
|
2014-08-13 08:27:50 +10:00
|
|
|
data->min_dist_sq = dist_sq;
|
2012-03-25 23:19:21 +00:00
|
|
|
data->coord = coord;
|
2011-11-07 12:55:18 +00:00
|
|
|
copy_v2_v2(data->min_co, co);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-20 15:52:00 +06:00
|
|
|
data->has_prev = true;
|
2011-11-07 12:55:18 +00:00
|
|
|
copy_v2_v2(data->prev_co, co);
|
|
|
|
|
}
|
|
|
|
|
|
2013-10-13 22:26:29 +02:00
|
|
|
static void find_nearest_tracking_segment_end_cb(void *userdata, int UNUSED(coord))
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
MouseSelectUserData *data = userdata;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
data->has_prev = false;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track,
|
2012-06-10 17:09:35 +00:00
|
|
|
MovieTrackingMarker *marker, int coord, int scene_framenr, float val)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
MouseSelectUserData *data = userdata;
|
2014-08-13 08:27:50 +10:00
|
|
|
float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]};
|
|
|
|
|
float dist_sq = len_squared_v2(mdiff);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2014-08-13 08:27:50 +10:00
|
|
|
if (data->marker == NULL || dist_sq < data->min_dist_sq) {
|
2012-06-10 17:09:35 +00:00
|
|
|
float co[2] = {scene_framenr, val};
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
data->track = track;
|
|
|
|
|
data->marker = marker;
|
2014-08-13 08:27:50 +10:00
|
|
|
data->min_dist_sq = dist_sq;
|
2012-03-25 23:19:21 +00:00
|
|
|
data->coord = coord;
|
2011-11-07 12:55:18 +00:00
|
|
|
copy_v2_v2(data->min_co, co);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-30 11:08:33 +11:00
|
|
|
static void mouse_select_init_data(MouseSelectUserData *userdata, const float co[2])
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
|
|
|
|
memset(userdata, 0, sizeof(MouseSelectUserData));
|
2014-08-13 08:27:50 +10:00
|
|
|
userdata->min_dist_sq = FLT_MAX;
|
2011-11-07 12:55:18 +00:00
|
|
|
copy_v2_v2(userdata->mouse_co, co);
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
static bool mouse_select_knot(bContext *C, float co[2], bool extend)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-25 23:19:21 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
|
View2D *v2d = &ar->v2d;
|
|
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2012-03-25 23:19:21 +00:00
|
|
|
static const int delta = 6;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (act_track) {
|
2011-11-07 12:55:18 +00:00
|
|
|
MouseSelectUserData userdata;
|
|
|
|
|
|
|
|
|
|
mouse_select_init_data(&userdata, co);
|
2012-03-25 23:19:21 +00:00
|
|
|
clip_graph_tracking_values_iterate_track(sc, act_track, &userdata,
|
|
|
|
|
find_nearest_tracking_knot_cb, NULL, NULL);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (userdata.marker) {
|
2011-11-07 12:55:18 +00:00
|
|
|
int x1, y1, x2, y2;
|
|
|
|
|
|
2014-04-21 18:11:47 +10:00
|
|
|
if (UI_view2d_view_to_region_clip(v2d, co[0], co[1], &x1, &y1) &&
|
|
|
|
|
UI_view2d_view_to_region_clip(v2d, userdata.min_co[0], userdata.min_co[1], &x2, &y2) &&
|
|
|
|
|
(abs(x2 - x1) <= delta && abs(y2 - y1) <= delta))
|
|
|
|
|
{
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!extend) {
|
2011-11-07 12:55:18 +00:00
|
|
|
SelectUserData selectdata = {SEL_DESELECT};
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2013-10-15 15:21:28 +00:00
|
|
|
clip_graph_tracking_iterate(sc,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
|
|
|
|
|
&selectdata,
|
2012-06-12 17:11:16 +00:00
|
|
|
toggle_selection_cb);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2015-05-13 15:55:32 +05:00
|
|
|
if (userdata.coord == 0) {
|
|
|
|
|
if (extend && (userdata.marker->flag & MARKER_GRAPH_SEL_X) != 0)
|
|
|
|
|
userdata.marker->flag &= ~MARKER_GRAPH_SEL_X;
|
|
|
|
|
else
|
|
|
|
|
userdata.marker->flag |= MARKER_GRAPH_SEL_X;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (extend && (userdata.marker->flag & MARKER_GRAPH_SEL_Y) != 0)
|
|
|
|
|
userdata.marker->flag &= ~MARKER_GRAPH_SEL_Y;
|
|
|
|
|
else
|
|
|
|
|
userdata.marker->flag |= MARKER_GRAPH_SEL_Y;
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
return true;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
return false;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
static bool mouse_select_curve(bContext *C, float co[2], bool extend)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-25 23:19:21 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
MouseSelectUserData userdata;
|
|
|
|
|
|
|
|
|
|
mouse_select_init_data(&userdata, co);
|
2013-10-15 15:21:28 +00:00
|
|
|
clip_graph_tracking_values_iterate(sc,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
|
2012-06-12 17:11:16 +00:00
|
|
|
&userdata, find_nearest_tracking_segment_cb,
|
2012-03-25 23:19:21 +00:00
|
|
|
NULL, find_nearest_tracking_segment_end_cb);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (userdata.track) {
|
|
|
|
|
if (extend) {
|
2012-03-25 23:19:21 +00:00
|
|
|
if (act_track == userdata.track) {
|
2019-01-15 23:24:20 +11:00
|
|
|
/* currently only single curve can be selected
|
|
|
|
|
* (selected curve represents active track) */
|
2012-03-25 23:19:21 +00:00
|
|
|
act_track = NULL;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
else if (act_track != userdata.track) {
|
2011-11-07 12:55:18 +00:00
|
|
|
SelectUserData selectdata = {SEL_DESELECT};
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
tracking->act_track = userdata.track;
|
2015-05-13 16:11:26 +05:00
|
|
|
if ((sc->flag & SC_SHOW_GRAPH_SEL_ONLY) == 0) {
|
|
|
|
|
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
|
|
|
|
|
BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, false);
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* deselect all knots on newly selected curve */
|
2013-10-15 15:21:28 +00:00
|
|
|
clip_graph_tracking_iterate(sc,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
|
|
|
|
|
&selectdata, toggle_selection_cb);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
return true;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
return false;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:53 +00:00
|
|
|
static int mouse_select(bContext *C, float co[2], bool extend)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2013-09-05 13:37:53 +00:00
|
|
|
bool sel = false;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* first try to select knot on selected curves */
|
2012-03-25 23:19:21 +00:00
|
|
|
sel = mouse_select_knot(C, co, extend);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!sel) {
|
2011-11-07 12:55:18 +00:00
|
|
|
/* if there's no close enough knot to mouse osition, select nearest curve */
|
2012-03-25 23:19:21 +00:00
|
|
|
sel = mouse_select_curve(C, co, extend);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (sel)
|
2012-05-07 08:53:59 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int select_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
float co[2];
|
2013-09-05 13:37:53 +00:00
|
|
|
bool extend = RNA_boolean_get(op->ptr, "extend");
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
RNA_float_get_array(op->ptr, "location", co);
|
|
|
|
|
|
|
|
|
|
return mouse_select(C, co, extend);
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2011-11-07 12:55:18 +00:00
|
|
|
float co[2];
|
|
|
|
|
|
|
|
|
|
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
|
|
|
|
|
RNA_float_set_array(op->ptr, "location", co);
|
|
|
|
|
|
|
|
|
|
return select_exec(C, op);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_select(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Select";
|
|
|
|
|
ot->description = "Select graph curves";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_select";
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = select_exec;
|
|
|
|
|
ot->invoke = select_invoke;
|
2013-12-25 19:35:29 +06:00
|
|
|
ot->poll = clip_graph_knots_poll;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = OPTYPE_UNDO;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
|
RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX,
|
2012-06-10 19:59:02 +00:00
|
|
|
"Location", "Mouse location to select nearest entity", -100.0f, 100.0f);
|
2011-11-07 12:55:18 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", 0,
|
2012-06-10 19:59:02 +00:00
|
|
|
"Extend", "Extend selection rather than clearing the existing selection");
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
/********************** box select operator *********************/
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
typedef struct BoxSelectuserData {
|
2012-03-04 19:34:01 +00:00
|
|
|
rctf rect;
|
2017-10-16 21:58:51 +11:00
|
|
|
bool select, extend, changed;
|
2018-10-05 10:27:04 +10:00
|
|
|
} BoxSelectuserData;
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
static void box_select_cb(void *userdata, MovieTrackingTrack *UNUSED(track),
|
2012-06-10 17:09:35 +00:00
|
|
|
MovieTrackingMarker *marker, int coord, int scene_framenr, float val)
|
2012-03-04 19:34:01 +00:00
|
|
|
{
|
2018-10-05 10:27:04 +10:00
|
|
|
BoxSelectuserData *data = (BoxSelectuserData *) userdata;
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2012-08-23 18:25:45 +00:00
|
|
|
if (BLI_rctf_isect_pt(&data->rect, scene_framenr, val)) {
|
2012-03-04 19:34:01 +00:00
|
|
|
int flag = 0;
|
|
|
|
|
|
|
|
|
|
if (coord == 0)
|
|
|
|
|
flag = MARKER_GRAPH_SEL_X;
|
|
|
|
|
else
|
|
|
|
|
flag = MARKER_GRAPH_SEL_Y;
|
|
|
|
|
|
2017-10-16 21:58:51 +11:00
|
|
|
if (data->select) {
|
2012-03-04 19:34:01 +00:00
|
|
|
marker->flag |= flag;
|
2017-10-16 21:58:51 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-04 19:34:01 +00:00
|
|
|
marker->flag &= ~flag;
|
2017-10-16 21:58:51 +11:00
|
|
|
}
|
2013-11-26 06:39:14 +11:00
|
|
|
data->changed = true;
|
2012-03-04 19:34:01 +00:00
|
|
|
}
|
|
|
|
|
else if (!data->extend) {
|
2012-05-03 23:47:39 +00:00
|
|
|
marker->flag &= ~MARKER_GRAPH_SEL;
|
2012-03-04 19:34:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
static int box_select_graph_exec(bContext *C, wmOperator *op)
|
2012-03-04 19:34:01 +00:00
|
|
|
{
|
|
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
2012-07-26 22:41:40 +00:00
|
|
|
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-25 23:19:21 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2018-10-05 10:27:04 +10:00
|
|
|
BoxSelectuserData userdata;
|
2014-04-21 16:47:16 +10:00
|
|
|
rctf rect;
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2013-08-30 09:11:47 +00:00
|
|
|
if (act_track == NULL) {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-04 19:34:01 +00:00
|
|
|
/* get rectangle from operator */
|
2014-04-21 16:47:16 +10:00
|
|
|
WM_operator_properties_border_to_rctf(op, &rect);
|
|
|
|
|
UI_view2d_region_to_view_rctf(&ar->v2d, &rect, &userdata.rect);
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
userdata.changed = false;
|
2017-10-16 21:58:51 +11:00
|
|
|
userdata.select = !RNA_boolean_get(op->ptr, "deselect");
|
2012-03-04 19:34:01 +00:00
|
|
|
userdata.extend = RNA_boolean_get(op->ptr, "extend");
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
clip_graph_tracking_values_iterate_track(sc, act_track, &userdata, box_select_cb, NULL, NULL);
|
2012-03-04 19:34:01 +00:00
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
if (userdata.changed) {
|
2012-05-07 08:53:59 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
|
2012-03-04 19:34:01 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-05 10:27:04 +10:00
|
|
|
void CLIP_OT_graph_select_box(wmOperatorType *ot)
|
2012-03-04 19:34:01 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->name = "Box Select";
|
|
|
|
|
ot->description = "Select curve points using box selection";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_select_box";
|
2012-03-04 19:34:01 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2018-10-05 10:27:04 +10:00
|
|
|
ot->invoke = WM_gesture_box_invoke;
|
|
|
|
|
ot->exec = box_select_graph_exec;
|
|
|
|
|
ot->modal = WM_gesture_box_modal;
|
2013-12-25 19:35:29 +06:00
|
|
|
ot->poll = clip_graph_knots_poll;
|
2012-03-04 19:34:01 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_UNDO;
|
|
|
|
|
|
|
|
|
|
/* properties */
|
2018-10-05 10:27:04 +10:00
|
|
|
WM_operator_properties_gesture_box_select(ot);
|
2012-03-04 19:34:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-08 17:06:40 +00:00
|
|
|
/********************** select all operator *********************/
|
|
|
|
|
|
|
|
|
|
static int graph_select_all_markers_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-08 17:06:40 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2012-03-08 17:06:40 +00:00
|
|
|
MovieTrackingMarker *marker;
|
|
|
|
|
int action = RNA_enum_get(op->ptr, "action");
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
if (!act_track)
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
|
|
if (action == SEL_TOGGLE) {
|
|
|
|
|
action = SEL_SELECT;
|
|
|
|
|
|
|
|
|
|
for (a = 0; a < act_track->markersnr; a++) {
|
|
|
|
|
marker = &act_track->markers[a];
|
|
|
|
|
|
|
|
|
|
if (marker->flag & MARKER_GRAPH_SEL) {
|
|
|
|
|
action = SEL_DESELECT;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (a = 0; a < act_track->markersnr; a++) {
|
|
|
|
|
marker = &act_track->markers[a];
|
|
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
|
case SEL_SELECT:
|
|
|
|
|
marker->flag |= MARKER_GRAPH_SEL;
|
|
|
|
|
break;
|
|
|
|
|
case SEL_DESELECT:
|
|
|
|
|
marker->flag &= ~MARKER_GRAPH_SEL;
|
|
|
|
|
break;
|
|
|
|
|
case SEL_INVERT:
|
|
|
|
|
marker->flag ^= MARKER_GRAPH_SEL;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-07 08:53:59 +00:00
|
|
|
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_select_all_markers(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-17 19:14:08 +00:00
|
|
|
ot->name = "(De)select All Markers";
|
2012-03-08 17:06:40 +00:00
|
|
|
ot->description = "Change selection of all markers of active track";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_select_all_markers";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = graph_select_all_markers_exec;
|
2013-12-25 19:35:29 +06:00
|
|
|
ot->poll = clip_graph_knots_poll;
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-05-07 08:53:59 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
WM_operator_properties_select_all(ot);
|
|
|
|
|
}
|
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
/******************** delete curve operator ********************/
|
|
|
|
|
|
2013-12-20 01:38:07 +01:00
|
|
|
static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op))
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-25 23:19:21 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2013-12-20 01:38:07 +01:00
|
|
|
if (!act_track)
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2013-12-20 01:38:07 +01:00
|
|
|
clip_delete_track(C, clip, act_track);
|
2013-11-25 04:55:26 +01:00
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_delete_curve(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Delete Curve";
|
2013-11-26 00:38:50 +01:00
|
|
|
ot->description = "Delete track corresponding to the selected curve";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "CLIP_OT_graph_delete_curve";
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2013-12-20 01:38:07 +01:00
|
|
|
ot->invoke = WM_operator_confirm;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = delete_curve_exec;
|
2013-12-25 19:35:29 +06:00
|
|
|
ot->poll = clip_graph_knots_poll;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-05-07 08:53:59 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************** delete knot operator ********************/
|
|
|
|
|
|
|
|
|
|
static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-25 23:19:21 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (act_track) {
|
2012-03-25 23:19:21 +00:00
|
|
|
int a = 0;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
while (a < act_track->markersnr) {
|
|
|
|
|
MovieTrackingMarker *marker = &act_track->markers[a];
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (marker->flag & MARKER_GRAPH_SEL)
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
clip_delete_marker(C, clip, act_track, marker);
|
2011-11-07 12:55:18 +00:00
|
|
|
else
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_delete_knot(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Delete Knot";
|
|
|
|
|
ot->description = "Delete curve knots";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_delete_knot";
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = delete_knot_exec;
|
2013-12-25 19:35:29 +06:00
|
|
|
ot->poll = clip_graph_knots_poll;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
/* flags */
|
2012-05-07 08:53:59 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
/******************** view all operator ********************/
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
float min, max;
|
|
|
|
|
} ViewAllUserData;
|
|
|
|
|
|
|
|
|
|
static void view_all_cb(void *userdata, MovieTrackingTrack *UNUSED(track), MovieTrackingMarker *UNUSED(marker),
|
2012-06-10 17:09:35 +00:00
|
|
|
int UNUSED(coord), int UNUSED(scene_framenr), float val)
|
2012-01-26 09:29:49 +00:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
ViewAllUserData *data = (ViewAllUserData *) userdata;
|
|
|
|
|
|
|
|
|
|
if (val < data->min)
|
|
|
|
|
data->min = val;
|
2012-01-26 09:29:49 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
if (val > data->max)
|
|
|
|
|
data->max = val;
|
2012-01-26 09:29:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int view_all_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
|
|
|
|
View2D *v2d = &ar->v2d;
|
|
|
|
|
ViewAllUserData userdata;
|
|
|
|
|
float extra;
|
|
|
|
|
|
|
|
|
|
userdata.max = -FLT_MAX;
|
|
|
|
|
userdata.min = FLT_MAX;
|
|
|
|
|
|
2013-10-15 15:21:28 +00:00
|
|
|
clip_graph_tracking_values_iterate(sc,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
|
|
|
|
|
(sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
|
|
|
|
|
&userdata, view_all_cb, NULL, NULL);
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
/* set extents of view to start/end frames */
|
2012-03-25 23:19:21 +00:00
|
|
|
v2d->cur.xmin = (float) SFRA;
|
|
|
|
|
v2d->cur.xmax = (float) EFRA;
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
if (userdata.min < userdata.max) {
|
|
|
|
|
v2d->cur.ymin = userdata.min;
|
|
|
|
|
v2d->cur.ymax = userdata.max;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
v2d->cur.ymin = -10;
|
|
|
|
|
v2d->cur.ymax = 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we need an extra "buffer" factor on either side so that the endpoints are visible */
|
2012-09-15 11:48:20 +00:00
|
|
|
extra = 0.01f * BLI_rctf_size_x(&v2d->cur);
|
2012-01-26 09:29:49 +00:00
|
|
|
v2d->cur.xmin -= extra;
|
|
|
|
|
v2d->cur.xmax += extra;
|
|
|
|
|
|
2012-09-15 11:48:20 +00:00
|
|
|
extra = 0.01f * BLI_rctf_size_y(&v2d->cur);
|
2012-01-26 09:29:49 +00:00
|
|
|
v2d->cur.ymin -= extra;
|
|
|
|
|
v2d->cur.ymax += extra;
|
|
|
|
|
|
|
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_view_all(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "View All";
|
|
|
|
|
ot->description = "View all curves in editor";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_view_all";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = view_all_exec;
|
|
|
|
|
ot->poll = ED_space_clip_graph_poll;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************** jump to current frame operator ********************/
|
|
|
|
|
|
2012-01-26 11:49:38 +00:00
|
|
|
void ED_clip_graph_center_current_frame(Scene *scene, ARegion *ar)
|
2012-01-26 09:29:49 +00:00
|
|
|
{
|
|
|
|
|
View2D *v2d = &ar->v2d;
|
2012-09-15 11:48:20 +00:00
|
|
|
float extra = BLI_rctf_size_x(&v2d->cur) / 2.0f;
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
/* set extents of view to start/end frames */
|
|
|
|
|
v2d->cur.xmin = (float)CFRA - extra;
|
|
|
|
|
v2d->cur.xmax = (float)CFRA + extra;
|
2012-01-26 11:49:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int center_current_frame_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
ARegion *ar = CTX_wm_region(C);
|
|
|
|
|
|
|
|
|
|
ED_clip_graph_center_current_frame(scene, ar);
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
ED_region_tag_redraw(ar);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2012-01-26 11:49:38 +00:00
|
|
|
void CLIP_OT_graph_center_current_frame(wmOperatorType *ot)
|
2012-01-26 09:29:49 +00:00
|
|
|
{
|
|
|
|
|
/* identifiers */
|
2012-01-26 11:49:38 +00:00
|
|
|
ot->name = "Center Current Frame";
|
|
|
|
|
ot->description = "Scroll view so current frame would be centered";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_center_current_frame";
|
2012-01-26 09:29:49 +00:00
|
|
|
|
|
|
|
|
/* api callbacks */
|
2012-01-26 11:49:38 +00:00
|
|
|
ot->exec = center_current_frame_exec;
|
2012-01-26 09:29:49 +00:00
|
|
|
ot->poll = ED_space_clip_graph_poll;
|
|
|
|
|
}
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
/********************** disable markers operator *********************/
|
|
|
|
|
|
|
|
|
|
static int graph_disable_markers_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
SpaceClip *sc = CTX_wm_space_clip(C);
|
2012-06-19 14:26:29 +00:00
|
|
|
MovieClip *clip = ED_space_clip_get_clip(sc);
|
2012-03-08 17:06:40 +00:00
|
|
|
MovieTracking *tracking = &clip->tracking;
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
|
2012-03-08 17:06:40 +00:00
|
|
|
MovieTrackingMarker *marker;
|
|
|
|
|
int action = RNA_enum_get(op->ptr, "action");
|
|
|
|
|
int a;
|
|
|
|
|
|
|
|
|
|
if (!act_track || (act_track->flag & TRACK_LOCKED))
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
|
|
for (a = 0; a < act_track->markersnr; a++) {
|
|
|
|
|
marker = &act_track->markers[a];
|
|
|
|
|
|
|
|
|
|
if (marker->flag & MARKER_GRAPH_SEL) {
|
2012-05-03 23:47:39 +00:00
|
|
|
if (action == 0)
|
2012-03-08 17:06:40 +00:00
|
|
|
marker->flag |= MARKER_DISABLED;
|
2012-05-03 23:47:39 +00:00
|
|
|
else if (action == 1)
|
2012-03-08 17:06:40 +00:00
|
|
|
marker->flag &= ~MARKER_DISABLED;
|
|
|
|
|
else
|
|
|
|
|
marker->flag ^= MARKER_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-08 10:14:53 +02:00
|
|
|
DEG_id_tag_update(&clip->id, 0);
|
2012-03-08 17:06:40 +00:00
|
|
|
|
2012-05-07 08:53:59 +00:00
|
|
|
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CLIP_OT_graph_disable_markers(wmOperatorType *ot)
|
|
|
|
|
{
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem actions_items[] = {
|
2012-06-10 19:59:02 +00:00
|
|
|
{0, "DISABLE", 0, "Disable", "Disable selected markers"},
|
|
|
|
|
{1, "ENABLE", 0, "Enable", "Enable selected markers"},
|
|
|
|
|
{2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"},
|
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2012-03-08 17:06:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* identifiers */
|
|
|
|
|
ot->name = "Disable Markers";
|
|
|
|
|
ot->description = "Disable/enable selected markers";
|
|
|
|
|
ot->idname = "CLIP_OT_graph_disable_markers";
|
|
|
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
|
ot->exec = graph_disable_markers_exec;
|
|
|
|
|
ot->poll = ED_space_clip_graph_poll;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
2012-05-07 08:53:59 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2012-03-08 17:06:40 +00:00
|
|
|
|
|
|
|
|
/* properties */
|
|
|
|
|
RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Disable action to execute");
|
|
|
|
|
}
|