Blender V4.3
tracking_ops_plane.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "MEM_guardedalloc.h"
10
11#include "DNA_screen_types.h"
12#include "DNA_space_types.h"
13
14#include "BLI_math_geom.h"
15#include "BLI_math_vector.h"
16#include "BLI_utildefines.h"
17
18#include "BKE_context.hh"
19#include "BKE_report.hh"
20#include "BKE_tracking.h"
21
22#include "DEG_depsgraph.hh"
23
24#include "WM_api.hh"
25#include "WM_types.hh"
26
27#include "ED_clip.hh"
28
29#include "clip_intern.hh"
31
32/********************** Create plane track operator *********************/
33
35{
38 MovieTracking *tracking = &clip->tracking;
39 MovieTrackingPlaneTrack *plane_track;
40 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
42
43 plane_track = BKE_tracking_plane_track_add(
44 tracking, &tracking_object->plane_tracks, &tracking_object->tracks, framenr);
45
46 if (plane_track == nullptr) {
47 BKE_report(op->reports, RPT_ERROR, "Need at least 4 selected point tracks to create a plane");
48 return OPERATOR_CANCELLED;
49 }
50
52
53 plane_track->flag |= SELECT;
54 tracking_object->active_track = nullptr;
55 tracking_object->active_plane_track = plane_track;
56
57 /* Compute homoraphies and apply them on marker's corner, so we've got
58 * quite nice motion from the very beginning.
59 */
61
64
65 return OPERATOR_FINISHED;
66}
67
69{
70 /* identifiers */
71 ot->name = "Create Plane Track";
72 ot->description = "Create new plane track out of selected point tracks";
73 ot->idname = "CLIP_OT_create_plane_track";
74
75 /* api callbacks */
78
79 /* flags */
81}
82
83/********************** Slide plane marker corner operator *********************/
84
97
99 const wmEvent *event,
100 int *r_corner)
101{
102 SpaceClip *space_clip = CTX_wm_space_clip(C);
103 ARegion *region = CTX_wm_region(C);
104
105 float co[2];
106 ED_clip_mouse_pos(space_clip, region, event->mval, co);
107
109 options.selected_only = true;
110 options.unlocked_only = true;
111 options.enabled_only = true;
112 const PlaneTrackPick track_pick = ed_tracking_pick_plane_track(&options, C, co);
113
114 if (ed_tracking_plane_track_pick_empty(&track_pick) ||
116 {
117 return nullptr;
118 }
119
120 if (r_corner != nullptr) {
121 *r_corner = track_pick.corner_index;
122 }
123
124 return track_pick.plane_track;
125}
126
128{
130 ARegion *region = CTX_wm_region(C);
131 MovieTrackingPlaneTrack *plane_track;
132 int width, height;
133 float co[2];
134 SlidePlaneMarkerData *customdata = nullptr;
135 int framenr = ED_space_clip_get_clip_frame_number(sc);
136 int corner;
137
138 ED_space_clip_get_size(sc, &width, &height);
139 if (width == 0 || height == 0) {
140 return nullptr;
141 }
142
143 ED_clip_mouse_pos(sc, region, event->mval, co);
144
145 plane_track = tracking_plane_marker_check_slide(C, event, &corner);
146 if (plane_track) {
147 MovieTrackingPlaneMarker *plane_marker;
148
149 customdata = MEM_cnew<SlidePlaneMarkerData>("slide plane marker data");
150
152
153 plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
154
155 customdata->plane_track = plane_track;
156 customdata->plane_marker = plane_marker;
157 customdata->width = width;
158 customdata->height = height;
159
160 customdata->previous_mval[0] = event->mval[0];
161 customdata->previous_mval[1] = event->mval[1];
162
163 customdata->corner_index = corner;
164 customdata->corner = plane_marker->corners[corner];
165
166 copy_v2_v2(customdata->previous_corner, customdata->corner);
167 copy_v2_v2(customdata->old_corner, customdata->corner);
168 }
169
170 return customdata;
171}
172
173static int slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
174{
176
177 if (slidedata) {
180 MovieTracking *tracking = &clip->tracking;
181 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
182
183 tracking_object->active_plane_track = slidedata->plane_track;
184 tracking_object->active_track = nullptr;
185
186 op->customdata = slidedata;
187
190
192
194 }
195
197}
198
200{
201 copy_v2_v2(data->corner, data->old_corner);
202}
203
205{
206 MEM_freeN(data);
207}
208
215
216static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
217{
221 float dx, dy, mdelta[2];
222 int next_corner_index, prev_corner_index, diag_corner_index;
223 const float *next_corner, *prev_corner, *diag_corner;
224 float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2];
225
226 switch (event->type) {
227 case EVT_LEFTCTRLKEY:
228 case EVT_RIGHTCTRLKEY:
229 case EVT_LEFTSHIFTKEY:
232 data->accurate = event->val == KM_PRESS;
233 }
235 case MOUSEMOVE:
236 mdelta[0] = event->mval[0] - data->previous_mval[0];
237 mdelta[1] = event->mval[1] - data->previous_mval[1];
238
239 dx = mdelta[0] / data->width / sc->zoom;
240 dy = mdelta[1] / data->height / sc->zoom;
241
242 if (data->accurate) {
243 dx /= 5.0f;
244 dy /= 5.0f;
245 }
246
247 data->corner[0] = data->previous_corner[0] + dx;
248 data->corner[1] = data->previous_corner[1] + dy;
249
250 /*
251 * prev_edge
252 * (Corner 3, current) <----------------------- (Corner 2, previous)
253 * | ^
254 * | |
255 * | |
256 * | |
257 * next_edge | | next_diag_edge
258 * | |
259 * | |
260 * | |
261 * v |
262 * (Corner 0, next) -----------------------> (Corner 1, diagonal)
263 * prev_diag_edge
264 */
265
266 next_corner_index = (data->corner_index + 1) % 4;
267 prev_corner_index = (data->corner_index + 3) % 4;
268 diag_corner_index = (data->corner_index + 2) % 4;
269
270 next_corner = data->plane_marker->corners[next_corner_index];
271 prev_corner = data->plane_marker->corners[prev_corner_index];
272 diag_corner = data->plane_marker->corners[diag_corner_index];
273
274 sub_v2_v2v2(next_edge, next_corner, data->corner);
275 sub_v2_v2v2(prev_edge, data->corner, prev_corner);
276 sub_v2_v2v2(next_diag_edge, prev_corner, diag_corner);
277 sub_v2_v2v2(prev_diag_edge, diag_corner, next_corner);
278
279 if (cross_v2v2(prev_edge, next_edge) < 0.0f) {
280 closest_to_line_v2(data->corner, data->corner, prev_corner, next_corner);
281 }
282
283 if (cross_v2v2(next_diag_edge, prev_edge) < 0.0f) {
284 closest_to_line_v2(data->corner, data->corner, prev_corner, diag_corner);
285 }
286
287 if (cross_v2v2(next_edge, prev_diag_edge) < 0.0f) {
288 closest_to_line_v2(data->corner, data->corner, next_corner, diag_corner);
289 }
290
291 data->previous_mval[0] = event->mval[0];
292 data->previous_mval[1] = event->mval[1];
293 copy_v2_v2(data->previous_corner, data->corner);
294
297
298 break;
299
300 case LEFTMOUSE:
301 case RIGHTMOUSE:
302 if (event->type == data->launch_event && event->val == KM_RELEASE) {
303 /* Marker is now keyframed. */
304 data->plane_marker->flag &= ~PLANE_MARKER_TRACKED;
305
307
309
311
314
315 return OPERATOR_FINISHED;
316 }
317
318 break;
319
320 case EVT_ESCKEY:
322
324
326
328
329 return OPERATOR_CANCELLED;
330 }
331
333}
334
336{
337 /* identifiers */
338 ot->name = "Slide Plane Marker";
339 ot->description = "Slide plane marker areas";
340 ot->idname = "CLIP_OT_slide_plane_marker";
341
342 /* api callbacks */
346
347 /* flags */
349}
SpaceClip * CTX_wm_space_clip(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:125
struct MovieTrackingPlaneTrack * BKE_tracking_plane_track_add(struct MovieTracking *tracking, struct ListBase *plane_tracks_base, struct ListBase *tracks, int framenr)
Definition tracking.cc:1542
struct MovieTrackingObject * BKE_tracking_object_get_active(const struct MovieTracking *tracking)
void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame)
void BKE_tracking_tracks_deselect_all(struct ListBase *tracksbase)
Definition tracking.cc:1222
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1849
#define ATTR_FALLTHROUGH
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1085
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
MovieClip * ED_space_clip_get_clip(const SpaceClip *sc)
void ED_clip_mouse_pos(const SpaceClip *sc, const ARegion *region, const int mval[2], float r_co[2])
void ED_space_clip_get_size(const SpaceClip *sc, int *r_width, int *r_height)
int ED_space_clip_get_clip_frame_number(const SpaceClip *sc)
bool ED_space_clip_tracking_poll(bContext *C)
Read Guarded memory(de)allocation.
@ OPTYPE_BLOCKING
Definition WM_types.hh:164
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_GRAB_CURSOR_XY
Definition WM_types.hh:168
@ OPTYPE_REGISTER
Definition WM_types.hh:160
#define NC_GEOM
Definition WM_types.hh:360
@ KM_PRESS
Definition WM_types.hh:284
@ KM_RELEASE
Definition WM_types.hh:285
#define NC_MOVIECLIP
Definition WM_types.hh:364
#define NA_EDITED
Definition WM_types.hh:550
#define ND_SELECT
Definition WM_types.hh:474
#define SELECT
CCL_NAMESPACE_BEGIN struct Options options
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
MovieTrackingPlaneTrack * active_plane_track
MovieTrackingTrack * active_track
MovieTrackingPlaneTrack * plane_track
MovieTrackingPlaneTrack * plane_track
MovieTrackingPlaneMarker * plane_marker
short val
Definition WM_types.hh:724
int mval[2]
Definition WM_types.hh:728
short type
Definition WM_types.hh:722
const char * name
Definition WM_types.hh:990
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1042
const char * idname
Definition WM_types.hh:992
int(* modal)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1036
int(* invoke)(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1022
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1006
const char * description
Definition WM_types.hh:996
struct ReportList * reports
PlaneTrackPick ed_tracking_pick_plane_track(const TrackPickOptions *options, struct bContext *C, const float co[2])
BLI_INLINE bool ed_tracking_plane_track_pick_empty(const PlaneTrackPick *pick)
void clip_tracking_hide_cursor(bContext *C)
void clip_tracking_show_cursor(bContext *C)
bool ed_tracking_plane_track_pick_can_slide(const PlaneTrackPick *pick)
BLI_INLINE TrackPickOptions ed_tracking_pick_options_defaults()
void CLIP_OT_create_plane_track(wmOperatorType *ot)
static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
static MovieTrackingPlaneTrack * tracking_plane_marker_check_slide(bContext *C, const wmEvent *event, int *r_corner)
static int slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void slide_plane_marker_update_homographies(SpaceClip *sc, SlidePlaneMarkerData *data)
void CLIP_OT_slide_plane_marker(wmOperatorType *ot)
static int create_plane_track_tracks_exec(bContext *C, wmOperator *op)
static void cancel_mouse_slide_plane_marker(SlidePlaneMarkerData *data)
static void free_slide_plane_marker_data(SlidePlaneMarkerData *data)
static SlidePlaneMarkerData * slide_plane_marker_customdata(bContext *C, const wmEvent *event)
int WM_userdef_event_type_from_keymap_type(int kmitype)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ RIGHTMOUSE
@ EVT_RIGHTCTRLKEY
@ EVT_LEFTCTRLKEY
@ MOUSEMOVE
@ LEFTMOUSE
@ EVT_ESCKEY
@ EVT_RIGHTSHIFTKEY
@ EVT_LEFTSHIFTKEY
wmOperatorType * ot
Definition wm_files.cc:4125