Camera tracking integraiton

===========================

- Corrected copyrights in my new files header.
- Added debug option to dump as PNG image content of search
  areas tracking between which was failed.
- Removed internal tracking settings like pyramid level and
  tolerance. Weren't useful neither for me nor for artists.
- Fixed bug in BKE_tracking_get_marker which could lead
  to failure of getting marker for current frame when
  there's marker for requested frame.
- Fixed bug with disappearing markers after tracking for
  cases when marker was added at frame different from
  tracking start frame and tracking start frame is
  equal to tracking end frame.
- Stop tracking when no markers could be tracked.
- Changed marker selection rules:
  * If marker isn't selected, all it's areas are getting
    selected with mouse.
  * If marker is selected and selection type doesn't have
    "extend" mode (SHIFT isn't holded down) the nearest
    to mouse cursor area would be selected. All the reast areas
    would loose selection.
- Limit number of frames which would be used in "Track Markers"
  operator. So now you could easily track along 10/20/etc frames.
- Change scene current frame after "Track Markers" operator.
- Implemented speed limitors. Now tracking could happen:
  * As fast as possible
  * With reatime speed (scene FPS)
  * With half of realtime speed
  * With quarter of realtime speed.
- Got rid of orig_user in MovieTrackingContext and user
  in TrackMarkersJob. This prevents crashes when user
  joins some space to SpaceClip from which tracking was started.
- Made keyframes on path bigger and do not draw keyframes for
  non-selected markers.

TODO: need to get rid of storing main, scene and screen
      in TrackMarkersJob. This is needed to set scene's
      current frame after tracking (such behavior is comfortable
      for artists) but this could lead to crash if scene is
      getting removed when tracking job is running.

      Render animation operator also stores scene and main,
      so such solution could be fine for first time before
      we've got something smarter.
This commit is contained in:
Sergey Sharybin
2011-06-22 14:54:53 +00:00
parent 68b7d48e01
commit 0bb215eece
24 changed files with 327 additions and 134 deletions

View File

@@ -15,7 +15,7 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# The Original Code is Copyright (C) 2006, Blender Foundation
# The Original Code is Copyright (C) 2011 Blender Foundation.
# All rights reserved.
#
# Contributor(s): Blender Foundation,

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
@@ -26,6 +26,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
/* define this to generate PNg images with content of search areas
tracking between which failed */
#undef DUMP_FAILURE
#include "libmv-capi.h"
#include "libmv/tracking/klt_region_tracker.h"
@@ -35,6 +39,10 @@
#include <stdlib.h>
#ifdef DUMP_FAILURE
# include <png.h>
#endif
#define DEFAULT_WINDOW_HALFSIZE 5
typedef struct ConfiguredRegionTracker {
@@ -72,14 +80,107 @@ static void floatBufToImage(const float *buf, int width, int height, libmv::Floa
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
(*image)(y, x, 0) = buf[a++];
(*image)(y, x, 0) = buf[a++];
}
}
}
#ifdef DUMP_FAILURE
void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
{
png_infop info_ptr;
png_structp png_ptr;
FILE *fp = fopen(file_name, "wb");
if (!fp)
return;
/* Initialize stuff */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
info_ptr = png_create_info_struct(png_ptr);
if (setjmp(png_jmpbuf(png_ptr))) {
fclose(fp);
return;
}
png_init_io(png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(png_ptr))) {
fclose(fp);
return;
}
png_set_IHDR(png_ptr, info_ptr, width, height,
depth, color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(png_ptr))) {
fclose(fp);
return;
}
png_write_image(png_ptr, row_pointers);
/* end write */
if (setjmp(png_jmpbuf(png_ptr))) {
fclose(fp);
return;
}
png_write_end(png_ptr, NULL);
fclose(fp);
}
static void saveImage(libmv::FloatImage image, int x0, int y0)
{
int x, y;
png_bytep *row_pointers;
row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*image.Height());
for (y = 0; y < image.Height(); y++) {
row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width());
for (x = 0; x < image.Width(); x++) {
if (x0 == x && y0 == y) {
row_pointers[y][x*4+0]= 255;
row_pointers[y][x*4+1]= 0;
row_pointers[y][x*4+2]= 0;
row_pointers[y][x*4+3]= 255;
}
else {
float pixel = image(y, x, 0);
row_pointers[y][x*4+0]= pixel*255;
row_pointers[y][x*4+1]= pixel*255;
row_pointers[y][x*4+2]= pixel*255;
row_pointers[y][x*4+3]= 255;
}
}
}
{
static int a= 0;
char buf[128];
snprintf(buf, sizeof(buf), "%02d.png", ++a);
savePNGImage(row_pointers, image.Width(), image.Height(), 8, PNG_COLOR_TYPE_RGBA, buf);
}
for (y = 0; y < image.Height(); y++) {
free(row_pointers[y]);
}
free(row_pointers);
}
#endif
int libmv_regionTrackerTrack(libmv_regionTrackerHandle tracker, const float *ima1, const float *ima2,
int width, int height, int half_window_size,
double x1, double y1, double *x2, double *y2)
double x1, double y1, double *x2, double *y2)
{
ConfiguredRegionTracker *configured_region_tracker;
libmv::RegionTracker *region_tracker;
@@ -95,7 +196,21 @@ int libmv_regionTrackerTrack(libmv_regionTrackerHandle tracker, const float *ima
floatBufToImage(ima1, width, height, &old_patch);
floatBufToImage(ima2, width, height, &new_patch);
#ifndef DUMP_FAILURE
return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
#else
{
double sx2 = *x2, sy2 = *y2;
int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
if (!result) {
saveImage(old_patch, x1, y1);
saveImage(new_patch, sx2, sy2);
}
return result;
}
#endif
}
void libmv_regionTrackerDestroy(libmv_regionTrackerHandle tracker)

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,

View File

@@ -84,7 +84,7 @@ static bool SolveTrackingEquation(const Mat2f &U,
float min_determinant,
Vec2f *d) {
float det = U.determinant();
if (det < min_determinant) {
if (fabsf(det) < min_determinant) {
d->setZero();
return false;
}

View File

@@ -110,12 +110,12 @@ class CLIP_PT_track_settings(bpy.types.Panel):
clip = context.space_data.clip
settings = clip.tracking.settings
layout.prop(settings, "max_iterations")
layout.prop(settings, "pyramid_level")
layout.prop(settings, "tolerance")
layout.prop(settings, "speed")
layout.prop(settings, "use_frames_limit")
layout.operator("clip.reset_tracking_settings", \
text="Reset To Defaults")
row = layout.row()
row.active = settings.use_frames_limit
row.prop(settings, "frames_limit")
class CLIP_PT_tracking_camera(bpy.types.Panel):

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
@@ -58,10 +58,9 @@ struct ImBuf *BKE_tracking_acquire_search_imbuf(struct ImBuf *ibuf, struct Movie
struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, int backwards);
void BKE_tracking_context_free(struct MovieTrackingContext *context);
void BKE_tracking_sync(struct MovieTrackingContext *context);
void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context);
int BKE_tracking_next(struct MovieTrackingContext *context);
void BKE_tracking_reset_settings(struct MovieTracking *tracking);
#define TRACK_SELECTED(track) ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)
#define TRACK_AREA_SELECTED(track, area) ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT))
@@ -70,7 +69,7 @@ void BKE_tracking_reset_settings(struct MovieTracking *tracking);
#define CLAMP_SEARCH_DIM 3
#define CLAMP_SEARCH_POS 4
#define TRACK_AREA_NONE - 1
#define TRACK_AREA_NONE -1
#define TRACK_AREA_POINT 1
#define TRACK_AREA_PAT 2
#define TRACK_AREA_SEARCH 4

View File

@@ -17,11 +17,12 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
* Sergey Sharybin,
* Peter Schlaile
*
* ***** END GPL LICENSE BLOCK *****
*/

View File

@@ -213,7 +213,7 @@ static MovieClip *movieclip_alloc(const char *name)
clip= alloc_libblock(&G.main->movieclip, ID_MC, name);
BKE_tracking_reset_settings(&clip->tracking);
clip->tracking.settings.frames_limit= 20;
clip->tracking.camera.focal= 24.0f;
return clip;

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
@@ -172,7 +172,7 @@ void BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *
MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr)
{
int a= track->markersnr;
int a= track->markersnr-1;
if(!track->markersnr)
return NULL;
@@ -267,7 +267,6 @@ void BKE_tracking_free(MovieTracking *tracking)
typedef struct MovieTrackingContext {
MovieClipUser user;
MovieClipUser *orig_user;
MovieClip *clip;
#ifdef WITH_LIBMV
@@ -278,6 +277,7 @@ typedef struct MovieTrackingContext {
MovieTrackingSettings settings;
int backwards;
int sync_frame;
} MovieTrackingContext;
MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, int backwards)
@@ -288,8 +288,7 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
MovieTrackingTrack *track;
#ifdef WITH_LIBMV
context->region_tracker= libmv_regionTrackerNew(settings->max_iterations,
settings->pyramid_level, settings->tolerance);
context->region_tracker= libmv_regionTrackerNew(100, 3, 0.2);
#endif
context->settings= *settings;
@@ -310,7 +309,6 @@ MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *u
context->clip= clip;
context->user= *user;
context->orig_user= user;
return context;
}
@@ -444,7 +442,7 @@ void BKE_tracking_sync(MovieTrackingContext *context)
if(sel_type==MCLIP_SEL_TRACK && sel==cur)
replace_sel= 1;
track->flag= cur->flag|TRACK_PROCESSED;
track->flag= cur->flag | (track->flag&TRACK_PROCESSED);
track->pat_flag= cur->pat_flag;
track->search_flag= cur->search_flag;
@@ -479,11 +477,15 @@ void BKE_tracking_sync(MovieTrackingContext *context)
context->clip->tracking.tracks= tracks;
;
if(context->backwards) newframe= context->user.framenr+1;
else newframe= context->user.framenr-1;
context->orig_user->framenr= newframe;
context->sync_frame= newframe;
}
void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context)
{
user->framenr= context->sync_frame;
}
int BKE_tracking_next(MovieTrackingContext *context)
@@ -491,6 +493,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
ImBuf *ibuf, *ibuf_new;
MovieTrackingTrack *track;
int curfra= context->user.framenr;
int ok= 0;
/* nothing to track, avoid unneeded frames reading to save time and memory */
if(!context->tracks.first)
@@ -530,8 +533,6 @@ int BKE_tracking_next(MovieTrackingContext *context)
x1, y1, &x2, &y2)) {
MovieTrackingMarker marker_new;
track->flag|= TRACK_PROCESSED;
marker_new.pos[0]= marker->pos[0]+track->search_min[0]+x2/ibuf_new->x;
marker_new.pos[1]= marker->pos[1]+track->search_min[1]+y2/ibuf_new->y;
@@ -543,13 +544,18 @@ int BKE_tracking_next(MovieTrackingContext *context)
if(marker->framenr!=curfra)
marker->framenr= curfra;
track->flag|= TRACK_PROCESSED;
BKE_tracking_insert_marker(track, &marker_new);
ok= 1;
}
MEM_freeN(patch);
MEM_freeN(patch_new);
#endif
}
} else
track->flag|= TRACK_PROCESSED;
track= track->next;
}
@@ -557,12 +563,5 @@ int BKE_tracking_next(MovieTrackingContext *context)
IMB_freeImBuf(ibuf);
IMB_freeImBuf(ibuf_new);
return 1;
}
void BKE_tracking_reset_settings(MovieTracking *tracking)
{
tracking->settings.max_iterations= 200;
tracking->settings.pyramid_level= 3;
tracking->settings.tolerance= 0.2;
return ok;
}

View File

@@ -5688,6 +5688,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
clip->sel_type= MCLIP_SEL_NONE;
clip->anim= NULL;
clip->tracking_context= NULL;
}
static void lib_link_movieclip(FileData *fd, Main *main)

View File

@@ -15,6 +15,8 @@
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# The Original Code is Copyright (C) 2011 Blender Foundation.
#
# Contributor(s): Blender Foundation,
# Sergey Sharybin
#

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*
@@ -127,7 +127,7 @@ static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf)
static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *track)
{
int count= sc->path_length;
int i, a, b, sel_type;
int i, a, b, sel_type, curindex= -1;
float path[102][2];
int tiny= sc->flag&SC_SHOW_TINY_MARKER;
MovieTrackingMarker *marker;
@@ -155,6 +155,9 @@ static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *
copy_v2_v2(path[--a], marker->pos);
if(marker->framenr==sc->user.framenr)
curindex= a;
i--;
}
@@ -166,6 +169,9 @@ static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *
if(!marker)
break;
if(marker->framenr==sc->user.framenr)
curindex= b;
copy_v2_v2(path[b++], marker->pos);
i++;
@@ -174,11 +180,15 @@ static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *
if(!tiny) {
UI_ThemeColor(TH_MARKER_OUTLINE);
glPointSize(4.0f);
glBegin(GL_POINTS);
for(i= a; i<b; i++)
glVertex2f(path[i][0], path[i][1]);
glEnd();
if(TRACK_SELECTED(track)) {
glPointSize(5.0f);
glBegin(GL_POINTS);
for(i= a; i<b; i++) {
if(i!=curindex)
glVertex2f(path[i][0], path[i][1]);
}
glEnd();
}
glLineWidth(3.0f);
glBegin(GL_LINE_STRIP);
@@ -188,16 +198,21 @@ static void draw_track_path(SpaceClip *sc, MovieClip *clip, MovieTrackingTrack *
glLineWidth(1.0f);
}
glPointSize(2.0f);
if(sel_type==MCLIP_SEL_TRACK && sel==track) UI_ThemeColor(TH_ACT_MARKER);
else {
if (TRACK_SELECTED(track)) UI_ThemeColor(TH_SEL_MARKER);
else UI_ThemeColor(TH_MARKER);
}
glBegin(GL_POINTS);
for(i= a; i<b; i++)
glVertex2f(path[i][0], path[i][1]);
glEnd();
if(TRACK_SELECTED(track)) {
glPointSize(3.0f);
glBegin(GL_POINTS);
for(i= a; i<b; i++) {
if(i!=curindex)
glVertex2f(path[i][0], path[i][1]);
}
glEnd();
}
glBegin(GL_LINE_STRIP);
for(i= a; i<b; i++)
@@ -391,6 +406,11 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
if(!clip)
return;
/* if trcking is in progress, we should sunchronize framenr from clipuser
so latest tracked frame would be shown */
if(clip->tracking_context)
BKE_tracking_sync_user(&sc->user, clip->tracking_context);
ibuf= ED_space_clip_acquire_buffer(sc);
if(ibuf) {

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*
@@ -68,7 +68,6 @@ void CLIP_OT_delete(struct wmOperatorType *ot);
void CLIP_OT_track_markers(struct wmOperatorType *ot);
void CLIP_OT_reset_tracking_settings(struct wmOperatorType *ot);
void CLIP_OT_clear_track_path(struct wmOperatorType *ot);
void CLIP_OT_track_to_fcurves(struct wmOperatorType *ot);

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*
@@ -208,7 +208,6 @@ static void clip_operatortypes(void)
WM_operatortype_append(CLIP_OT_track_markers);
WM_operatortype_append(CLIP_OT_reset_tracking_settings);
WM_operatortype_append(CLIP_OT_clear_track_path);
WM_operatortype_append(CLIP_OT_track_to_fcurves);

View File

@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2008 Blender Foundation.
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
*
@@ -62,6 +62,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
#include "PIL_time.h"
#include "UI_view2d.h"
#include "clip_intern.h" // own include
@@ -348,7 +350,10 @@ static int mouse_select(bContext *C, float co[2], int extend)
if(track) {
int area= track_mouse_area(sc, co, track);
if(!extend || !TRACK_SELECTED(track))
if(area==TRACK_AREA_NONE)
return OPERATOR_FINISHED;
if(!TRACK_SELECTED(track))
area= TRACK_AREA_ALL;
if(extend && TRACK_AREA_SELECTED(track, area)) {
@@ -652,10 +657,15 @@ void CLIP_OT_select_all(wmOperatorType *ot)
/********************** track operator *********************/
typedef struct TrackMarkersJob {
struct MovieTrackingContext *context;
int sfra, efra, backwards;
MovieClip *clip;
MovieClipUser *user;
struct MovieTrackingContext *context; /* tracking context */
int sfra, efra, lastfra; /* Start, end and recently tracked frames */
int backwards; /* Backwards tracking flag */
MovieClip *clip; /* Clip which is tracking */
float delay; /* Delay in milliseconds to allow tracking at fixed FPS */
struct Main *main;
struct Scene *scene;
struct bScreen *screen;
} TrackMarkersJob;
static int track_markers_testbreak(void)
@@ -668,16 +678,40 @@ static void track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backwar
SpaceClip *sc= CTX_wm_space_clip(C);
MovieClip *clip= ED_space_clip(sc);
Scene *scene= CTX_data_scene(C);
MovieTrackingSettings *settings= &clip->tracking.settings;
tmj->sfra= sc->user.framenr;
tmj->clip= clip;
tmj->user= &sc->user;
tmj->backwards= backwards;
if(backwards) tmj->efra= SFRA;
else tmj->efra= EFRA;
/* limit frames to be tracked by user setting */
if(settings->flag&TRACKING_FRAMES_LIMIT) {
if(backwards) tmj->efra= MAX2(tmj->efra, tmj->sfra-settings->frames_limit);
else tmj->efra= MIN2(tmj->efra, tmj->sfra+settings->frames_limit);
}
if(settings->speed!=TRACKING_SPEED_FASTEST) {
tmj->delay= 1.0f/scene->r.frs_sec*1000.0f;
if(settings->speed==TRACKING_SPEED_HALF) tmj->delay*= 2;
else if(settings->speed==TRACKING_SPEED_QUARTER) tmj->delay*= 4;
}
tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards);
clip->tracking_context= tmj->context;
/* XXX: silly to store this, but this data is needed to update scene and movieclip
frame numbers when tracking is finished. This introduces better feedback for artists.
Maybe there's another way to solve this problem, but can't think better way atm.
Anyway, this way isn't more unstable as animation rendering animation
which uses the same approach (except storing screen). */
tmj->scene= scene;
tmj->main= CTX_data_main(C);
tmj->screen= CTX_wm_screen(C);
}
static void track_markers_startjob(void *tmv, short *UNUSED(stop), short *do_update, float *progress)
@@ -686,17 +720,34 @@ static void track_markers_startjob(void *tmv, short *UNUSED(stop), short *do_upd
int framenr= tmj->sfra;
while(framenr != tmj->efra) {
if(!BKE_tracking_next(tmj->context))
break;
if(tmj->delay>0) {
/* tracking should happen with fixed fps. Calculate time
using current timer value before tracking frame and after.
Small (and maybe unneeded optimization): do not calculate exec_time
for "Fastest" tracking */
double start_time= PIL_check_seconds_timer(), exec_time;
if(!BKE_tracking_next(tmj->context))
break;
exec_time= PIL_check_seconds_timer()-start_time;
if(tmj->delay>exec_time)
PIL_sleep_ms(tmj->delay-exec_time);
} else if(!BKE_tracking_next(tmj->context))
break;
*do_update= 1;
*progress=(float)(framenr-tmj->sfra) / (tmj->efra-tmj->sfra);
if(track_markers_testbreak())
break;
if(tmj->backwards) framenr--;
else framenr++;
tmj->lastfra= framenr;
if(track_markers_testbreak())
break;
}
}
@@ -711,30 +762,44 @@ static void track_markers_freejob(void *tmv)
{
TrackMarkersJob *tmj= (TrackMarkersJob *)tmv;
tmj->clip->tracking_context= NULL;
tmj->scene->r.cfra= tmj->lastfra;
ED_update_for_newframe(tmj->main, tmj->scene, tmj->screen, 0);
BKE_tracking_sync(tmj->context);
BKE_tracking_context_free(tmj->context);
/* movie clip's user was used during tracking,
need to restore current frame number */
tmj->user->framenr= tmj->sfra;
MEM_freeN(tmj);
WM_main_add_notifier(NC_SCENE|ND_FRAME, tmj->scene);
}
static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
{
TrackMarkersJob *tmj;
SpaceClip *sc= CTX_wm_space_clip(C);
MovieClip *clip= ED_space_clip(sc);
wmJob *steve;
Scene *scene= CTX_data_scene(C);
int backwards= RNA_boolean_get(op->ptr, "backwards");
if(clip->tracking_context)
return OPERATOR_CANCELLED;
tmj= MEM_callocN(sizeof(TrackMarkersJob), "TrackMarkersJob data");
track_markers_initjob(C, tmj, backwards);
/* setup job */
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Track Markers", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
WM_jobs_customdata(steve, tmj, track_markers_freejob);
WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|NA_EVALUATED, 0);
/* if there's delay set in tracking job, tracking should happen
with fixed FPS. To deal with editor refresh we have to syncronize
tracks from job and tracks in clip. Do this in timer callback
to prevent threading conflicts. */
if(tmj->delay>0) WM_jobs_timer(steve, tmj->delay/1000.0f, NC_MOVIECLIP|NA_EVALUATED, 0);
else WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|NA_EVALUATED, 0);
WM_jobs_callbacks(steve, track_markers_startjob, NULL, track_markers_updatejob, NULL);
G.afbreek= 0;
@@ -755,12 +820,22 @@ static int track_markers_exec(bContext *C, wmOperator *op)
Scene *scene= CTX_data_scene(C);
struct MovieTrackingContext *context;
int framenr= sc->user.framenr;
int sfra= framenr;
int sfra= framenr, efra;
int backwards= RNA_boolean_get(op->ptr, "backwards");
MovieTrackingSettings *settings= &clip->tracking.settings;
if(backwards) efra= SFRA;
else efra= EFRA;
/* limit frames to be tracked by user setting */
if(settings->flag&TRACKING_FRAMES_LIMIT) {
if(backwards) efra= MAX2(efra, sfra-settings->frames_limit);
else efra= MIN2(efra, sfra+settings->frames_limit);
}
context= BKE_tracking_context_new(clip, &sc->user, backwards);
while(framenr != EFRA) {
while(framenr != efra) {
if(!BKE_tracking_next(context))
break;
@@ -771,11 +846,11 @@ static int track_markers_exec(bContext *C, wmOperator *op)
BKE_tracking_sync(context);
BKE_tracking_context_free(context);
/* movie clip's user was used during tracking,
need to restore current frame number */
sc->user.framenr= sfra;
/* update scene current frame to the lastes tracked frame */
scene->r.cfra= framenr;
WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
return OPERATOR_FINISHED;
}
@@ -816,33 +891,6 @@ void CLIP_OT_track_markers(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tarcking");
}
/********************** reset tracking settings operator *********************/
static int reset_tracking_settings_exec(bContext *C, wmOperator *UNUSED(op))
{
SpaceClip *sc= CTX_wm_space_clip(C);
MovieClip *clip= ED_space_clip(sc);
BKE_tracking_reset_settings(&clip->tracking);
return OPERATOR_FINISHED;
}
void CLIP_OT_reset_tracking_settings(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Reset Tracking Settings";
ot->description= "Reset tracking settings to default values";
ot->idname= "CLIP_OT_reset_tracking_settings";
/* api callbacks */
ot->exec= reset_tracking_settings_exec;
ot->poll= space_clip_frame_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
/********************** clear track operator *********************/
static int clear_track_path_poll(bContext *C)

View File

@@ -60,6 +60,9 @@ typedef struct MovieClip {
void *ibuf_cache; /* cache of ibufs, not in file */
struct MovieTracking tracking; /* data for SfM tracking */
void *tracking_context; /* context of tracking job
used to synchronize data like framenumber
in SpaceClip clip user */
int sel_type; /* last selected thing */
int pad;

View File

@@ -90,10 +90,9 @@ typedef struct MovieTrackingTrack {
} MovieTrackingTrack;
typedef struct MovieTrackingSettings {
int max_iterations;
int pyramid_level;
float tolerance;
int pad;
int flag; /* different flags (frames nr limit..) */
short speed; /* speed of tracking */
short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */
} MovieTrackingSettings;
typedef struct MovieTracking {
@@ -106,4 +105,13 @@ typedef struct MovieTracking {
/* MovieTrackingTrack->flag */
#define TRACK_PROCESSED 2
/* MovieTrackingSettings->speed */
#define TRACKING_SPEED_FASTEST 0
#define TRACKING_SPEED_REALTIME 1
#define TRACKING_SPEED_HALF 2
#define TRACKING_SPEED_QUARTER 4
/* MovieTrackingSettings->flag */
#define TRACKING_FRAMES_LIMIT 1
#endif

View File

@@ -108,32 +108,31 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem speed_items[] = {
{0, "FASTEST", 0, "Fastest", "track as fast as it's possible"},
{TRACKING_SPEED_REALTIME, "REALTIME", 0, "Realtime", "Track with realtime speed"},
{TRACKING_SPEED_HALF, "HALF", 0, "Half", "Track with half of realtime speed"},
{TRACKING_SPEED_HALF, "QUARTER", 0, "Quarter", "Track with quarter of realtime speed"},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "MovieTrackingSettings", NULL);
RNA_def_struct_ui_text(srna, "Movie tracking settings", "Match-moving tracking settings");
/* max iterations */
prop= RNA_def_property(srna, "max_iterations", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "max_iterations");
RNA_def_property_range(prop, 1.0f, INT_MAX);
RNA_def_property_ui_range(prop, 1, 500, 1, 1);
RNA_def_property_ui_text(prop, "Max Iterations", "Maximal iteration used by KLT region tracker");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* speed */
prop= RNA_def_property(srna, "speed", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, speed_items);
RNA_def_property_ui_text(prop, "Speed", "Speed to make tracking with");
/* pyramid level */
prop= RNA_def_property(srna, "pyramid_level", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "pyramid_level");
RNA_def_property_range(prop, 1.0f, INT_MAX);
RNA_def_property_ui_range(prop, 1, 20, 1, 1);
RNA_def_property_ui_text(prop, "Pyramid Level", "Levels used by pyramid tracker");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* use limit frames */
prop= RNA_def_property(srna, "use_frames_limit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_FRAMES_LIMIT);
RNA_def_property_ui_text(prop, "Limit Frames", "Limit number of frames be tracked during single tracking operation");
/* tolerance */
prop= RNA_def_property(srna, "tolerance", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "tolerance");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 2, 1, 3);
RNA_def_property_ui_text(prop, "Tolerance", "Tolerance of retrackt tracker");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* limit frames */
prop= RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "frames_limit");
RNA_def_property_range(prop, 1, INT_MAX);
RNA_def_property_ui_text(prop, "Frames Limit", "Amount of frames to be tracked during single tracking operation");
}
static void rna_def_trackingCamera(BlenderRNA *brna)