Masking support for motion tracks
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 12 Jun 2012 11:13:53 +0000 (11:13 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 12 Jun 2012 11:13:53 +0000 (11:13 +0000)
Added option to use Grease Pencil datablock as a mask for pattern
when doing motion tracking. Option could be found in Tracking Settings
panel.

All strokes would be rasterized separately from each other and every
stroke is treating as a closed spline.

Also added option to apply a mask on track preview which is situated
just after B/B/W channel button under track preview.

14 files changed:
extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
extern/libmv/libmv/tracking/track_region.cc
extern/libmv/libmv/tracking/track_region.h
release/scripts/startup/bl_ui/space_clip.py
source/blender/blenkernel/BKE_tracking.h
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/tracking.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/space_clip/space_clip.c
source/blender/makesdna/DNA_movieclip_types.h
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_tracking.c

index 8751e1e190b5595b0ba6a72b390fa1e54e2f6193..3d3b7398c9bc23aedf766ee168c63b22dc11820c 100644 (file)
@@ -243,7 +243,7 @@ void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int
        fclose(fp);
 }
 
-static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
+static void saveImage(const char *prefix, libmv::FloatImage image, int x0, int y0)
 {
        int x, y;
        png_bytep *row_pointers;
@@ -283,7 +283,7 @@ static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
        free(row_pointers);
 }
 
-static void saveBytesImage(char *prefix, unsigned char *data, int width, int height)
+static void saveBytesImage(const char *prefix, unsigned char *data, int width, int height)
 {
        int x, y;
        png_bytep *row_pointers;
@@ -376,6 +376,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
        }
 
        libmv::TrackRegionOptions track_region_options;
+       libmv::FloatImage image1_mask;
+
        switch (options->motion_model) {
 #define LIBMV_CONVERT(the_model) \
     case libmv::TrackRegionOptions::the_model: \
@@ -398,6 +400,12 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
        track_region_options.use_brute_initialization = options->use_brute;
        track_region_options.use_normalized_intensities = options->use_normalization;
 
+       if (options->image1_mask) {
+               floatBufToImage(options->image1_mask, image1_width, image1_height, 1, &image1_mask);
+
+               track_region_options.image1_mask = &image1_mask;
+       }
+
        /* Convert from raw float buffers to libmv's FloatImage. */
        libmv::FloatImage old_patch, new_patch;
        floatBufToImage(image1, image1_width, image1_height, 1, &old_patch);
@@ -437,15 +445,24 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
 
 void libmv_samplePlanarPatch(const float *image, int width, int height,
                              int channels, const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y, float *patch,
+                             int num_samples_x, int num_samples_y,
+                             const float *mask, float *patch,
                              double *warped_position_x, double *warped_position_y)
 {
-       libmv::FloatImage libmv_image, libmv_patch;
+       libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
+       libmv::FloatImage *libmv_mask_for_sample = NULL;
 
        floatBufToImage(image, width, height, channels, &libmv_image);
 
+       if (mask) {
+               floatBufToImage(mask, width, height, 1, &libmv_mask);
+
+               libmv_mask_for_sample = &libmv_mask;
+       }
+
        libmv::SamplePlanarPatch(libmv_image, xs, ys, num_samples_x, num_samples_y,
-                                &libmv_patch, warped_position_x, warped_position_y);
+                                libmv_mask_for_sample, &libmv_patch,
+                                warped_position_x, warped_position_y);
 
        imageToFloatBuf(&libmv_patch, channels, patch);
 }
index fe759b06fe436b5043e25d628153eb6e372ede64..fc3b6f94f62de582332ee3c2fe49707930c59809 100644 (file)
@@ -52,18 +52,21 @@ void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
 
 /* TrackRegion (new planar tracker) */
 struct libmv_trackRegionOptions {
-  int motion_model;
-  int num_iterations;
-  int use_brute;
-  int use_normalization;
-  double minimum_correlation;
-  double sigma;
+       int motion_model;
+       int num_iterations;
+       int use_brute;
+       int use_normalization;
+       double minimum_correlation;
+       double sigma;
+       float *image1_mask;
 };
+
 struct libmv_trackRegionResult {
-  int termination;
-  const char *termination_reason;
-  double correlation;
+       int termination;
+       const char *termination_reason;
+       double correlation;
 };
+
 int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
                       const float *image1, int image1_width, int image1_height,
                       const float *image2, int image2_width, int image2_height,
@@ -73,7 +76,8 @@ int libmv_trackRegion(const struct libmv_trackRegionOptions *options,
 
 void libmv_samplePlanarPatch(const float *image, int width, int height,
                              int channels, const double *xs, const double *ys,
-                             int num_samples_x, int num_samples_y, float *patch,
+                             int num_samples_x, int num_samples_y,
+                             const float *mask, float *patch,
                              double *warped_position_x, double *warped_position_y);
 
 /* Tracks */
index e65ead50c80bac0140feeb71f170bd6fd6918030..f52919b2a616a5debfa876bd4be1b70dded5d5cf 100644 (file)
@@ -1351,7 +1351,7 @@ void TrackRegion(const FloatImage &image1,
 bool SamplePlanarPatch(const FloatImage &image,
                        const double *xs, const double *ys,
                        int num_samples_x, int num_samples_y,
-                       FloatImage *patch,
+                       FloatImage *mask, FloatImage *patch,
                        double *warped_position_x, double *warped_position_y) {
   // Bail early if the points are outside the image.
   if (!AllInBounds(image, xs, ys)) {
@@ -1376,6 +1376,13 @@ bool SamplePlanarPatch(const FloatImage &image,
       SampleLinear(image, image_position(1),
                    image_position(0),
                    &(*patch)(r, c, 0));
+      if (mask) {
+        float maskValue = SampleLinear(*mask, image_position(1),
+                                       image_position(0), 0);
+
+        for (int d = 0; d < image.Depth(); d++)
+          (*patch)(r, c, d) *= maskValue;
+      }
     }
   }
 
index 0de11239da69b382d8b081a5326d9753e7c35262..22ecfc54a15ba9de1293711d60e7eedf761df2b7 100644 (file)
@@ -135,10 +135,14 @@ void TrackRegion(const FloatImage &image1,
 // pixels of border around them. (so e.g. a corner of the patch cannot lie
 // directly on the edge of the image). Four corners are always required. All
 // channels are interpolated.
+// When mask is not null it'll be used as a pattern mask. Ot should match
+// the size of image.
+// Warped coordinates of marker's position would be returned in
+// warped_position_x and warped_position_y
 bool SamplePlanarPatch(const FloatImage &image,
                        const double *xs, const double *ys,
                        int num_samples_x, int num_samples_y,
-                       FloatImage *patch,
+                       FloatImage *mask, FloatImage *patch,
                        double *warped_position_x, double *warped_position_y);
 
 }  // namespace libmv
index 9ab8fcb5655c8c5890dbf458d85bda7a9c22d106..2f2d95f78df7599f768e54ed32d495263b386a99 100644 (file)
@@ -233,6 +233,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
             col.prop(settings, "default_motion_model")
             col.prop(settings, "default_use_brute")
             col.prop(settings, "default_use_normalization")
+            col.prop(settings, "default_use_mask")
             col.prop(settings, "default_correlation_min")
 
             col.separator()
@@ -541,6 +542,10 @@ class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
         sub = row.row()
         sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
 
+        row.separator()
+        sub = row.row()
+        sub.prop(act_track, "use_alpha_preview", text="", toggle=True, icon='IMAGE_ALPHA')
+
         layout.separator()
 
         row = layout.row(align=True)
@@ -580,6 +585,7 @@ class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
             col.prop(active, "motion_model")
             col.prop(active, "use_brute")
             col.prop(active, "use_normalization")
+            col.prop(active, "use_mask")
             col.prop(active, "correlation_min")
 
             col.separator()
index 716b65408e10706954e9d1ee3315296cd1347215..11013d549513373d4ee61d36159e2f3ae7d736e3 100644 (file)
@@ -72,14 +72,15 @@ void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct Movie
 void BKE_tracking_free(struct MovieTracking *tracking);
 
 struct ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
-                                                struct ImBuf *struct_ibuf, struct MovieTrackingMarker *marker,
+                                                struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
+                                                struct MovieTrackingMarker *marker, int use_mask,
                                                 int num_samples_x, int num_samples_y, float pos[2]);
 struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
                                              struct MovieTrackingMarker *marker, int anchored, int disable_channels);
 struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
                                             struct MovieTrackingMarker *marker, int anchored, int disable_channels);
-struct ImBuf *BKE_tracking_track_mask_get(struct MovieTracking *tracking, struct MovieTrackingTrack *track,
-                                          struct MovieTrackingMarker *marker, int width, int height);
+float *BKE_tracking_track_mask_get(int frame_width, int frame_height, struct MovieTrackingTrack *track,
+                                   struct MovieTrackingMarker *marker);
 
 void BKE_track_unique_name(struct ListBase *tracksbase, struct MovieTrackingTrack *track);
 
index 8b91ee29c59d950833313f87e7de0264d2b948b2..92184a386951630f6d2bafd53ad0b15ab15e8f5b 100644 (file)
@@ -1039,6 +1039,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
 
        scopes->marker = NULL;
        scopes->track = NULL;
+       scopes->track_locked = TRUE;
 
        if (clip) {
                MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
@@ -1055,6 +1056,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
                                ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user);
 
                                scopes->track_disabled = FALSE;
+                               scopes->marker = marker;
+                               scopes->track = track;
 
                                if (ibuf && (ibuf->rect || ibuf->rect_float)) {
                                        ImBuf *search_ibuf;
@@ -1087,6 +1090,8 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
 
                                        scopes->frame_width = ibuf->x;
                                        scopes->frame_height = ibuf->y;
+
+                                       scopes->use_track_mask = track->flag & TRACK_PREVIEW_ALPHA;
                                }
 
                                IMB_freeImBuf(ibuf);
@@ -1095,8 +1100,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
                        if ((track->flag & TRACK_LOCKED) == 0) {
                                float pat_min[2], pat_max[2];
 
-                               scopes->marker = marker;
-                               scopes->track = track;
+                               scopes->track_locked = FALSE;
 
                                /* XXX: would work fine with non-transformed patterns, but would likely fail
                                 *      with transformed patterns, but that would be easier to debug when
index 4cfa8461f2e399f0568202fd6f7bbc6a72c27c8d..a9e754498117826a6f8558d3aac078faf18d43f4 100644 (file)
@@ -1052,6 +1052,8 @@ typedef struct TrackContext {
        int search_area_height;
        int search_area_width;
        int framenr;
+
+       float *mask;
 #else
        int pad;
 #endif
@@ -1158,6 +1160,9 @@ static void track_context_free(void *customdata)
        if (track_context->search_area)
                MEM_freeN(track_context->search_area);
 
+       if (track_context->mask)
+               MEM_freeN(track_context->mask);
+
 #else
        (void)track_context;
 #endif
@@ -1244,14 +1249,16 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g
                                            track->flag & TRACK_DISABLE_GREEN, track->flag & TRACK_DISABLE_BLUE, grayscale);
 }
 
-ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
-                                         ImBuf *search_ibuf, MovieTrackingMarker *marker,
-                                         int num_samples_x, int num_samples_y, float pos[2])
+ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height, ImBuf *search_ibuf,
+                                         MovieTrackingTrack *track, MovieTrackingMarker *marker,
+                                         int use_mask, int num_samples_x, int num_samples_y,
+                                         float pos[2])
 {
 #ifdef WITH_LIBMV
        ImBuf *pattern_ibuf;
        double src_pixel_x[5], src_pixel_y[5];
        double warped_position_x, warped_position_y;
+       float *mask = NULL;
 
        pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
        pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB;
@@ -1262,9 +1269,13 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
 
        get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
 
+       if (use_mask) {
+               mask = BKE_tracking_track_mask_get(frame_width, frame_height, track, marker);
+       }
+
        libmv_samplePlanarPatch(search_ibuf->rect_float, search_ibuf->x, search_ibuf->y, 4,
                                src_pixel_x, src_pixel_y, num_samples_x,
-                               num_samples_y, pattern_ibuf->rect_float,
+                               num_samples_y, mask, pattern_ibuf->rect_float,
                                &warped_position_x, &warped_position_y);
 
        if (pos) {
@@ -1272,6 +1283,10 @@ ImBuf *BKE_tracking_sample_pattern_imbuf(int frame_width, int frame_height,
                pos[1] = warped_position_y;
        }
 
+       if (mask) {
+               MEM_freeN(mask);
+       }
+
        return pattern_ibuf;
 #else
        ImBuf *pattern_ibuf;
@@ -1310,8 +1325,8 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo
 
        search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
 
-       pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, marker,
-                                                        num_samples_x, num_samples_y, NULL);
+       pattern_ibuf = BKE_tracking_sample_pattern_imbuf(ibuf->x, ibuf->y, search_ibuf, track, marker,
+                                                        FALSE, num_samples_x, num_samples_y, NULL);
 
        IMB_freeImBuf(search_ibuf);
 
@@ -1366,8 +1381,21 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
        layer = track->gpd->layers.first;
 
        while (layer) {
-               if (layer->flag & GP_LAYER_ACTIVE)
-                       return layer;
+               if (layer->flag & GP_LAYER_ACTIVE) {
+                       bGPDframe *frame = layer->frames.first;
+                       int ok = FALSE;
+
+                       while (frame) {
+                               if (frame->strokes.first) {
+                                       ok = TRUE;
+                               }
+
+                               frame = frame->next;
+                       }
+
+                       if (ok)
+                               return layer;
+               }
 
                layer = layer->next;
        }
@@ -1375,15 +1403,11 @@ static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
        return NULL;
 }
 
-static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTrackingMarker *marker,
-                                               bGPDlayer *layer, ImBuf *ibuf, int width, int height)
+static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
+                                                                                          MovieTrackingMarker *marker, bGPDlayer *layer,
+                                               float *mask, int mask_width, int mask_height)
 {
        bGPDframe *frame = layer->frames.first;
-       float *mask;
-       int x, y;
-       float aspy = 1.0f / tracking->camera.pixel_aspect;
-
-       mask = MEM_callocN(ibuf->x * ibuf->y * sizeof(float), "track mask");
 
        while (frame) {
                bGPDstroke *stroke = frame->strokes.first;
@@ -1398,11 +1422,11 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra
                                                               "track mask rasterization points");
 
                                for (i = 0; i < stroke->totpoints; i++, fp += 2) {
-                                       fp[0] = stroke_points[i].x * width / ibuf->x - marker->search_min[0];
-                                       fp[1] = stroke_points[i].y * height * aspy / ibuf->x - marker->search_min[1];
+                                       fp[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width / mask_width;
+                                       fp[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height / mask_height;
                                }
 
-                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, ibuf->x, ibuf->y);
+                               PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height);
 
                                MEM_freeN(mask_points);
                        }
@@ -1412,45 +1436,26 @@ static void track_mask_gpencil_layer_rasterize(MovieTracking *tracking, MovieTra
 
                frame = frame->next;
        }
-
-       for (y = 0; y < ibuf->y; y++) {
-               for (x = 0; x < ibuf->x; x++) {
-                       float *pixel = &ibuf->rect_float[4 * (y * ibuf->x + x)];
-                       float val = mask[y * ibuf->x + x];
-
-                       pixel[0] = val;
-                       pixel[1] = val;
-                       pixel[2] = val;
-                       pixel[3] = 1.0f;
-               }
-       }
-
-       MEM_freeN(mask);
-
-       IMB_rect_from_float(ibuf);
 }
 
-ImBuf *BKE_tracking_track_mask_get(MovieTracking *tracking, MovieTrackingTrack *track, MovieTrackingMarker *marker,
-                                   int width, int height)
+float *BKE_tracking_track_mask_get(int frame_width, int frame_height,
+                                   MovieTrackingTrack *track, MovieTrackingMarker *marker)
 {
-       ImBuf *ibuf;
+       float *mask = NULL;
        bGPDlayer *layer = track_mask_gpencil_layer_get(track);
        int mask_width, mask_height;
 
-       mask_width = (marker->search_max[0] - marker->search_min[0]) * width;
-       mask_height = (marker->search_max[1] - marker->search_min[1]) * height;
-
-       ibuf = IMB_allocImBuf(mask_width, mask_height, 32, IB_rect | IB_rectfloat);
+       mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
+       mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
 
        if (layer) {
-               track_mask_gpencil_layer_rasterize(tracking, marker, layer, ibuf, width, height);
-       }
-       else {
-               float white[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-               IMB_rectfill(ibuf, white);
+               mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
+
+               track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
+                                                  mask, mask_width, mask_height);
        }
 
-       return ibuf;
+       return mask;
 }
 
 #ifdef WITH_LIBMV
@@ -1676,7 +1681,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
        frame_width = destination_ibuf->x;
        frame_height = destination_ibuf->y;
 
-       #pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
+       //#pragma omp parallel for private(a) shared(destination_ibuf, ok) if (map_size>1)
        for (a = 0; a < map_size; a++) {
                TrackContext *track_context = NULL;
                MovieTrackingTrack *track;
@@ -1724,7 +1729,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                double src_pixel_y[5];
 
                                /* settings for the tracker */
-                               struct libmv_trackRegionOptions options;
+                               struct libmv_trackRegionOptions options = {0};
                                struct libmv_trackRegionResult result;
 
                                float *patch_new;
@@ -1744,6 +1749,14 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                        track_context->search_area_width = width;
 
                                        IMB_freeImBuf(reference_ibuf);
+
+                                       if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0) {
+                                               if (track_context->mask)
+                                                       MEM_freeN(track_context->mask);
+
+                                               track_context->mask = BKE_tracking_track_mask_get(frame_width, frame_height,
+                                                                                                 track, marker);
+                                       }
                                }
 
                                /* for now track to the same search area dimension as marker has got for current frame
@@ -1765,6 +1778,9 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                options.minimum_correlation = track->minimum_correlation;
                                options.sigma = 0.9;
 
+                               if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) != 0)
+                                       options.image1_mask = track_context->mask;
+
                                /* Convert the marker corners and center into pixel coordinates in the search/destination images. */
                                get_marker_coords_for_tracking(frame_width, frame_height, &track_context->marker, src_pixel_x, src_pixel_y);
                                get_marker_coords_for_tracking(frame_width, frame_height, marker, dst_pixel_x, dst_pixel_y);
@@ -1790,7 +1806,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
 
                                marker_search_scale_after_tracking(marker, &marker_new);
 
-                               #pragma omp critical
+                               //#pragma omp critical
                                {
                                        if (context->first_time) {
                                                /* check if there's no keyframe/tracked markers before tracking marker.
index 7b69e8204677cd8a187513f445c045e13671dfcc..22aa1031f481f25211d94b8867c2382dee95203a 100644 (file)
@@ -1550,7 +1550,8 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
                        IMB_freeImBuf(scopes->track_preview);
 
                tmpibuf = BKE_tracking_sample_pattern_imbuf(scopes->frame_width, scopes->frame_height,
-                                                           scopes->track_search, &scopes->undist_marker,
+                                                           scopes->track_search, scopes->track,
+                                                           &scopes->undist_marker, scopes->use_track_mask,
                                                            width, height, scopes->track_pos);
 
                if (tmpibuf->rect_float)
@@ -1582,6 +1583,12 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
                if (width > 0 && height > 0) {
                        drawibuf = scopes->track_preview;
 
+                       if (scopes->use_track_mask) {
+                               glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
+                               uiSetRoundBox(15);
+                               uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
+                       }
+
                        glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y,
                                          drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);
 
index a2adbd7a143aec7b1cb5cc65dc172214a65bae48..4615906b0dad8153b0cb402c18a14fb3b5a1596c 100644 (file)
@@ -4201,7 +4201,7 @@ static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonDa
                scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my);
        }
        else {
-               if (scopes->marker) {
+               if (!scopes->track_locked) {
                        if (scopes->marker->framenr != scopes->framenr)
                                scopes->marker = BKE_tracking_ensure_marker(scopes->track, scopes->framenr);
 
index 534ab8eeb95f11121d647c3bc56bf9eb3ebffc24..9a8e0de3e84a1b4ffbae6b81fc6bc6a077121d95 100644 (file)
@@ -215,6 +215,15 @@ static void clip_scopes_tag_refresh(ScrArea *sa)
        sc->scopes.ok = FALSE;
 }
 
+static void clip_scopes_check_gpencil_change(ScrArea *sa)
+{
+       SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
+
+       if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
+               clip_scopes_tag_refresh(sa);
+       }
+}
+
 static void clip_stabilization_tag_refresh(ScrArea *sa)
 {
        SpaceClip *sc = (SpaceClip *) sa->spacedata.first;
@@ -400,6 +409,7 @@ static void clip_listener(ScrArea *sa, wmNotifier *wmn)
                        switch (wmn->data) {
                                case ND_ANIMPLAY:
                                case ND_GPENCIL:
+                                       clip_scopes_check_gpencil_change(sa);
                                        ED_area_tag_redraw(sa);
                                        break;
                        }
index b5ab7898bd97f00b41331cb966ccf53b75fd8897..19004dbc8b88ff48b30e50efc94615bdbd802e5b 100644 (file)
@@ -90,7 +90,8 @@ typedef struct MovieClip {
 } MovieClip;
 
 typedef struct MovieClipScopes {
-       int ok;                         /* 1 means scopes are ok and recalculation is unneeded */
+       short ok;                       /* 1 means scopes are ok and recalculation is unneeded */
+       short use_track_mask;           /* whether track's mask should be applied on preview */
        int track_preview_height;       /* height of track preview widget */
        int frame_width, frame_height;  /* width and height of frame for which scopes are calculated */
        struct MovieTrackingMarker undist_marker;   /* undistorted position of marker used for pattern sampling */
@@ -98,7 +99,7 @@ typedef struct MovieClipScopes {
        struct ImBuf *track_preview;    /* ImBuf displayed in track preview */
        float track_pos[2];             /* sub-pizel position of marker in track ImBuf */
        short track_disabled;           /* active track is disabled, special notifier should be drawn */
-       char pad[2];
+       short track_locked;             /* active track is locked, no transformation should be allowed */
        int framenr;                    /* frame number scopes are created for */
        struct MovieTrackingTrack *track;   /* track scopes are created for */
        struct MovieTrackingMarker *marker; /* marker scopes are created for */
index 6ca63f2c1c9e3dcdc1caf9377a4888cbc2369e5b..84ae18357519e5cc118ddbce09ddc395c7aa5a6d 100644 (file)
@@ -287,6 +287,7 @@ enum {
 #define TRACK_USE_2D_STAB   (1 << 8)
 #define TRACK_PREVIEW_GRAYSCALE (1 << 9)
 #define TRACK_DOPE_SEL      (1 << 10)
+#define TRACK_PREVIEW_ALPHA (1 << 11)
 
 /* MovieTrackingTrack->motion_model */
 #define TRACK_MOTION_MODEL_TRANSLATION                 0
@@ -297,8 +298,9 @@ enum {
 #define TRACK_MOTION_MODEL_HOMOGRAPHY                  5
 
 /* MovieTrackingTrack->algorithm_flag */
-#define TRACK_ALGORITHM_FLAG_USE_BRUTE 1
-#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION 2
+#define TRACK_ALGORITHM_FLAG_USE_BRUTE                 (1 << 0)
+#define TRACK_ALGORITHM_FLAG_USE_NORMALIZATION (1 << 2)
+#define TRACK_ALGORITHM_FLAG_USE_MASK                  (1 << 3)
 
 /* MovieTrackingTrack->adjframes */
 #define TRACK_MATCH_KEYFRAME        0
index f1f962f67019cd45b34807ff1bcfeb9ba1f92396..c95d04d005a15d9dc5107cd1341d667fb53af271 100644 (file)
@@ -637,13 +637,19 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
        RNA_def_property_enum_items(prop, tracker_motion_model);
        RNA_def_property_ui_text(prop, "Motion model", "Default motion model to use for tracking");
 
-       /* use_brute */
+       /* default_use_brute */
        prop = RNA_def_property(srna, "default_use_brute", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_BRUTE);
        RNA_def_property_ui_text(prop, "Prepass", "Use a brute-force translation-only initialization when tracking");
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
-       /* default use_normalization */
+       /* default_use_brute */
+       prop = RNA_def_property(srna, "default_use_mask", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK);
+       RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
+       /* default_use_normalization */
        prop = RNA_def_property(srna, "default_use_normalization", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "default_algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION);
        RNA_def_property_ui_text(prop, "Normalize", "Normalize light intensities while tracking (slower)");
@@ -965,6 +971,12 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
        /* use_brute */
+       prop = RNA_def_property(srna, "use_mask", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_MASK);
+       RNA_def_property_ui_text(prop, "Use Mask", "Use a grease pencil datablock as a mask to use only specified areas of pattern when tracking");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
+       /* use_normalization */
        prop = RNA_def_property(srna, "use_normalization", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "algorithm_flag", TRACK_ALGORITHM_FLAG_USE_NORMALIZATION);
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -1008,6 +1020,13 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Grayscale", "Display what the tracking algorithm sees in the preview");
        RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
 
+       /* preview_alpha */
+       prop = RNA_def_property(srna, "use_alpha_preview", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_PREVIEW_ALPHA);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_ui_text(prop, "Alpha", "Apply track's mask on displaying preview");
+       RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
+
        /* has bundle */
        prop = RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE);