Camera tracking integration

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

- Changed libmv api to use doubles instead of floats.
  No real benefit rather than keeping API uniform.
- Optimized reconstructed camera search. It's optimized for
  playback, not random access.
- Added option to show projection of bundles into footage.
  To see bundles "Show Bundles" from Display panel should
  be enabled. Used very rough limit of 3 px to consider projection
  is fine. Colors are still hard-coded. Not sure it could be useful
  to make them configurable.
- Added option to mute footage. It could be useful to check
  if markers/bundles are moving smoothly.
- Added selector for focal length units.
This commit is contained in:
Sergey Sharybin 2011-07-11 09:04:00 +00:00
parent 1135dbcc36
commit 08bd300f0e
13 changed files with 282 additions and 36 deletions

@ -331,7 +331,7 @@ int libmv_reporojectionPointForTrack(libmv_Reconstruction *reconstruction, int t
return 0;
}
int libmv_reporojectionCameraForImage(libmv_Reconstruction *reconstruction, int image, float mat[4][4])
int libmv_reporojectionCameraForImage(libmv_Reconstruction *reconstruction, int image, double mat[4][4])
{
libmv::Camera *camera = ((libmv::Reconstruction *)reconstruction)->CameraForImage(image);
@ -368,3 +368,20 @@ void libmv_destroyReconstruction(libmv_Reconstruction *reconstruction)
delete (libmv::Reconstruction *)reconstruction;
}
/* ************ utils ************ */
void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
double x, double y, double *x1, double *y1)
{
libmv::CameraIntrinsics intrinsics;
intrinsics.SetFocalLength(focal_length);
intrinsics.set_principal_point(principal_x, principal_y);
intrinsics.set_radial_distortion(k1, k2, k3);
if(focal_length) {
/* do a lens undistortion if focal length is non-zero only */
intrinsics.ApplyIntrinsics(x, y, x1, y1);
}
}

@ -58,9 +58,13 @@ void libmv_tracksDestroy(struct libmv_Tracks *tracks);
struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2,
double focal_length, double principal_x, double principal_y, double k1, double k2, double k3);
int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *reconstruction, int track, double pos[3]);
int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *reconstruction, int image, float mat[4][4]);
int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *reconstruction, int image, double mat[4][4]);
void libmv_destroyReconstruction(struct libmv_Reconstruction *reconstruction);
/* utils */
void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
double x, double y, double *x1, double *y1);
#ifdef __cplusplus
}
#endif

@ -218,7 +218,11 @@ class CLIP_PT_tracking_camera(bpy.types.Panel):
sc = context.space_data
clip = sc.clip
layout.prop(clip.tracking.camera, "focal_length")
layout.prop(clip.tracking.camera, "sensor_width")
row = layout.row()
row.prop(clip.tracking.camera, "focal_length")
row.prop(clip.tracking.camera, "units", text="")
layout.label(text="Principal Point")
layout.prop(clip.tracking.camera, "principal", text="")
@ -249,6 +253,8 @@ class CLIP_PT_display(bpy.types.Panel):
row.prop(sc, "path_length")
layout.prop(sc, "show_tiny_markers")
layout.prop(sc, "show_bundles")
layout.prop(sc, "use_mute_footage")
class CLIP_PT_test(bpy.types.Panel):

@ -48,6 +48,7 @@ void BKE_movieclip_reload(struct MovieClip *clip);
struct ImBuf *BKE_movieclip_acquire_ibuf(struct MovieClip *clip, struct MovieClipUser *user);
void BKE_movieclip_acquire_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height);
void BKE_movieclip_approx_size(struct MovieClip *clip, int *width, int *height);
int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user);
void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr);

@ -75,6 +75,8 @@ struct MovieTrackingTrack *BKE_find_track_by_name(struct MovieTracking *tracking
struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
void BKE_get_tracking_mat(struct Scene *scene, float mat[4][4]);
void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]);
void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float width, float height, float nco[2]);
#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))

@ -214,6 +214,9 @@ static MovieClip *movieclip_alloc(const char *name)
clip= alloc_libblock(&G.main->movieclip, ID_MC, name);
clip->tracking.camera.sensor_width= 35.0f;
clip->tracking.camera.units= CAMERA_UNITS_MM;
clip->tracking.settings.frames_limit= 20;
clip->tracking.settings.keyframe1= 1;
clip->tracking.settings.keyframe2= 30;
@ -281,7 +284,6 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
ImBuf *ibuf= NULL;
int framenr= user?user->framenr:clip->lastframe;
clip->lastframe= framenr;
ibuf= get_imbuf_cache(clip, user);
if(!ibuf) {
@ -294,6 +296,9 @@ ImBuf *BKE_movieclip_acquire_ibuf(MovieClip *clip, MovieClipUser *user)
put_imbuf_cache(clip, user, ibuf);
}
if(ibuf)
clip->lastframe= framenr;
return ibuf;
}
@ -325,6 +330,29 @@ void BKE_movieclip_acquire_size(MovieClip *clip, MovieClipUser *user, int *width
IMB_freeImBuf(ibuf);
}
void BKE_movieclip_approx_size(MovieClip *clip, int *width, int *height)
{
ImBuf *ibuf= BKE_movieclip_acquire_ibuf(clip, NULL);
if(!ibuf) {
MovieClipUser user;
user.framenr= 0;
ibuf= BKE_movieclip_acquire_ibuf(clip, &user);
}
if(ibuf && ibuf->x && ibuf->y) {
*width= ibuf->x;
*height= ibuf->y;
} else {
*width= 0;
*height= 0;
}
if(ibuf)
IMB_freeImBuf(ibuf);
}
/* get segments of cached frames. useful for debugging cache policies */
void BKE_movieclip_get_cache_segments(MovieClip *clip, int *totseg_r, int **points_r)
{

@ -758,9 +758,16 @@ static void retrive_libmv_reconstruct(MovieClip *clip, struct libmv_Reconstructi
reconstructed= MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera");
for(a= sfra; a<=efra; a++) {
float mat[4][4];
double matd[4][4];
if(libmv_reporojectionCameraForImage(reconstruction, a, matd)) {
int i, j;
float mat[4][4];
for(i=0; i<4; i++)
for(j= 0; j<4; j++)
mat[i][j]= matd[i][j];
if(libmv_reporojectionCameraForImage(reconstruction, a, mat)) {
if(!origin_set) {
copy_v3_v3(origin, mat[3]);
origin_set= 1;
@ -838,11 +845,27 @@ MovieTrackingTrack *BKE_find_track_by_name(MovieTracking *tracking, const char *
MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr)
{
int a;
MovieTrackingCamera *camera= &tracking->camera;
int a= 0, d= 1;
for (a= 0; a<tracking->camera.reconnr; a++ ) {
if(tracking->camera.reconstructed[a].framenr==framenr)
return &tracking->camera.reconstructed[a];
if(!camera->reconnr)
return NULL;
if(camera->last_camera<camera->reconnr)
a= camera->last_camera;
if(camera->reconstructed[a].framenr>=framenr)
d= -1;
while(a>=0 && a<camera->reconnr) {
if(camera->reconstructed[a].framenr==framenr) {
camera->last_camera= a;
return &camera->reconstructed[a];
break;
}
a+= d;
}
return NULL;
@ -862,3 +885,56 @@ void BKE_get_tracking_mat(Scene *scene, float mat[4][4])
copy_m4_m4(mat, obmat);
}
void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4])
{
MovieReconstructedCamera *camera;
float lens= tracking->camera.focal*32.0f/(float)winx;
float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
float winmat[4][4];
clipsta= 0.1f;
clipend= 1000.0f;
if(winx >= winy)
viewfac= (lens*winx)/32.0f;
else
viewfac= (lens*winy)/32.0f;
pixsize= clipsta/viewfac;
left= -0.5f*(float)winx*pixsize;
bottom= -0.5f*(float)winy*pixsize;
right= 0.5f*(float)winx*pixsize;
top= 0.5f*(float)winy*pixsize;
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
camera= BKE_tracking_get_reconstructed_camera(tracking, framenr);
if(camera) {
float imat[4][4];
invert_m4_m4(imat, camera->mat);
mul_m4_m4m4(mat, imat, winmat);
} else copy_m4_m4(mat, winmat);
}
void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float width, float height, float nco[2])
{
MovieTrackingCamera *camera= &tracking->camera;
#ifdef WITH_LIBMV
double x= nco[0], y= nco[1];
/* normalize coords */
x= (co[0]-camera->principal[0]) / camera->focal;
y= (co[1]-camera->principal[1]) / camera->focal;
libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1],
camera->k1, camera->k2, camera->k3, x, y, &x, &y);
/* result is in image coords already */
nco[0]= x;
nco[1]= y;
#endif
}

@ -141,7 +141,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
glRecti(x, 0, x+framelen, 8);
}
static void draw_movieclip_buffer(ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, float zoomx, float zoomy)
{
int x, y;
@ -151,11 +151,16 @@ static void draw_movieclip_buffer(ARegion *ar, ImBuf *ibuf, float zoomx, float z
/* find window pixel coordinates of origin */
UI_view2d_to_region_no_clip(&ar->v2d, 0.f, 0.f, &x, &y);
if(ibuf->rect_float)
IMB_rect_from_float(ibuf);
if(sc->flag&SC_MUTE_FOOTAGE) {
glColor3f(0.0f, 0.0f, 0.0f);
glRectf(x, y, x+ibuf->x*sc->zoom, y+ibuf->y*sc->zoom);
} else {
if(ibuf->rect_float)
IMB_rect_from_float(ibuf);
if(ibuf->rect)
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
if(ibuf->rect)
glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
}
/* reset zoom */
glPixelZoom(1.f, 1.f);
@ -482,9 +487,10 @@ static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx
static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, float zoomx, float zoomy)
{
float x, y;
MovieTracking* tracking= &clip->tracking;
MovieTrackingMarker *marker;
MovieTrackingTrack *track;
int width, height, sel_type;
int width, height, sel_type, framenr= sc->user.framenr;
void *sel;
ED_space_clip_size(sc, &width, &height);
@ -509,7 +515,7 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
BKE_movieclip_last_selection(clip, &sel_type, &sel);
if(sc->flag&SC_SHOW_MARKER_PATH) {
track= clip->tracking.tracks.first;
track= tracking->tracks.first;
while(track) {
if((track->flag&TRACK_HIDDEN)==0)
draw_track_path(sc, clip, track);
@ -519,10 +525,10 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
}
/* markers outline and non-selected areas */
track= clip->tracking.tracks.first;
track= tracking->tracks.first;
while(track) {
if((track->flag&TRACK_HIDDEN)==0) {
marker= BKE_tracking_get_marker(track, sc->user.framenr);
marker= BKE_tracking_get_marker(track, framenr);
draw_marker_outline(sc, track, marker);
draw_marker_slide_zones(sc, track, marker, 1, 0, width, height);
@ -534,13 +540,13 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
/* selected areas only, so selection wouldn't be overlapped by
non-selected areas */
track= clip->tracking.tracks.first;
track= tracking->tracks.first;
while(track) {
if((track->flag&TRACK_HIDDEN)==0) {
int act= sel_type==MCLIP_SEL_TRACK && sel==track;
if(!act) {
marker= BKE_tracking_get_marker(track, sc->user.framenr);
marker= BKE_tracking_get_marker(track, framenr);
draw_marker_areas(sc, track, marker, 0, 1);
draw_marker_slide_zones(sc, track, marker, 0, 0, width, height);
}
@ -552,12 +558,54 @@ static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, fl
/* active marker would be displayed on top of everything else */
if(sel_type==MCLIP_SEL_TRACK) {
if((((MovieTrackingTrack *)sel)->flag&TRACK_HIDDEN)==0) {
marker= BKE_tracking_get_marker(sel, sc->user.framenr);
marker= BKE_tracking_get_marker(sel, framenr);
draw_marker_areas(sc, sel, marker, 1, 1);
draw_marker_slide_zones(sc, sel, marker, 0, 1, width, height);
}
}
if(sc->flag&SC_SHOW_BUNDLES) {
float pos[4], vec[4], mat[4][4];
glEnable(GL_POINT_SMOOTH);
glPointSize(3.0f);
BKE_tracking_projection_matrix(tracking, framenr, width, height, mat);
track= tracking->tracks.first;
while(track) {
if(track->flag&TRACK_HAS_BUNDLE) {
marker= BKE_tracking_get_marker(track, framenr);
copy_v4_v4(vec, track->bundle_pos);
vec[3]=1;
mul_v4_m4v4(pos, mat, vec);
pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width;
pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height;
BKE_tracking_apply_intrinsics(tracking, pos, width, height, pos);
vec[0]= marker->pos[0]*width;
vec[1]= marker->pos[1]*height;
sub_v2_v2(vec, pos);
if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f);
else glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_POINTS);
glVertex3f(pos[0]/width, pos[1]/height, 0);
glEnd();
}
track= track->next;
}
glPointSize(1.0f);
glDisable(GL_POINT_SMOOTH);
}
glPopMatrix();
}
@ -581,7 +629,7 @@ void draw_clip_main(SpaceClip *sc, ARegion *ar, Scene *scene)
ibuf= ED_space_clip_acquire_buffer(sc);
if(ibuf) {
draw_movieclip_buffer(ar, ibuf, zoomx, zoomy);
draw_movieclip_buffer(sc, ar, ibuf, zoomx, zoomy);
IMB_freeImBuf(ibuf);
draw_tracking(sc, ar, clip, zoomx, zoomy);

@ -965,6 +965,8 @@ enum {
#define SC_LOCK_SELECTION (1<<2)
#define SC_SHOW_TINY_MARKER (1<<3)
#define SC_SHOW_MARKER_PATH (1<<4)
#define SC_SHOW_BUNDLES (1<<5)
#define SC_MUTE_FOOTAGE (1<<6)
/* space types, moved from DNA_screen_types.h */

@ -54,10 +54,13 @@ typedef struct MovieReconstructedCamera {
} MovieReconstructedCamera;
typedef struct MovieTrackingCamera {
float sensor_width; /* width of CCD sensor */
float focal; /* focal length */
short units; /* units of focal length user is working with */
short pad;
float principal[2]; /* principal point */
float k1, k2, k3; /* radial distortion */
float pad;
int last_camera; /* most recently used camera */
int reconnr; /* number of reconstructed cameras */
struct MovieReconstructedCamera *reconstructed; /* reconstructed cameras */
} MovieTrackingCamera;
@ -105,6 +108,12 @@ typedef struct MovieTracking {
ListBase tracks;
} MovieTracking;
/* MovieTrackingCamera->units */
enum {
CAMERA_UNITS_PX = 0,
CAMERA_UNITS_MM
};
/* MovieTrackingMarker->flag */
#define MARKER_DISABLED 1

@ -62,19 +62,12 @@ static void rna_MovieClip_reload_update(Main *bmain, Scene *scene, PointerRNA *p
static void rna_MovieClip_size_get(PointerRNA *ptr, int *values)
{
MovieClip *clip= (MovieClip*)ptr->data;
ImBuf *ibuf;
int width, height;
ibuf= BKE_movieclip_acquire_ibuf(clip, NULL);
if (ibuf) {
values[0]= ibuf->x;
values[1]= ibuf->y;
BKE_movieclip_approx_size(clip, &width, &height);
IMB_freeImBuf(ibuf);
}
else {
values[0]= 0;
values[1]= 0;
}
values[0]= height;
values[1]= width;
}
static void rna_MovieClip_resolution_get(PointerRNA *ptr, float *values)

@ -2676,6 +2676,18 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Tiny Markers", "Show markers tiny");
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_TINY_MARKER);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
/* show bundles */
prop= RNA_def_property(srna, "show_bundles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Show Bundles", "Show projection of bundles into footage");
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_SHOW_BUNDLES);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
/* mute footage */
prop= RNA_def_property(srna, "use_mute_footage", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_ui_text(prop, "Mute Footage", "Mute footage and show black background instead");
RNA_def_property_boolean_sdna(prop, NULL, "flag", SC_MUTE_FOOTAGE);
RNA_def_property_update(prop, NC_SPACE|ND_SPACE_CLIP, NULL);
}
void RNA_def_space(BlenderRNA *brna)

@ -116,6 +116,29 @@ static PointerRNA rna_tracking_active_track_get(PointerRNA *ptr)
return rna_pointer_inherit_refine(ptr, &RNA_SceneRenderLayer, NULL);
}
static float rna_trackingCamera_focal_get(PointerRNA *ptr)
{
MovieClip *clip= (MovieClip*)ptr->id.data;
MovieTrackingCamera *camera= &clip->tracking.camera;
float val= camera->focal;
if(camera->units==CAMERA_UNITS_MM) {
int width, height;
BKE_movieclip_approx_size(clip, &width, &height);
if(width)
val= val*camera->sensor_width/(float)width;
}
return val;
}
static void rna_trackingCamera_focal_set(PointerRNA *ptr, float value)
{
MovieClip *clip= (MovieClip*)ptr->id.data;
}
#else
static void rna_def_trackingSettings(BlenderRNA *brna)
@ -124,7 +147,7 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
PropertyRNA *prop;
static EnumPropertyItem speed_items[] = {
{0, "FASTEST", 0, "Fastest", "track as fast as it's possible"},
{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"},
@ -170,33 +193,58 @@ static void rna_def_trackingCamera(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
static EnumPropertyItem camera_units_items[] = {
{CAMERA_UNITS_PX, "PIXELS", 0, "Pixels", "Use pixels for units of focal length"},
{CAMERA_UNITS_MM, "MILLIMETERS", 0, "Millimeters", "Use millimeters for units of focal length"},
{0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "MovieTrackingCamera", NULL);
RNA_def_struct_ui_text(srna, "Movie tracking camera data", "Match-moving camera data for tracking");
/* Sensor Wdth */
prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sensor_width");
RNA_def_property_range(prop, 0.0f, 500.0f);
RNA_def_property_ui_text(prop, "Sensor Width", "Width of CCD sensor in millimeters");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* Focal Length */
prop= RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "focal");
RNA_def_property_range(prop, 0.0f, 5000.0f);
RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length in pixels");
RNA_def_property_float_funcs(prop, "rna_trackingCamera_focal_get", "rna_trackingCamera_focal_set", NULL);
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* Units */
prop= RNA_def_property(srna, "units", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "units");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_enum_items(prop, camera_units_items);
RNA_def_property_ui_text(prop, "Units", "Units used for camera focal length");
/* Principal Point */
prop= RNA_def_property(srna, "principal", PROP_FLOAT, PROP_NONE);
RNA_def_property_array(prop, 2);
RNA_def_property_float_sdna(prop, NULL, "principal");
RNA_def_property_ui_text(prop, "Principal Point", "Optical center of lens");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
/* Radial distortion parameters */
prop= RNA_def_property(srna, "k1", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "k1");
RNA_def_property_ui_text(prop, "K1", "");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "k2");
RNA_def_property_ui_text(prop, "K2", "");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "k3");
RNA_def_property_ui_text(prop, "K3", "");
RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL);
}
static void rna_def_trackingMarker(BlenderRNA *brna)