Blender V4.3
transform_convert_tracking.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DNA_space_types.h"
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_math_matrix.h"
14#include "BLI_math_vector.h"
15
16#include "BKE_context.hh"
17#include "BKE_movieclip.h"
19#include "BKE_tracking.h"
20
21#include "ED_clip.hh"
22
23#include "WM_api.hh"
24
25#include "transform.hh"
26#include "transform_convert.hh"
27
29 int mode;
30 int flag;
31
32 /* Tracks transformation from main window. */
33 int area;
34 const float *relative, *loc;
35 float soffset[2], srelative[2];
36 float offset[2];
37
42
45};
46
51
52/* -------------------------------------------------------------------- */
58
61
62 /* NOTE: These pointers will be `nullptr` during counting step.
63 * This means, that the transformation data initialization functions are to increment
64 * `tc->data_len` instead of filling in the transformation data when these pointers are
65 * `nullptr`. For simplicity, check the `current.td` against `nullptr`.
66 * Do not `tc->data_len` when filling in the transformation data. */
67 struct {
72};
73
75 MovieTrackingTrack *track,
76 MovieTrackingMarker *marker,
77 int area,
78 float loc[2],
79 const float rel[2],
80 const float off[2],
81 const float aspect[2])
82{
83 TransData *td = init_context->current.td;
84 TransData2D *td2d = init_context->current.td2d;
85 TransDataTracking *tdt = init_context->current.tdt;
86
87 if (td == nullptr) {
88 init_context->tc->data_len++;
89 return;
90 }
91
92 int anchor = area == TRACK_AREA_POINT && off;
93
94 tdt->flag = marker->flag;
95 tdt->framenr = marker->framenr;
97
98 if (anchor) {
99 td2d->loc[0] = rel[0] * aspect[0]; /* Hold original location. */
100 td2d->loc[1] = rel[1] * aspect[1];
101
102 tdt->loc = loc;
103 td2d->loc2d = loc; /* Current location. */
104 }
105 else {
106 td2d->loc[0] = loc[0] * aspect[0]; /* Hold original location. */
107 td2d->loc[1] = loc[1] * aspect[1];
108
109 td2d->loc2d = loc; /* Current location. */
110 }
111 td2d->loc[2] = 0.0f;
112
113 tdt->relative = rel;
114 tdt->area = area;
115
116 tdt->markersnr = track->markersnr;
117 tdt->markers = track->markers;
118 tdt->track = track;
119
120 if (rel) {
121 if (!anchor) {
122 td2d->loc[0] += rel[0] * aspect[0];
123 td2d->loc[1] += rel[1] * aspect[1];
124 }
125
126 copy_v2_v2(tdt->srelative, rel);
127 }
128
129 if (off) {
130 copy_v2_v2(tdt->soffset, off);
131 }
132
133 td->flag = 0;
134 td->loc = td2d->loc;
135 copy_v3_v3(td->iloc, td->loc);
136
137 // copy_v3_v3(td->center, td->loc);
138 td->flag |= TD_INDIVIDUAL_SCALE;
139 td->center[0] = marker->pos[0] * aspect[0];
140 td->center[1] = marker->pos[1] * aspect[1];
141
142 memset(td->axismtx, 0, sizeof(td->axismtx));
143 td->axismtx[2][2] = 1.0f;
144
145 td->ext = nullptr;
146 td->val = nullptr;
147
148 td->flag |= TD_SELECTED;
149 td->dist = 0.0;
150
151 unit_m3(td->mtx);
152 unit_m3(td->smtx);
153
154 init_context->current.td++;
155 init_context->current.td2d++;
156 init_context->current.tdt++;
157}
158
160 const int framenr,
161 MovieTrackingTrack *track,
162 const float aspect[2])
163{
164 MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
165
167 track,
168 marker,
170 track->offset,
171 marker->pos,
172 track->offset,
173 aspect);
174
175 if (track->flag & SELECT) {
177 init_context, track, marker, TRACK_AREA_POINT, marker->pos, nullptr, nullptr, aspect);
178 }
179
180 if (track->pat_flag & SELECT) {
181 int a;
182
183 for (a = 0; a < 4; a++) {
185 track,
186 marker,
188 marker->pattern_corners[a],
189 marker->pos,
190 nullptr,
191 aspect);
192 }
193 }
194
195 if (track->search_flag & SELECT) {
197 track,
198 marker,
200 marker->search_min,
201 marker->pos,
202 nullptr,
203 aspect);
204
206 track,
207 marker,
209 marker->search_max,
210 marker->pos,
211 nullptr,
212 aspect);
213 }
214
215 if (init_context->current.td != nullptr) {
216 marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
217 }
218}
219
221 const int framenr,
222 MovieTrackingTrack *track,
223 const float aspect[2])
224{
225 if (!TRACK_VIEW_SELECTED(init_context->space_clip, track)) {
226 return;
227 }
228 if (track->flag & TRACK_LOCKED) {
229 return;
230 }
231 trackToTransData(init_context, framenr, track, aspect);
232}
233
235 MovieTrackingPlaneTrack *plane_track,
236 MovieTrackingPlaneMarker *plane_marker,
237 float corner[2],
238 const float aspect[2])
239{
240 TransData *td = init_context->current.td;
241 TransData2D *td2d = init_context->current.td2d;
242 TransDataTracking *tdt = init_context->current.tdt;
243
244 if (td == nullptr) {
245 init_context->tc->data_len++;
246 return;
247 }
248
249 tdt->flag = plane_marker->flag;
250 tdt->framenr = plane_marker->framenr;
252 tdt->plane_track = plane_track;
253
254 td2d->loc[0] = corner[0] * aspect[0]; /* Hold original location. */
255 td2d->loc[1] = corner[1] * aspect[1];
256
257 td2d->loc2d = corner; /* Current location. */
258 td2d->loc[2] = 0.0f;
259
260 td->flag = 0;
261 td->loc = td2d->loc;
262 copy_v3_v3(td->iloc, td->loc);
263 copy_v3_v3(td->center, td->loc);
264
265 memset(td->axismtx, 0, sizeof(td->axismtx));
266 td->axismtx[2][2] = 1.0f;
267
268 td->ext = nullptr;
269 td->val = nullptr;
270
271 td->flag |= TD_SELECTED;
272 td->dist = 0.0;
273
274 unit_m3(td->mtx);
275 unit_m3(td->smtx);
276
277 init_context->current.td++;
278 init_context->current.td2d++;
279 init_context->current.tdt++;
280}
281
283 const int framenr,
284 MovieTrackingPlaneTrack *plane_track,
285 const float aspect[2])
286{
287 MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
288
289 for (int i = 0; i < 4; i++) {
291 init_context, plane_track, plane_marker, plane_marker->corners[i], aspect);
292 }
293
294 if (init_context->current.td != nullptr) {
295 plane_marker->flag &= ~PLANE_MARKER_TRACKED;
296 }
297}
298
300 const int framenr,
301 MovieTrackingPlaneTrack *plane_track,
302 const float aspect[2])
303{
304 if (!PLANE_TRACK_VIEW_SELECTED(plane_track)) {
305 return;
306 }
307 planeTrackToTransData(init_context, framenr, plane_track, aspect);
308}
309
311 TransDataContainer * /*tc*/,
312 TransCustomData *custom_data)
313{
314 if (custom_data->data) {
315 TransDataTracking *tdt = static_cast<TransDataTracking *>(custom_data->data);
316 if (tdt->smarkers) {
317 MEM_freeN(tdt->smarkers);
318 }
319
320 MEM_freeN(tdt);
321 custom_data->data = nullptr;
322 }
323}
324
326{
327 SpaceClip *space_clip = CTX_wm_space_clip(C);
328 MovieClip *clip = ED_space_clip_get_clip(space_clip);
329 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
330 const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
331
333
335 init_context.space_clip = space_clip;
336 init_context.t = t;
337 init_context.tc = tc;
338
339 /* Count required transformation data. */
340
341 tc->data_len = 0;
342
343 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
344 trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
345 }
346
347 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
348 planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
349 }
350
351 if (tc->data_len == 0) {
352 return;
353 }
354
355 tc->data = static_cast<TransData *>(
356 MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData"));
357 tc->data_2d = static_cast<TransData2D *>(
358 MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D"));
360 "TransTracking TransDataTracking");
362
363 init_context.current.td = tc->data;
364 init_context.current.td2d = tc->data_2d;
365 init_context.current.tdt = static_cast<TransDataTracking *>(tc->custom.type.data);
366
367 /* Create actual transformation data. */
368
369 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
370 trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
371 }
372
373 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
374 planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
375 }
376}
377
379{
382 int width, height;
383
385
386 tc->data_len = 0;
387
388 if (!clip) {
389 return;
390 }
391
392 BKE_movieclip_get_size(clip, &sc->user, &width, &height);
393
394 if (width == 0 || height == 0) {
395 return;
396 }
397
399}
400
403/* -------------------------------------------------------------------- */
408{
410 TransDataTracking *tdt_array = static_cast<TransDataTracking *>(tc->custom.type.data);
411
412 int i = 0;
413 while (i < tc->data_len) {
414 TransDataTracking *tdt = &tdt_array[i];
415
417 MovieTrackingTrack *track = tdt->track;
419
420 BLI_assert(marker != nullptr);
421
422 marker->flag = tdt->flag;
423
424 if (track->flag & SELECT) {
425 i++;
426 }
427
428 if (track->pat_flag & SELECT) {
429 i += 4;
430 }
431
432 if (track->search_flag & SELECT) {
433 i += 2;
434 }
435 }
436 else if (tdt->mode == transDataTracking_ModePlaneTracks) {
437 MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
439 tdt->framenr);
440
441 BLI_assert(plane_marker != nullptr);
442
443 plane_marker->flag = tdt->flag;
444 i += 3;
445 }
446
447 i++;
448 }
449}
450
452{
453 TransData *td;
454 TransData2D *td2d;
456 int td_index;
457
458 if (t->state == TRANS_CANCEL) {
460 }
461
463
464 /* Flush to 2d vector from internally used 3d vector. */
465 for (td_index = 0,
466 td = tc->data,
467 td2d = tc->data_2d,
468 tdt = static_cast<TransDataTracking *>(tc->custom.type.data);
469 td_index < tc->data_len;
470 td_index++, td2d++, td++, tdt++)
471 {
473 float loc2d[2];
474
475 if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) {
476 continue;
477 }
478
479 loc2d[0] = td2d->loc[0] / t->aspect[0];
480 loc2d[1] = td2d->loc[1] / t->aspect[1];
481
482 if (t->flag & T_ALT_TRANSFORM) {
483 if (t->mode == TFM_RESIZE) {
484 if (tdt->area != TRACK_AREA_PAT && !(t->state == TRANS_CANCEL)) {
485 continue;
486 }
487 }
488 else if (t->mode == TFM_TRANSLATION) {
489 if (tdt->area == TRACK_AREA_POINT && tdt->relative) {
490 float d[2], d2[2];
491
492 if (!tdt->smarkers) {
493 tdt->smarkers = static_cast<float(*)[2]>(MEM_callocN(
494 sizeof(*tdt->smarkers) * tdt->markersnr, "flushTransTracking markers"));
495 for (int a = 0; a < tdt->markersnr; a++) {
496 copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos);
497 }
498 }
499
500 sub_v2_v2v2(d, loc2d, tdt->soffset);
501 sub_v2_v2(d, tdt->srelative);
502
503 sub_v2_v2v2(d2, loc2d, tdt->srelative);
504
505 for (int a = 0; a < tdt->markersnr; a++) {
506 add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
507 }
508
509 negate_v2_v2(td2d->loc2d, d);
510 }
511 }
512 }
513
514 if (tdt->area != TRACK_AREA_POINT || tdt->relative == nullptr) {
515 td2d->loc2d[0] = loc2d[0];
516 td2d->loc2d[1] = loc2d[1];
517
518 if (tdt->relative) {
519 sub_v2_v2(td2d->loc2d, tdt->relative);
520 }
521 }
522 }
523 else if (tdt->mode == transDataTracking_ModePlaneTracks) {
524 td2d->loc2d[0] = td2d->loc[0] / t->aspect[0];
525 td2d->loc2d[1] = td2d->loc[1] / t->aspect[1];
526 }
527 }
528}
529
531{
532 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
533
536 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
537 const int framenr = ED_space_clip_get_clip_frame_number(sc);
538
540
541 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
542 if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
543 MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
544
545 if (t->mode == TFM_TRANSLATION) {
548 }
551 }
552 }
553 else if (t->mode == TFM_RESIZE) {
556 }
559 }
560 }
561 else if (t->mode == TFM_ROTATION) {
564 }
565 }
566 }
567 }
568
569 DEG_id_tag_update(&clip->id, 0);
570 }
571}
572
575/* -------------------------------------------------------------------- */
580{
581 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
583 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
584 const int framenr = ED_space_clip_get_clip_frame_number(sc);
585 /* Update coordinates of modified plane tracks. */
586 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
587 bool do_update = false;
588 if (plane_track->flag & PLANE_TRACK_HIDDEN) {
589 continue;
590 }
591 do_update |= PLANE_TRACK_VIEW_SELECTED(plane_track) != 0;
592 if (do_update == false) {
593 if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
594 int i;
595 for (i = 0; i < plane_track->point_tracksnr; i++) {
596 MovieTrackingTrack *track = plane_track->point_tracks[i];
597 if (TRACK_VIEW_SELECTED(sc, track)) {
598 do_update = true;
599 break;
600 }
601 }
602 }
603 }
604 if (do_update) {
606 }
607 }
608 if (t->scene->nodetree != nullptr) {
609 /* Tracks can be used for stabilization nodes,
610 * flush update for such nodes.
611 */
612 if (t->context != nullptr) {
613 Main *bmain = CTX_data_main(C);
614 BKE_ntree_update_tag_id_changed(bmain, &clip->id);
615 BKE_ntree_update_main(bmain, nullptr);
617 }
618 }
619}
620
624 /*flags*/ (T_POINTS | T_2D_EDIT),
625 /*create_trans_data*/ createTransTrackingData,
626 /*recalc_data*/ recalcData_tracking,
627 /*special_aftertrans_update*/ special_aftertrans_update__movieclip,
628};
Main * CTX_data_main(const bContext *C)
SpaceClip * CTX_wm_space_clip(const bContext *C)
void BKE_movieclip_get_size(struct MovieClip *clip, const struct MovieClipUser *user, int *r_width, int *r_height)
void BKE_ntree_update_main(Main *bmain, NodeTreeUpdateExtraParams *params)
void BKE_ntree_update_tag_id_changed(Main *bmain, ID *id)
void BKE_tracking_marker_clamp_pattern_position(struct MovieTrackingMarker *marker)
Definition tracking.cc:1308
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1837
struct MovieTrackingMarker * BKE_tracking_marker_ensure(struct MovieTrackingTrack *track, int framenr)
Definition tracking.cc:1402
#define PLANE_TRACK_VIEW_SELECTED(plane_track)
@ TRACK_AREA_POINT
@ TRACK_AREA_PAT
@ TRACK_AREA_SEARCH
struct MovieTrackingMarker * BKE_tracking_marker_get(struct MovieTrackingTrack *track, int framenr)
Definition tracking.cc:1358
void BKE_tracking_marker_clamp_search_position(struct MovieTrackingMarker *marker)
Definition tracking.cc:1338
struct MovieTrackingObject * BKE_tracking_object_get_active(const struct MovieTracking *tracking)
struct MovieTrackingMarker * BKE_tracking_marker_get_exact(struct MovieTrackingTrack *track, int framenr)
Definition tracking.cc:1391
void BKE_tracking_track_plane_from_existing_motion(struct MovieTrackingPlaneTrack *plane_track, int start_frame)
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_ensure(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1849
void BKE_tracking_marker_clamp_search_size(struct MovieTrackingMarker *marker)
Definition tracking.cc:1327
#define TRACK_VIEW_SELECTED(sc, track)
#define TRACK_AREA_SELECTED(track, area)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
void unit_m3(float m[3][3])
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v2_v2(float r[2], const float a[2])
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
void DEG_id_tag_update(ID *id, unsigned int flags)
@ TRACK_LOCKED
@ PLANE_TRACK_HIDDEN
@ PLANE_TRACK_AUTOKEY
@ MARKER_TRACKED
@ MARKER_DISABLED
MovieClip * ED_space_clip_get_clip(const SpaceClip *sc)
bool ED_space_clip_check_show_trackedit(const SpaceClip *sc)
int ED_space_clip_get_clip_frame_number(const SpaceClip *sc)
@ TFM_RESIZE
@ TFM_ROTATION
@ TFM_TRANSLATION
Read Guarded memory(de)allocation.
#define NC_SCENE
Definition WM_types.hh:345
#define ND_NODES
Definition WM_types.hh:403
#define SELECT
draw_view in_light_buf[] float
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void *(* MEM_callocN)(size_t len, const char *str)
Definition mallocn.cc:42
static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, const float space_mat[4][4], Vector< Object * > &instance_stack, Vector< short > &dupli_gen_type_stack)
void * first
MovieTrackingMarker * markers
struct bNodeTree * nodetree
ListBase spacedata
struct MovieClipUser user
TransCustomData type
Definition transform.hh:425
void(* free_cb)(TransInfo *, TransDataContainer *tc, TransCustomData *custom_data)
Definition transform.hh:409
TransCustomDataContainer custom
Definition transform.hh:501
TransData * data
Definition transform.hh:445
TransData2D * data_2d
Definition transform.hh:449
MovieTrackingMarker * markers
MovieTrackingPlaneTrack * plane_track
float smtx[3][3]
float axismtx[3][3]
float mtx[3][3]
TransDataExtension * ext
eTfmMode mode
Definition transform.hh:517
eTState state
Definition transform.hh:527
float aspect[3]
Definition transform.hh:553
Scene * scene
Definition transform.hh:654
eTFlag flag
Definition transform.hh:523
bContext * context
Definition transform.hh:649
ScrArea * area
Definition transform.hh:651
struct TransformInitContext::@570 current
@ T_ALT_TRANSFORM
Definition transform.hh:126
@ T_2D_EDIT
Definition transform.hh:104
@ T_POINTS
Definition transform.hh:93
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:851
@ TRANS_CANCEL
Definition transform.hh:210
conversion and adaptation of different datablocks to a common struct.
static void cancelTransTracking(TransInfo *t)
static void recalcData_tracking(TransInfo *t)
static void planeMarkerToTransDataInit(TransformInitContext *init_context, MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker, float corner[2], const float aspect[2])
static void flushTransTracking(TransInfo *t)
static void planeTrackToTransDataIfNeeded(TransformInitContext *init_context, const int framenr, MovieTrackingPlaneTrack *plane_track, const float aspect[2])
static void planeTrackToTransData(TransformInitContext *init_context, const int framenr, MovieTrackingPlaneTrack *plane_track, const float aspect[2])
static void trackToTransDataIfNeeded(TransformInitContext *init_context, const int framenr, MovieTrackingTrack *track, const float aspect[2])
static void markerToTransDataInit(TransformInitContext *init_context, MovieTrackingTrack *track, MovieTrackingMarker *marker, int area, float loc[2], const float rel[2], const float off[2], const float aspect[2])
static void createTransTrackingTracksData(bContext *C, TransInfo *t)
TransConvertTypeInfo TransConvertType_Tracking
static void trackToTransData(TransformInitContext *init_context, const int framenr, MovieTrackingTrack *track, const float aspect[2])
@ transDataTracking_ModeTracks
@ transDataTracking_ModePlaneTracks
static void createTransTrackingData(bContext *C, TransInfo *t)
static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
static void transDataTrackingFree(TransInfo *, TransDataContainer *, TransCustomData *custom_data)
@ TD_INDIVIDUAL_SCALE
@ TD_SELECTED
void WM_event_add_notifier(const bContext *C, uint type, void *reference)