Blender  V3.3
tracking_ops_plane.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2011 Blender Foundation. All rights reserved. */
3 
8 #include "MEM_guardedalloc.h"
9 
10 #include "DNA_screen_types.h"
11 #include "DNA_space_types.h"
12 
13 #include "BLI_math.h"
14 #include "BLI_utildefines.h"
15 
16 #include "BKE_context.h"
17 #include "BKE_report.h"
18 #include "BKE_tracking.h"
19 
20 #include "DEG_depsgraph.h"
21 
22 #include "WM_api.h"
23 #include "WM_types.h"
24 
25 #include "ED_clip.h"
26 
27 #include "clip_intern.h"
28 #include "tracking_ops_intern.h"
29 
30 /********************** Create plane track operator *********************/
31 
33 {
36  MovieTracking *tracking = &clip->tracking;
37  MovieTrackingPlaneTrack *plane_track;
38  ListBase *tracks_base = BKE_tracking_get_active_tracks(tracking);
39  ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
40  int framenr = ED_space_clip_get_clip_frame_number(sc);
41 
42  plane_track = BKE_tracking_plane_track_add(tracking, plane_tracks_base, tracks_base, framenr);
43 
44  if (plane_track == NULL) {
45  BKE_report(op->reports, RPT_ERROR, "Need at least 4 selected point tracks to create a plane");
46  return OPERATOR_CANCELLED;
47  }
48 
50 
51  plane_track->flag |= SELECT;
52  clip->tracking.act_track = NULL;
53  clip->tracking.act_plane_track = plane_track;
54 
55  /* Compute homoraphies and apply them on marker's corner, so we've got
56  * quite nice motion from the very beginning.
57  */
59 
62 
63  return OPERATOR_FINISHED;
64 }
65 
67 {
68  /* identifiers */
69  ot->name = "Create Plane Track";
70  ot->description = "Create new plane track out of selected point tracks";
71  ot->idname = "CLIP_OT_create_plane_track";
72 
73  /* api callbacks */
76 
77  /* flags */
79 }
80 
81 /********************** Slide plane marker corner operator *********************/
82 
83 typedef struct SlidePlaneMarkerData {
87  int width, height;
89  float *corner;
90  int previous_mval[2];
91  float previous_corner[2];
92  float old_corner[2];
93  bool accurate;
95 
96 static float mouse_to_plane_slide_zone_distance_squared(const float co[2],
97  const float slide_zone[2],
98  int width,
99  int height)
100 {
101  const float pixel_co[2] = {co[0] * width, co[1] * height},
102  pixel_slide_zone[2] = {slide_zone[0] * width, slide_zone[1] * height};
103  return square_f(pixel_co[0] - pixel_slide_zone[0]) + square_f(pixel_co[1] - pixel_slide_zone[1]);
104 }
105 
107  const wmEvent *event,
108  int *r_corner)
109 {
110  const float distance_clip_squared = 12.0f * 12.0f;
112  ARegion *region = CTX_wm_region(C);
113  MovieClip *clip = ED_space_clip_get_clip(sc);
114  MovieTracking *tracking = &clip->tracking;
115  int width, height;
116  float co[2];
117  ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
118  int framenr = ED_space_clip_get_clip_frame_number(sc);
119 
121  if (width == 0 || height == 0) {
122  return NULL;
123  }
124 
125  ED_clip_mouse_pos(sc, region, event->mval, co);
126 
127  float min_distance_squared = FLT_MAX;
128  int min_corner = -1;
129  MovieTrackingPlaneTrack *min_plane_track = NULL;
130  for (MovieTrackingPlaneTrack *plane_track = plane_tracks_base->first; plane_track != NULL;
131  plane_track = plane_track->next) {
132  if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
133  MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
134  for (int i = 0; i < 4; i++) {
136  co, plane_marker->corners[i], width, height);
137 
138  if (distance_squared < min_distance_squared) {
139  min_distance_squared = distance_squared;
140  min_corner = i;
141  min_plane_track = plane_track;
142  }
143  }
144  }
145  }
146 
147  if (min_distance_squared < distance_clip_squared / sc->zoom) {
148  if (r_corner != NULL) {
149  *r_corner = min_corner;
150  }
151  return min_plane_track;
152  }
153 
154  return NULL;
155 }
156 
157 static void *slide_plane_marker_customdata(bContext *C, const wmEvent *event)
158 {
160  ARegion *region = CTX_wm_region(C);
161  MovieTrackingPlaneTrack *plane_track;
162  int width, height;
163  float co[2];
164  SlidePlaneMarkerData *customdata = NULL;
165  int framenr = ED_space_clip_get_clip_frame_number(sc);
166  int corner;
167 
169  if (width == 0 || height == 0) {
170  return NULL;
171  }
172 
173  ED_clip_mouse_pos(sc, region, event->mval, co);
174 
175  plane_track = tracking_plane_marker_check_slide(C, event, &corner);
176  if (plane_track) {
177  MovieTrackingPlaneMarker *plane_marker;
178 
179  customdata = MEM_callocN(sizeof(SlidePlaneMarkerData), "slide plane marker data");
180 
182 
183  plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
184 
185  customdata->plane_track = plane_track;
186  customdata->plane_marker = plane_marker;
187  customdata->width = width;
188  customdata->height = height;
189 
190  customdata->previous_mval[0] = event->mval[0];
191  customdata->previous_mval[1] = event->mval[1];
192 
193  customdata->corner_index = corner;
194  customdata->corner = plane_marker->corners[corner];
195 
196  copy_v2_v2(customdata->previous_corner, customdata->corner);
197  copy_v2_v2(customdata->old_corner, customdata->corner);
198  }
199 
200  return customdata;
201 }
202 
203 static int slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
204 {
206 
207  if (slidedata) {
209  MovieClip *clip = ED_space_clip_get_clip(sc);
210  MovieTracking *tracking = &clip->tracking;
211 
212  tracking->act_plane_track = slidedata->plane_track;
213  tracking->act_track = NULL;
214 
215  op->customdata = slidedata;
216 
219 
221 
222  return OPERATOR_RUNNING_MODAL;
223  }
224 
225  return OPERATOR_PASS_THROUGH;
226 }
227 
229 {
230  copy_v2_v2(data->corner, data->old_corner);
231 }
232 
234 {
235  MEM_freeN(data);
236 }
237 
239 {
240  int framenr = ED_space_clip_get_clip_frame_number(sc);
241 
243 }
244 
245 static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
246 {
248  MovieClip *clip = ED_space_clip_get_clip(sc);
250  float dx, dy, mdelta[2];
251  int next_corner_index, prev_corner_index, diag_corner_index;
252  const float *next_corner, *prev_corner, *diag_corner;
253  float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2];
254 
255  switch (event->type) {
256  case EVT_LEFTCTRLKEY:
257  case EVT_RIGHTCTRLKEY:
258  case EVT_LEFTSHIFTKEY:
259  case EVT_RIGHTSHIFTKEY:
261  data->accurate = event->val == KM_PRESS;
262  }
264  case MOUSEMOVE:
265  mdelta[0] = event->mval[0] - data->previous_mval[0];
266  mdelta[1] = event->mval[1] - data->previous_mval[1];
267 
268  dx = mdelta[0] / data->width / sc->zoom;
269  dy = mdelta[1] / data->height / sc->zoom;
270 
271  if (data->accurate) {
272  dx /= 5.0f;
273  dy /= 5.0f;
274  }
275 
276  data->corner[0] = data->previous_corner[0] + dx;
277  data->corner[1] = data->previous_corner[1] + dy;
278 
279  /*
280  * prev_edge
281  * (Corner 3, current) <----------------------- (Corner 2, previous)
282  * | ^
283  * | |
284  * | |
285  * | |
286  * next_edge | | next_diag_edge
287  * | |
288  * | |
289  * | |
290  * v |
291  * (Corner 0, next) -----------------------> (Corner 1, diagonal)
292  * prev_diag_edge
293  */
294 
295  next_corner_index = (data->corner_index + 1) % 4;
296  prev_corner_index = (data->corner_index + 3) % 4;
297  diag_corner_index = (data->corner_index + 2) % 4;
298 
299  next_corner = data->plane_marker->corners[next_corner_index];
300  prev_corner = data->plane_marker->corners[prev_corner_index];
301  diag_corner = data->plane_marker->corners[diag_corner_index];
302 
303  sub_v2_v2v2(next_edge, next_corner, data->corner);
304  sub_v2_v2v2(prev_edge, data->corner, prev_corner);
305  sub_v2_v2v2(next_diag_edge, prev_corner, diag_corner);
306  sub_v2_v2v2(prev_diag_edge, diag_corner, next_corner);
307 
308  if (cross_v2v2(prev_edge, next_edge) < 0.0f) {
309  closest_to_line_v2(data->corner, data->corner, prev_corner, next_corner);
310  }
311 
312  if (cross_v2v2(next_diag_edge, prev_edge) < 0.0f) {
313  closest_to_line_v2(data->corner, data->corner, prev_corner, diag_corner);
314  }
315 
316  if (cross_v2v2(next_edge, prev_diag_edge) < 0.0f) {
317  closest_to_line_v2(data->corner, data->corner, next_corner, diag_corner);
318  }
319 
320  data->previous_mval[0] = event->mval[0];
321  data->previous_mval[1] = event->mval[1];
322  copy_v2_v2(data->previous_corner, data->corner);
323 
326 
327  break;
328 
329  case LEFTMOUSE:
330  case RIGHTMOUSE:
331  if (event->type == data->launch_event && event->val == KM_RELEASE) {
332  /* Marker is now keyframed. */
333  data->plane_marker->flag &= ~PLANE_MARKER_TRACKED;
334 
336 
338 
340 
343 
344  return OPERATOR_FINISHED;
345  }
346 
347  break;
348 
349  case EVT_ESCKEY:
351 
353 
355 
357 
358  return OPERATOR_CANCELLED;
359  }
360 
361  return OPERATOR_RUNNING_MODAL;
362 }
363 
365 {
366  /* identifiers */
367  ot->name = "Slide Plane Marker";
368  ot->description = "Slide plane marker areas";
369  ot->idname = "CLIP_OT_slide_plane_marker";
370 
371  /* api callbacks */
375 
376  /* flags */
378 }
struct SpaceClip * CTX_wm_space_clip(const bContext *C)
Definition: context.c:923
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:1950
struct ListBase * BKE_tracking_get_active_tracks(struct MovieTracking *tracking)
Definition: tracking.c:346
#define PLANE_TRACK_VIEW_SELECTED(plane_track)
Definition: BKE_tracking.h:837
struct MovieTrackingPlaneTrack * BKE_tracking_plane_track_add(struct MovieTracking *tracking, struct ListBase *plane_tracks_base, struct ListBase *tracks, int framenr)
Definition: tracking.c:1611
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition: tracking.c:1890
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.c:1289
struct ListBase * BKE_tracking_get_active_plane_tracks(struct MovieTracking *tracking)
Definition: tracking.c:357
#define ATTR_FALLTHROUGH
MINLINE float square_f(float a)
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
Definition: math_geom.c:3183
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(struct ID *id, int flag)
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:834
@ PLANE_MARKER_TRACKED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
int ED_space_clip_get_clip_frame_number(struct SpaceClip *sc)
Definition: clip_editor.c:231
void ED_space_clip_get_size(struct SpaceClip *sc, int *width, int *height)
Definition: clip_editor.c:146
void ED_clip_mouse_pos(struct SpaceClip *sc, struct ARegion *region, const int mval[2], float co[2])
Definition: clip_editor.c:541
bool ED_space_clip_tracking_poll(struct bContext *C)
Definition: clip_editor.c:83
struct MovieClip * ED_space_clip_get_clip(struct SpaceClip *sc)
Definition: clip_editor.c:570
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
@ KM_PRESS
Definition: WM_types.h:267
@ KM_RELEASE
Definition: WM_types.h:268
@ OPTYPE_BLOCKING
Definition: WM_types.h:150
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_GRAB_CURSOR_XY
Definition: WM_types.h:154
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define NC_GEOM
Definition: WM_types.h:343
#define NC_MOVIECLIP
Definition: WM_types.h:347
#define NA_EDITED
Definition: WM_types.h:523
#define ND_SELECT
Definition: WM_types.h:455
#define SELECT
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
T distance_squared(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
void * first
Definition: DNA_listBase.h:31
struct MovieTracking tracking
MovieTrackingPlaneTrack * act_plane_track
MovieTrackingTrack * act_track
MovieTrackingPlaneTrack * plane_track
MovieTrackingPlaneMarker * plane_marker
short val
Definition: WM_types.h:680
int mval[2]
Definition: WM_types.h:684
short type
Definition: WM_types.h:678
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:935
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
const char * description
Definition: WM_types.h:893
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
struct ReportList * reports
void clip_tracking_hide_cursor(struct bContext *C)
void clip_tracking_show_cursor(struct bContext *C)
void CLIP_OT_create_plane_track(wmOperatorType *ot)
static int slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void * slide_plane_marker_customdata(bContext *C, const wmEvent *event)
static MovieTrackingPlaneTrack * tracking_plane_marker_check_slide(bContext *C, const wmEvent *event, int *r_corner)
static float mouse_to_plane_slide_zone_distance_squared(const float co[2], const float slide_zone[2], int width, int height)
struct SlidePlaneMarkerData SlidePlaneMarkerData
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)
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.c:3479