Camera tracking: wall scene orientation operator
[blender-staging.git] / source / blender / editors / space_clip / tracking_ops.c
index d6940d14dbf1c0a15bf6d56e982391d9f4b8512c..68b98ce756cd3a68c306c372519ee62a03d00b16 100644 (file)
@@ -334,7 +334,7 @@ static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTra
 }
 
 /* corner = 0: right-bottom corner,
  corner = 1: left-top corner */
* corner = 1: left-top corner */
 static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
                        int area, float co[2], int corner, int width, int height)
 {
@@ -1014,6 +1014,7 @@ static int select_all_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        MovieTrackingTrack *track= NULL;        /* selected track */
+       MovieTrackingMarker *marker;
        ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        int action= RNA_enum_get(op->ptr, "action");
        int framenr= sc->user.framenr;
@@ -1024,8 +1025,12 @@ static int select_all_exec(bContext *C, wmOperator *op)
                track= tracksbase->first;
                while(track) {
                        if(TRACK_VIEW_SELECTED(sc, track)) {
-                               action= SEL_DESELECT;
-                               break;
+                               marker= BKE_tracking_get_marker(track, framenr);
+
+                               if(MARKER_VISIBLE(sc, marker)) {
+                                       action= SEL_DESELECT;
+                                       break;
+                               }
                        }
 
                        track= track->next;
@@ -1035,9 +1040,9 @@ static int select_all_exec(bContext *C, wmOperator *op)
        track= tracksbase->first;
        while(track) {
                if((track->flag&TRACK_HIDDEN)==0) {
-                       MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
+                       marker= BKE_tracking_get_marker(track, framenr);
 
-                       if(marker && MARKER_VISIBLE(sc, marker)) {
+                       if(MARKER_VISIBLE(sc, marker)) {
                                switch (action) {
                                        case SEL_SELECT:
                                                track->flag|= SELECT;
@@ -1138,8 +1143,8 @@ static int select_groped_exec(bContext *C, wmOperator *op)
 
                if(ok) {
                        track->flag|= SELECT;
-                       if(sc->flag&SC_SHOW_MARKER_PATTERN) track->pat_flag|= SELECT;;
-                       if(sc->flag&SC_SHOW_MARKER_SEARCH) track->search_flag|= SELECT;;
+                       if(sc->flag&SC_SHOW_MARKER_PATTERN) track->pat_flag|= SELECT;
+                       if(sc->flag&SC_SHOW_MARKER_SEARCH) track->search_flag|= SELECT;
                }
 
                track= track->next;
@@ -1208,7 +1213,7 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip)
        track= tracksbase->first;
        while(track) {
                if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) {
-                       MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, framenr);
+                       MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr);
 
                        if (!marker || (marker->flag&MARKER_DISABLED) == 0)
                                tot++;
@@ -1220,22 +1225,41 @@ static int track_count_markers(SpaceClip *sc, MovieClip *clip)
        return tot;
 }
 
+static void clear_invisible_track_selection(SpaceClip *sc, MovieClip *clip)
+{
+       ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
+       int hidden = 0;
+
+       if ((sc->flag&SC_SHOW_MARKER_PATTERN)==0)
+               hidden |= TRACK_AREA_PAT;
+
+       if ((sc->flag&SC_SHOW_MARKER_SEARCH)==0)
+               hidden |= TRACK_AREA_SEARCH;
+
+       if (hidden) {
+               MovieTrackingTrack *track = tracksbase->first;
+
+               while(track) {
+                       if ((track->flag & TRACK_HIDDEN) == 0)
+                               BKE_tracking_track_flag(track, hidden, SELECT, 1);
+
+                       track = track->next;
+               }
+       }
+}
+
 static void track_init_markers(SpaceClip *sc, MovieClip *clip, int *frames_limit_r)
 {
        ListBase *tracksbase= BKE_tracking_get_tracks(&clip->tracking);
        MovieTrackingTrack *track;
-       int framenr= sc->user.framenr, hidden= 0;
+       int framenr= sc->user.framenr;
        int frames_limit= 0;
 
-       if((sc->flag&SC_SHOW_MARKER_PATTERN)==0) hidden|= TRACK_AREA_PAT;
-       if((sc->flag&SC_SHOW_MARKER_SEARCH)==0) hidden|= TRACK_AREA_SEARCH;
+       clear_invisible_track_selection(sc, clip);
 
        track= tracksbase->first;
        while(track) {
-               if(hidden)
-                       BKE_tracking_track_flag(track, hidden, SELECT, 1);
-
-               if(TRACK_SELECTED(track)) {
+               if(TRACK_VIEW_SELECTED(sc, track)) {
                        if((track->flag&TRACK_HIDDEN)==0 && (track->flag&TRACK_LOCKED)==0) {
                                BKE_tracking_ensure_marker(track, framenr);
 
@@ -1303,11 +1327,11 @@ static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backward
 
        tmj->lastfra= tmj->sfra;
 
-       /* 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). */
+       /* XXX: silly to store this, but this data is needed to update scene and movie-clip
+        *      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);
@@ -1324,10 +1348,10 @@ static void track_markers_startjob(void *tmv, short *stop, short *do_update, flo
        while(framenr != tmj->efra) {
                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 */
+                        * 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;
 
@@ -1469,9 +1493,9 @@ static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
        WM_jobs_customdata(steve, tmj, track_markers_freejob);
 
        /* 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. */
+        * 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);
 
@@ -2224,7 +2248,7 @@ static void set_axis(Scene *scene,  Object *ob, MovieClip *clip, MovieTrackingOb
        object_apply_mat4(ob, mat, 0, 0);
 }
 
-static int set_floor_exec(bContext *C, wmOperator *op)
+static int set_plane_exec(bContext *C, wmOperator *op)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
@@ -2237,6 +2261,7 @@ static int set_floor_exec(bContext *C, wmOperator *op)
        Object *camera= get_camera_with_movieclip(scene, clip);
        int tot= 0;
        float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3]= {0.0f, 0.0f, 0.0f};
+       int plane= RNA_enum_get(op->ptr, "plane");
        float rot[4][4]={{0.0f, 0.0f, -1.0f, 0.0f},
                         {0.0f, 1.0f, 0.0f, 0.0f},
                         {1.0f, 0.0f, 0.0f, 0.0f},
@@ -2284,9 +2309,16 @@ static int set_floor_exec(bContext *C, wmOperator *op)
        /* construct ortho-normal basis */
        unit_m4(mat);
 
-       cross_v3_v3v3(mat[0], vec[1], vec[2]);
-       copy_v3_v3(mat[1], vec[1]);
-       cross_v3_v3v3(mat[2], mat[0], mat[1]);
+       if (plane == 0) { /* floor */
+               cross_v3_v3v3(mat[0], vec[1], vec[2]);
+               copy_v3_v3(mat[1], vec[1]);
+               cross_v3_v3v3(mat[2], mat[0], mat[1]);
+       }
+       else if (plane == 1) { /* wall */
+               cross_v3_v3v3(mat[2], vec[1], vec[2]);
+               copy_v3_v3(mat[1], vec[1]);
+               cross_v3_v3v3(mat[0], mat[1], mat[2]);
+       }
 
        normalize_v3(mat[0]);
        normalize_v3(mat[1]);
@@ -2328,19 +2360,28 @@ static int set_floor_exec(bContext *C, wmOperator *op)
        return OPERATOR_FINISHED;
 }
 
-void CLIP_OT_set_floor(wmOperatorType *ot)
+void CLIP_OT_set_plane(wmOperatorType *ot)
 {
+       static EnumPropertyItem plane_items[] = {
+                       {0, "FLOOR", 0, "Floor", "Set floor plane"},
+                       {1, "WALL", 0, "Wall", "Set wall plane"},
+                       {0, NULL, 0, NULL, NULL}
+       };
+
        /* identifiers */
-       ot->name= "Set Floor";
-       ot->description= "Set floor based on 3 selected bundles by moving camera (or it's parent if present) in 3D space";
-       ot->idname= "CLIP_OT_set_floor";
+       ot->name= "Set Plane";
+       ot->description= "Set plane based on 3 selected bundles by moving camera (or it's parent if present) in 3D space";
+       ot->idname= "CLIP_OT_set_plane";
 
        /* api callbacks */
-       ot->exec= set_floor_exec;
+       ot->exec= set_plane_exec;
        ot->poll= set_orientation_poll;
 
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       RNA_def_enum(ot->srna, "plane", plane_items, 0, "Plane", "Plane to be sued for orientation");
 }
 
 /********************** set axis operator *********************/
@@ -2502,9 +2543,8 @@ static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       float dist= RNA_float_get(op->ptr, "distance");
 
-       if(dist==0.0f)
+       if(!RNA_struct_property_is_set(op->ptr, "distance"))
                RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist);
 
        return set_scale_exec(C, op);
@@ -2555,9 +2595,8 @@ static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSE
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       float dist= RNA_float_get(op->ptr, "distance");
 
-       if(dist==0.0f)
+       if(!RNA_struct_property_is_set(op->ptr, "distance"))
                RNA_float_set(op->ptr, "distance", clip->tracking.settings.object_distance);
 
        return set_solution_scale_exec(C, op);
@@ -2736,7 +2775,7 @@ static int detect_features_exec(bContext *C, wmOperator *op)
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        int clip_flag= clip->flag&MCLIP_TIMECODE_FLAGS;
-       ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag);
+       ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, clip_flag, MOVIECLIP_CACHE_SKIP);
        MovieTracking *tracking= &clip->tracking;
        ListBase *tracksbase= BKE_tracking_get_tracks(tracking);
        MovieTrackingTrack *track= tracksbase->first;
@@ -3310,7 +3349,7 @@ static int is_track_clean(MovieTrackingTrack *track, int frames, int del)
                                }
                                else if(markers[a].flag&MARKER_DISABLED) {
                                        /* current segment which would be deleted was finished by disabled marker,
-                                          so next segment should be started from disabled marker */
+                                        * so next segment should be started from disabled marker */
                                        start_disabled= 1;
                                }
                        }
@@ -3396,15 +3435,15 @@ static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
-       int frames= RNA_int_get(op->ptr, "frames");
-       float error= RNA_float_get(op->ptr, "error");
-       int action= RNA_enum_get(op->ptr, "action");
 
-       if(frames==0 && error==0 && action==0) {
+       if(!RNA_struct_property_is_set(op->ptr, "frames"))
                RNA_int_set(op->ptr, "frames", clip->tracking.settings.clean_frames);
+
+       if(!RNA_struct_property_is_set(op->ptr, "error"))
                RNA_float_set(op->ptr, "error", clip->tracking.settings.clean_error);
+
+       if(!RNA_struct_property_is_set(op->ptr, "action"))
                RNA_enum_set(op->ptr, "action", clip->tracking.settings.clean_action);
-       }
 
        return clean_tracks_exec(C, op);
 }
@@ -3504,3 +3543,74 @@ void CLIP_OT_tracking_object_remove(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
+
+/********************** copy tracks to clipboard operator *********************/
+
+static int copy_tracks_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+       MovieTracking *tracking = &clip->tracking;
+       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+
+       clear_invisible_track_selection(sc, clip);
+
+       BKE_tracking_clipboard_copy_tracks(tracking, object);
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_copy_tracks(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Copy Tracks";
+       ot->description = "Copy selected tracks to clipboard";
+       ot->idname = "CLIP_OT_copy_tracks";
+
+       /* api callbacks */
+       ot->exec = copy_tracks_exec;
+       ot->poll = ED_space_clip_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER;
+}
+
+/********************** paste tracks from clipboard operator *********************/
+
+static int paste_tracks_poll(bContext *C)
+{
+       if (ED_space_clip_poll(C)) {
+               return BKE_tracking_clipboard_has_tracks();
+       }
+
+       return 0;
+}
+
+static int paste_tracks_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       SpaceClip *sc = CTX_wm_space_clip(C);
+       MovieClip *clip = ED_space_clip(sc);
+       MovieTracking *tracking = &clip->tracking;
+       MovieTrackingObject *object = BKE_tracking_active_object(tracking);
+
+       BKE_tracking_clipboard_paste_tracks(tracking, object);
+
+       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip);
+
+       return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_paste_tracks(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Paste Tracks";
+       ot->description = "Paste tracks from clipboard";
+       ot->idname = "CLIP_OT_paste_tracks";
+
+       /* api callbacks */
+       ot->exec = paste_tracks_exec;
+       ot->poll = paste_tracks_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}