Blender V4.5
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
8
9#include "DNA_space_types.h"
10
11#include "MEM_guardedalloc.h"
12
13#include "BLI_listbase.h"
14#include "BLI_math_matrix.h"
15#include "BLI_math_vector.h"
16
17#include "BKE_context.hh"
18#include "BKE_movieclip.h"
20#include "BKE_tracking.h"
21
22#include "ED_clip.hh"
23
24#include "WM_api.hh"
25
26#include "transform.hh"
27#include "transform_convert.hh"
28
29namespace blender::ed::transform {
30
32 int mode;
33 int flag;
34
35 /* Tracks transformation from main window. */
36 int area;
37 const float *relative, *loc;
38 float soffset[2], srelative[2];
39 float offset[2];
40
41 float (*smarkers)[2];
45
48};
49
54
55/* -------------------------------------------------------------------- */
58
61
64
65 /* NOTE: These pointers will be `nullptr` during counting step.
66 * This means, that the transformation data initialization functions are to increment
67 * `tc->data_len` instead of filling in the transformation data when these pointers are
68 * `nullptr`. For simplicity, check the `current.td` against `nullptr`.
69 * Do not `tc->data_len` when filling in the transformation data. */
70 struct {
75};
76
78 MovieTrackingTrack *track,
79 MovieTrackingMarker *marker,
80 int area,
81 float loc[2],
82 const float rel[2],
83 const float off[2],
84 const float aspect[2])
85{
86 TransData *td = init_context->current.td;
87 TransData2D *td2d = init_context->current.td2d;
88 TransDataTracking *tdt = init_context->current.tdt;
89
90 if (td == nullptr) {
91 init_context->tc->data_len++;
92 return;
93 }
94
95 int anchor = area == TRACK_AREA_POINT && off;
96
97 tdt->flag = marker->flag;
98 tdt->framenr = marker->framenr;
100
101 if (anchor) {
102 td2d->loc[0] = rel[0] * aspect[0]; /* Hold original location. */
103 td2d->loc[1] = rel[1] * aspect[1];
104
105 tdt->loc = loc;
106 td2d->loc2d = loc; /* Current location. */
107 }
108 else {
109 td2d->loc[0] = loc[0] * aspect[0]; /* Hold original location. */
110 td2d->loc[1] = loc[1] * aspect[1];
111
112 td2d->loc2d = loc; /* Current location. */
113 }
114 td2d->loc[2] = 0.0f;
115
116 tdt->relative = rel;
117 tdt->area = area;
118
119 tdt->markersnr = track->markersnr;
120 tdt->markers = track->markers;
121 tdt->track = track;
122
123 if (rel) {
124 if (!anchor) {
125 td2d->loc[0] += rel[0] * aspect[0];
126 td2d->loc[1] += rel[1] * aspect[1];
127 }
128
129 copy_v2_v2(tdt->srelative, rel);
130 }
131
132 if (off) {
133 copy_v2_v2(tdt->soffset, off);
134 }
135
136 td->flag = 0;
137 td->loc = td2d->loc;
138 copy_v3_v3(td->iloc, td->loc);
139
140 // copy_v3_v3(td->center, td->loc);
142 td->center[0] = marker->pos[0] * aspect[0];
143 td->center[1] = marker->pos[1] * aspect[1];
144
145 memset(td->axismtx, 0, sizeof(td->axismtx));
146 td->axismtx[2][2] = 1.0f;
147
148 td->ext = nullptr;
149 td->val = nullptr;
150
151 td->flag |= TD_SELECTED;
152 td->dist = 0.0;
153
154 unit_m3(td->mtx);
155 unit_m3(td->smtx);
156
157 init_context->current.td++;
158 init_context->current.td2d++;
159 init_context->current.tdt++;
160}
161
163 const int framenr,
164 MovieTrackingTrack *track,
165 const float aspect[2])
166{
167 MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
168
170 track,
171 marker,
173 track->offset,
174 marker->pos,
175 track->offset,
176 aspect);
177
178 if (track->flag & SELECT) {
180 init_context, track, marker, TRACK_AREA_POINT, marker->pos, nullptr, nullptr, aspect);
181 }
182
183 if (track->pat_flag & SELECT) {
184 int a;
185
186 for (a = 0; a < 4; a++) {
188 track,
189 marker,
191 marker->pattern_corners[a],
192 marker->pos,
193 nullptr,
194 aspect);
195 }
196 }
197
198 if (track->search_flag & SELECT) {
200 track,
201 marker,
203 marker->search_min,
204 marker->pos,
205 nullptr,
206 aspect);
207
209 track,
210 marker,
212 marker->search_max,
213 marker->pos,
214 nullptr,
215 aspect);
216 }
217
218 if (init_context->current.td != nullptr) {
219 marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
220 }
221}
222
224 const int framenr,
225 MovieTrackingTrack *track,
226 const float aspect[2])
227{
228 if (!TRACK_VIEW_SELECTED(init_context->space_clip, track)) {
229 return;
230 }
231 if (track->flag & TRACK_LOCKED) {
232 return;
233 }
234 trackToTransData(init_context, framenr, track, aspect);
235}
236
238 MovieTrackingPlaneTrack *plane_track,
239 MovieTrackingPlaneMarker *plane_marker,
240 float corner[2],
241 const float aspect[2])
242{
243 TransData *td = init_context->current.td;
244 TransData2D *td2d = init_context->current.td2d;
245 TransDataTracking *tdt = init_context->current.tdt;
246
247 if (td == nullptr) {
248 init_context->tc->data_len++;
249 return;
250 }
251
252 tdt->flag = plane_marker->flag;
253 tdt->framenr = plane_marker->framenr;
255 tdt->plane_track = plane_track;
256
257 td2d->loc[0] = corner[0] * aspect[0]; /* Hold original location. */
258 td2d->loc[1] = corner[1] * aspect[1];
259
260 td2d->loc2d = corner; /* Current location. */
261 td2d->loc[2] = 0.0f;
262
263 td->flag = 0;
264 td->loc = td2d->loc;
265 copy_v3_v3(td->iloc, td->loc);
266 copy_v3_v3(td->center, td->loc);
267
268 memset(td->axismtx, 0, sizeof(td->axismtx));
269 td->axismtx[2][2] = 1.0f;
270
271 td->ext = nullptr;
272 td->val = nullptr;
273
274 td->flag |= TD_SELECTED;
275 td->dist = 0.0;
276
277 unit_m3(td->mtx);
278 unit_m3(td->smtx);
279
280 init_context->current.td++;
281 init_context->current.td2d++;
282 init_context->current.tdt++;
283}
284
286 const int framenr,
287 MovieTrackingPlaneTrack *plane_track,
288 const float aspect[2])
289{
290 MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
291
292 for (int i = 0; i < 4; i++) {
294 init_context, plane_track, plane_marker, plane_marker->corners[i], aspect);
295 }
296
297 if (init_context->current.td != nullptr) {
298 plane_marker->flag &= ~PLANE_MARKER_TRACKED;
299 }
300}
301
303 const int framenr,
304 MovieTrackingPlaneTrack *plane_track,
305 const float aspect[2])
306{
307 if (!PLANE_TRACK_VIEW_SELECTED(plane_track)) {
308 return;
309 }
310 planeTrackToTransData(init_context, framenr, plane_track, aspect);
311}
312
314 TransDataContainer * /*tc*/,
315 TransCustomData *custom_data)
316{
317 if (custom_data->data) {
318 TransDataTracking *tdt = static_cast<TransDataTracking *>(custom_data->data);
319 if (tdt->smarkers) {
320 MEM_freeN(tdt->smarkers);
321 }
322
323 MEM_freeN(tdt);
324 custom_data->data = nullptr;
325 }
326}
327
329{
330 SpaceClip *space_clip = CTX_wm_space_clip(C);
331 MovieClip *clip = ED_space_clip_get_clip(space_clip);
332 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
333 const int framenr = ED_space_clip_get_clip_frame_number(space_clip);
334
336
338 init_context.space_clip = space_clip;
339 init_context.t = t;
340 init_context.tc = tc;
341
342 /* Count required transformation data. */
343
344 tc->data_len = 0;
345
346 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
347 trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
348 }
349
350 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
351 planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
352 }
353
354 if (tc->data_len == 0) {
355 return;
356 }
357
358 tc->data = MEM_calloc_arrayN<TransData>(tc->data_len, "TransTracking TransData");
359 tc->data_2d = MEM_calloc_arrayN<TransData2D>(tc->data_len, "TransTracking TransData2D");
361 "TransTracking TransDataTracking");
363
364 init_context.current.td = tc->data;
365 init_context.current.td2d = tc->data_2d;
366 init_context.current.tdt = static_cast<TransDataTracking *>(tc->custom.type.data);
367
368 /* Create actual transformation data. */
369
370 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
371 trackToTransDataIfNeeded(&init_context, framenr, track, t->aspect);
372 }
373
374 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
375 planeTrackToTransDataIfNeeded(&init_context, framenr, plane_track, t->aspect);
376 }
377}
378
380{
383 int width, height;
384
386
387 tc->data_len = 0;
388
389 if (!clip) {
390 return;
391 }
392
393 BKE_movieclip_get_size(clip, &sc->user, &width, &height);
394
395 if (width == 0 || height == 0) {
396 return;
397 }
398
400}
401
403
404/* -------------------------------------------------------------------- */
407
409{
411 TransDataTracking *tdt_array = static_cast<TransDataTracking *>(tc->custom.type.data);
412
413 int i = 0;
414 while (i < tc->data_len) {
415 TransDataTracking *tdt = &tdt_array[i];
416
418 MovieTrackingTrack *track = tdt->track;
420
421 BLI_assert(marker != nullptr);
422
423 marker->flag = tdt->flag;
424
425 if (track->flag & SELECT) {
426 i++;
427 }
428
429 if (track->pat_flag & SELECT) {
430 i += 4;
431 }
432
433 if (track->search_flag & SELECT) {
434 i += 2;
435 }
436 }
437 else if (tdt->mode == transDataTracking_ModePlaneTracks) {
438 MovieTrackingPlaneTrack *plane_track = tdt->plane_track;
440 tdt->framenr);
441
442 BLI_assert(plane_marker != nullptr);
443
444 plane_marker->flag = tdt->flag;
445 i += 3;
446 }
447
448 i++;
449 }
450}
451
453{
454 TransData *td;
455 TransData2D *td2d;
457 int td_index;
458
459 if (t->state == TRANS_CANCEL) {
461 }
462
464
465 /* Flush to 2d vector from internally used 3d vector. */
466 for (td_index = 0,
467 td = tc->data,
468 td2d = tc->data_2d,
469 tdt = static_cast<TransDataTracking *>(tc->custom.type.data);
470 td_index < tc->data_len;
471 td_index++, td2d++, td++, tdt++)
472 {
474 float loc2d[2];
475
476 if (t->mode == TFM_ROTATION && tdt->area == TRACK_AREA_SEARCH) {
477 continue;
478 }
479
480 loc2d[0] = td2d->loc[0] / t->aspect[0];
481 loc2d[1] = td2d->loc[1] / t->aspect[1];
482
483 if (t->flag & T_ALT_TRANSFORM) {
484 if (t->mode == TFM_RESIZE) {
485 if (tdt->area != TRACK_AREA_PAT && !(t->state == TRANS_CANCEL)) {
486 continue;
487 }
488 }
489 else if (t->mode == TFM_TRANSLATION) {
490 if (tdt->area == TRACK_AREA_POINT && tdt->relative) {
491 float d[2], d2[2];
492
493 if (!tdt->smarkers) {
494 tdt->smarkers = static_cast<float(*)[2]>(MEM_callocN(
495 sizeof(*tdt->smarkers) * tdt->markersnr, "flushTransTracking markers"));
496 for (int a = 0; a < tdt->markersnr; a++) {
497 copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos);
498 }
499 }
500
501 sub_v2_v2v2(d, loc2d, tdt->soffset);
502 sub_v2_v2(d, tdt->srelative);
503
504 sub_v2_v2v2(d2, loc2d, tdt->srelative);
505
506 for (int a = 0; a < tdt->markersnr; a++) {
507 add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2);
508 }
509
510 negate_v2_v2(td2d->loc2d, d);
511 }
512 }
513 }
514
515 if (tdt->area != TRACK_AREA_POINT || tdt->relative == nullptr) {
516 td2d->loc2d[0] = loc2d[0];
517 td2d->loc2d[1] = loc2d[1];
518
519 if (tdt->relative) {
520 sub_v2_v2(td2d->loc2d, tdt->relative);
521 }
522 }
523 }
524 else if (tdt->mode == transDataTracking_ModePlaneTracks) {
525 td2d->loc2d[0] = td2d->loc[0] / t->aspect[0];
526 td2d->loc2d[1] = td2d->loc[1] / t->aspect[1];
527 }
528 }
529}
530
532{
533 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
534
537 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
538 const int framenr = ED_space_clip_get_clip_frame_number(sc);
539
541
542 LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
543 if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
544 MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
545
546 if (t->mode == TFM_TRANSLATION) {
549 }
552 }
553 }
554 else if (t->mode == TFM_RESIZE) {
557 }
560 }
561 }
562 else if (t->mode == TFM_ROTATION) {
565 }
566 }
567 }
568 }
569
570 DEG_id_tag_update(&clip->id, 0);
571 }
572}
573
575
576/* -------------------------------------------------------------------- */
579
581{
582 SpaceClip *sc = static_cast<SpaceClip *>(t->area->spacedata.first);
584 const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking);
585 const int framenr = ED_space_clip_get_clip_frame_number(sc);
586 /* Update coordinates of modified plane tracks. */
587 LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
588 bool do_update = false;
589 if (plane_track->flag & PLANE_TRACK_HIDDEN) {
590 continue;
591 }
592 do_update |= PLANE_TRACK_VIEW_SELECTED(plane_track) != 0;
593 if (do_update == false) {
594 if ((plane_track->flag & PLANE_TRACK_AUTOKEY) == 0) {
595 int i;
596 for (i = 0; i < plane_track->point_tracksnr; i++) {
597 MovieTrackingTrack *track = plane_track->point_tracks[i];
598 if (TRACK_VIEW_SELECTED(sc, track)) {
599 do_update = true;
600 break;
601 }
602 }
603 }
604 }
605 if (do_update) {
607 }
608 }
609 if (t->scene->nodetree != nullptr) {
610 /* Tracks can be used for stabilization nodes,
611 * flush update for such nodes.
612 */
613 if (t->context != nullptr) {
614 Main *bmain = CTX_data_main(C);
615 BKE_ntree_update_tag_id_changed(bmain, &clip->id);
616 BKE_ntree_update(*bmain);
618 }
619 }
620}
621
623
625 /*flags*/ (T_POINTS | T_2D_EDIT),
626 /*create_trans_data*/ createTransTrackingData,
627 /*recalc_data*/ recalcData_tracking,
628 /*special_aftertrans_update*/ special_aftertrans_update__movieclip,
629};
630
631} // namespace blender::ed::transform
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 &bmain, std::optional< blender::Span< bNodeTree * > > modified_trees=std::nullopt, const 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:1307
struct MovieTrackingPlaneMarker * BKE_tracking_plane_marker_get_exact(struct MovieTrackingPlaneTrack *plane_track, int framenr)
Definition tracking.cc:1836
struct MovieTrackingMarker * BKE_tracking_marker_ensure(struct MovieTrackingTrack *track, int framenr)
Definition tracking.cc:1401
#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:1357
void BKE_tracking_marker_clamp_search_position(struct MovieTrackingMarker *marker)
Definition tracking.cc:1337
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:1390
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:1848
void BKE_tracking_marker_clamp_search_size(struct MovieTrackingMarker *marker)
Definition tracking.cc:1326
#define TRACK_VIEW_SELECTED(sc, track)
#define TRACK_AREA_SELECTED(track, area)
#define BLI_assert(a)
Definition BLI_assert.h:46
#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)
@ PLANE_MARKER_TRACKED
@ MARKER_TRACKED
@ MARKER_DISABLED
@ TRACK_LOCKED
@ PLANE_TRACK_HIDDEN
@ PLANE_TRACK_AUTOKEY
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)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define NC_SCENE
Definition WM_types.hh:375
#define ND_NODES
Definition WM_types.hh:433
bool do_update
Definition WM_types.hh:1008
#define SELECT
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static void transDataTrackingFree(TransInfo *, TransDataContainer *, TransCustomData *custom_data)
static void recalcData_tracking(TransInfo *t)
static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
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 trackToTransData(TransformInitContext *init_context, const int framenr, MovieTrackingTrack *track, const float aspect[2])
static void flushTransTracking(TransInfo *t)
static void createTransTrackingTracksData(bContext *C, TransInfo *t)
static void createTransTrackingData(bContext *C, TransInfo *t)
static void trackToTransDataIfNeeded(TransformInitContext *init_context, const int framenr, MovieTrackingTrack *track, const float aspect[2])
static void planeTrackToTransData(TransformInitContext *init_context, const int framenr, MovieTrackingPlaneTrack *plane_track, const float aspect[2])
TransConvertTypeInfo TransConvertType_Tracking
static void planeMarkerToTransDataInit(TransformInitContext *init_context, MovieTrackingPlaneTrack *plane_track, MovieTrackingPlaneMarker *plane_marker, float corner[2], const float aspect[2])
static void planeTrackToTransDataIfNeeded(TransformInitContext *init_context, const int framenr, MovieTrackingPlaneTrack *plane_track, const float aspect[2])
static void init_context(DupliContext *r_ctx, Depsgraph *depsgraph, Scene *scene, Object *ob, const float space_mat[4][4], blender::Set< const Object * > *include_objects, Vector< Object * > &instance_stack, Vector< short > &dupli_gen_type_stack)
void * first
struct MovieTracking tracking
MovieTrackingMarker * markers
struct bNodeTree * nodetree
ListBase spacedata
struct MovieClipUser user
void(* free_cb)(TransInfo *, TransDataContainer *tc, TransCustomData *custom_data)
Definition transform.hh:628
struct blender::ed::transform::TransformInitContext::@066325116056105274332372000063144226000354107167 current
i
Definition text_draw.cc:230
#define TRANS_DATA_CONTAINER_FIRST_SINGLE(t)
Definition transform.hh:39
conversion and adaptation of different datablocks to a common struct.
void WM_event_add_notifier(const bContext *C, uint type, void *reference)