Blender V5.0
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
8
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_callocN<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
174 wmOperator *op,
175 const wmEvent *event)
176{
178
179 if (slidedata) {
182 MovieTracking *tracking = &clip->tracking;
183 MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
184
185 tracking_object->active_plane_track = slidedata->plane_track;
186 tracking_object->active_track = nullptr;
187
188 op->customdata = slidedata;
189
192
194
196 }
197
199}
200
202{
203 copy_v2_v2(data->corner, data->old_corner);
204}
205
210
217
219{
223 float dx, dy, mdelta[2];
224 int next_corner_index, prev_corner_index, diag_corner_index;
225 const float *next_corner, *prev_corner, *diag_corner;
226 float next_edge[2], prev_edge[2], next_diag_edge[2], prev_diag_edge[2];
227
228 switch (event->type) {
229 case EVT_LEFTCTRLKEY:
230 case EVT_RIGHTCTRLKEY:
231 case EVT_LEFTSHIFTKEY:
234 data->accurate = event->val == KM_PRESS;
235 }
237 case MOUSEMOVE:
238 mdelta[0] = event->mval[0] - data->previous_mval[0];
239 mdelta[1] = event->mval[1] - data->previous_mval[1];
240
241 dx = mdelta[0] / data->width / sc->zoom;
242 dy = mdelta[1] / data->height / sc->zoom;
243
244 if (data->accurate) {
245 dx /= 5.0f;
246 dy /= 5.0f;
247 }
248
249 data->corner[0] = data->previous_corner[0] + dx;
250 data->corner[1] = data->previous_corner[1] + dy;
251
252 /*
253 * prev_edge
254 * (Corner 3, current) <----------------------- (Corner 2, previous)
255 * | ^
256 * | |
257 * | |
258 * | |
259 * next_edge | | next_diag_edge
260 * | |
261 * | |
262 * | |
263 * v |
264 * (Corner 0, next) -----------------------> (Corner 1, diagonal)
265 * prev_diag_edge
266 */
267
268 next_corner_index = (data->corner_index + 1) % 4;
269 prev_corner_index = (data->corner_index + 3) % 4;
270 diag_corner_index = (data->corner_index + 2) % 4;
271
272 next_corner = data->plane_marker->corners[next_corner_index];
273 prev_corner = data->plane_marker->corners[prev_corner_index];
274 diag_corner = data->plane_marker->corners[diag_corner_index];
275
276 sub_v2_v2v2(next_edge, next_corner, data->corner);
277 sub_v2_v2v2(prev_edge, data->corner, prev_corner);
278 sub_v2_v2v2(next_diag_edge, prev_corner, diag_corner);
279 sub_v2_v2v2(prev_diag_edge, diag_corner, next_corner);
280
281 if (cross_v2v2(prev_edge, next_edge) < 0.0f) {
282 closest_to_line_v2(data->corner, data->corner, prev_corner, next_corner);
283 }
284
285 if (cross_v2v2(next_diag_edge, prev_edge) < 0.0f) {
286 closest_to_line_v2(data->corner, data->corner, prev_corner, diag_corner);
287 }
288
289 if (cross_v2v2(next_edge, prev_diag_edge) < 0.0f) {
290 closest_to_line_v2(data->corner, data->corner, next_corner, diag_corner);
291 }
292
293 data->previous_mval[0] = event->mval[0];
294 data->previous_mval[1] = event->mval[1];
295 copy_v2_v2(data->previous_corner, data->corner);
296
299
300 break;
301
302 case LEFTMOUSE:
303 case RIGHTMOUSE:
304 if (event->type == data->launch_event && event->val == KM_RELEASE) {
305 /* Marker is now keyframed. */
306 data->plane_marker->flag &= ~PLANE_MARKER_TRACKED;
307
309
311
313
316
317 return OPERATOR_FINISHED;
318 }
319
320 break;
321
322 case EVT_ESCKEY:
324
326
328
330
331 return OPERATOR_CANCELLED;
332 default: {
333 break;
334 }
335 }
336
338}
339
341{
342 /* identifiers */
343 ot->name = "Slide Plane Marker";
344 ot->description = "Slide plane marker areas";
345 ot->idname = "CLIP_OT_slide_plane_marker";
346
347 /* API callbacks. */
351
352 /* flags */
354}
SpaceClip * CTX_wm_space_clip(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
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:1118
@ PLANE_MARKER_TRACKED
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ 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.
#define C
Definition RandGen.cpp:29
#define NC_GEOM
Definition WM_types.hh:393
@ KM_PRESS
Definition WM_types.hh:311
@ KM_RELEASE
Definition WM_types.hh:312
#define NC_MOVIECLIP
Definition WM_types.hh:397
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_GRAB_CURSOR_XY
Definition WM_types.hh:188
@ OPTYPE_REGISTER
Definition WM_types.hh:180
#define NA_EDITED
Definition WM_types.hh:584
#define ND_SELECT
Definition WM_types.hh:508
BMesh const char void * data
#define SELECT
CCL_NAMESPACE_BEGIN struct Options options
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
struct MovieTracking tracking
MovieTrackingPlaneTrack * active_plane_track
MovieTrackingTrack * active_track
MovieTrackingPlaneTrack * plane_track
MovieTrackingPlaneTrack * plane_track
MovieTrackingPlaneMarker * plane_marker
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
int mval[2]
Definition WM_types.hh:763
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 MovieTrackingPlaneTrack * tracking_plane_marker_check_slide(bContext *C, const wmEvent *event, int *r_corner)
static void slide_plane_marker_update_homographies(SpaceClip *sc, SlidePlaneMarkerData *data)
static wmOperatorStatus slide_plane_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void CLIP_OT_slide_plane_marker(wmOperatorType *ot)
static wmOperatorStatus 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 wmOperatorStatus slide_plane_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
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:4237