Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Mon, 14 Aug 2017 15:07:30 +0000 (17:07 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Mon, 14 Aug 2017 15:07:30 +0000 (17:07 +0200)
intern/cycles/bvh/bvh_build.cpp
release/scripts/startup/bl_operators/clip.py
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/tracking_auto.c
source/blender/blenkernel/intern/tracking_util.c
source/blender/blenkernel/tracking_private.h

index 933e98fea0142a0add2a4d49beabf02ed1c77c17..eb1d89729fbfe30a26dba7711067e458f73d86e2 100644 (file)
@@ -1040,7 +1040,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
                 */
                start_index = spatial_free_index;
                spatial_free_index += range.size();
-
                /* Extend an array when needed. */
                const size_t range_end = start_index + range.size();
                if(prim_type.size() < range_end) {
@@ -1066,8 +1065,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
                                prim_time.resize(range_end);
                        }
                }
-               spatial_spin_lock.unlock();
-
                /* Perform actual data copy. */
                if(new_leaf_data_size > 0) {
                        memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
@@ -1077,6 +1074,7 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
                                memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
                        }
                }
+               spatial_spin_lock.unlock();
        }
        else {
                /* For the regular BVH builder we simply copy new data starting at the
index d0e551597333f88e91b520fe7e14975030a50809..ea68641f68b09eddf8d3cd0f27a73c148820c50a 100644 (file)
@@ -210,7 +210,7 @@ class CLIP_OT_set_active_clip(bpy.types.Operator):
     @classmethod
     def poll(cls, context):
         space = context.space_data
-        return space.type == 'CLIP_EDITOR'
+        return space.type == 'CLIP_EDITOR' and space.clip
 
     def execute(self, context):
         clip = context.space_data.clip
@@ -254,6 +254,11 @@ class CLIP_OT_track_to_empty(Operator):
         constraint.object = tracking_object.name
         constraint.camera = CLIP_camera_for_clip(context, clip)
 
+    @classmethod
+    def poll(cls, context):
+        space = context.space_data
+        return space.type == 'CLIP_EDITOR' and space.clip
+
     def execute(self, context):
         sc = context.space_data
         clip = sc.clip
index 15a0f1191f8c9fdaa002def80778a79fe2ba9216..71fbb3d726acca80c0ecdfb12f62c198774b2aba 100644 (file)
@@ -492,18 +492,20 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
 
 struct IDCopyLibManagementData {
        const ID *id_src;
+       ID *id_dst;
        int flag;
 };
 
 /* Increases usercount as required, and remap self ID pointers. */
-static int id_copy_libmanagement_cb(void *user_data, ID *id_self, ID **id_pointer, int cb_flag)
+static int id_copy_libmanagement_cb(void *user_data, ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
 {
        struct IDCopyLibManagementData *data = user_data;
        ID *id = *id_pointer;
 
        /* Remap self-references to new copied ID. */
        if (id == data->id_src) {
-               id = *id_pointer = id_self;
+               /* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
+               id = *id_pointer = data->id_dst;
        }
 
        /* Increase used IDs refcount if needed and required. */
@@ -656,7 +658,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, con
        }
 
        /* Update ID refcount, remap pointers to self in new ID. */
-       struct IDCopyLibManagementData data = {.id_src = id, .flag = flag};
+       struct IDCopyLibManagementData data = {.id_src = id, .id_dst = *r_newid, .flag = flag};
        BKE_library_foreach_ID_link(bmain, *r_newid, id_copy_libmanagement_cb, &data, IDWALK_NOP);
 
        /* Do not make new copy local in case we are copying outside of main...
index d33b1ce7d06c73946e931fc24c8a58e9fc914349..346d107792e536207e174aac87252f2bfb4fd589 100644 (file)
@@ -1221,17 +1221,12 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
  */
 void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bNodeTree *ntree_src, const int flag)
 {
-       bNode *node_src;
        bNodeSocket *sock_dst, *sock_src;
        bNodeLink *link_dst;
 
        /* We never handle usercount here for own data. */
        const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
 
-       if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
-               id_us_plus((ID *)ntree_dst->gpd);
-       }
-
        /* in case a running nodetree is copied */
        ntree_dst->execdata = NULL;
 
@@ -1240,7 +1235,7 @@ void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bN
        BLI_listbase_clear(&ntree_dst->nodes);
        BLI_listbase_clear(&ntree_dst->links);
 
-       for (node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) {
+       for (bNode *node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) {
                BKE_node_copy_ex(ntree_dst, node_src, flag_subdata);
        }
 
@@ -1291,9 +1286,9 @@ void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bN
        }
 
        /* update node->parent pointers */
-       for (node_src = ntree_dst->nodes.first; node_src; node_src = node_src->next) {
-               if (node_src->parent) {
-                       node_src->parent = node_src->parent->new_node;
+       for (bNode *node_dst = ntree_dst->nodes.first, *node_src = ntree_src->nodes.first; node_dst; node_dst = node_dst->next, node_src = node_src->next) {
+               if (node_dst->parent) {
+                       node_dst->parent = node_dst->parent->new_node;
                }
        }
 
index 414946f877d5a5707ba38bbc6a0b07d5b7694204..30981ed8f23c87330f2bc86cb3fcbc147f215e43 100644 (file)
@@ -381,7 +381,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
 
 bool BKE_autotrack_context_step(AutoTrackContext *context)
 {
-       int frame_delta = context->backwards ? -1 : 1;
+       const int frame_delta = context->backwards ? -1 : 1;
        bool ok = false;
        int track;
 
@@ -395,67 +395,64 @@ bool BKE_autotrack_context_step(AutoTrackContext *context)
                             libmv_reference_marker,
                             libmv_tracked_marker;
                libmv_TrackRegionResult libmv_result;
-               int frame = BKE_movieclip_remap_scene_to_clip_frame(
-                       context->clips[options->clip_index],
-                       context->user.framenr);
-               bool has_marker;
-
+               const int frame = BKE_movieclip_remap_scene_to_clip_frame(
+                       context->clips[options->clip_index],
+                       context->user.framenr);
                BLI_spin_lock(&context->spin_lock);
-               has_marker = libmv_autoTrackGetMarker(context->autotrack,
-                                                     options->clip_index,
-                                                     frame,
-                                                     options->track_index,
-                                                     &libmv_current_marker);
+               const bool has_marker = libmv_autoTrackGetMarker(context->autotrack,
+                                                                options->clip_index,
+                                                                frame,
+                                                                options->track_index,
+                                                                &libmv_current_marker);
                BLI_spin_unlock(&context->spin_lock);
-
-               if (has_marker) {
-                       if (!tracking_check_marker_margin(&libmv_current_marker,
-                                                         options->track->margin,
-                                                         context->frame_width,
-                                                         context->frame_height))
-                       {
-                               continue;
-                       }
-
-                       libmv_tracked_marker = libmv_current_marker;
-                       libmv_tracked_marker.frame = frame + frame_delta;
-
-                       if (options->use_keyframe_match) {
-                               libmv_tracked_marker.reference_frame =
-                                       libmv_current_marker.reference_frame;
-                               libmv_autoTrackGetMarker(context->autotrack,
-                                                    options->clip_index,
-                                                    libmv_tracked_marker.reference_frame,
-                                                    options->track_index,
-                                                    &libmv_reference_marker);
-                       }
-                       else {
-                               libmv_tracked_marker.reference_frame = frame;
-                               libmv_reference_marker = libmv_current_marker;
-                       }
-
-                       if (libmv_autoTrackMarker(context->autotrack,
-                                                 &options->track_region_options,
-                                                 &libmv_tracked_marker,
-                                                 &libmv_result))
-                       {
-                               BLI_spin_lock(&context->spin_lock);
-                               libmv_autoTrackAddMarker(context->autotrack,
-                                                        &libmv_tracked_marker);
-                               BLI_spin_unlock(&context->spin_lock);
-                       }
-                       else {
-                               options->is_failed = true;
-                               options->failed_frame = frame + frame_delta;
-                       }
-                       ok = true;
+               /* Check whether we've got marker to sync with. */
+               if (!has_marker) {
+                       continue;
+               }
+               /* Check whether marker is going outside of allowed frame margin. */
+               if (!tracking_check_marker_margin(&libmv_current_marker,
+                                                 options->track->margin,
+                                                 context->frame_width,
+                                                 context->frame_height))
+               {
+                       continue;
+               }
+               libmv_tracked_marker = libmv_current_marker;
+               libmv_tracked_marker.frame = frame + frame_delta;
+               /* Update reference frame. */
+               if (options->use_keyframe_match) {
+                       libmv_tracked_marker.reference_frame =
+                               libmv_current_marker.reference_frame;
+                       libmv_autoTrackGetMarker(context->autotrack,
+                                            options->clip_index,
+                                            libmv_tracked_marker.reference_frame,
+                                            options->track_index,
+                                            &libmv_reference_marker);
                }
+               else {
+                       libmv_tracked_marker.reference_frame = frame;
+                       libmv_reference_marker = libmv_current_marker;
+               }
+               /* Perform actual tracking. */
+               if (libmv_autoTrackMarker(context->autotrack,
+                                         &options->track_region_options,
+                                         &libmv_tracked_marker,
+                                         &libmv_result))
+               {
+                       BLI_spin_lock(&context->spin_lock);
+                       libmv_autoTrackAddMarker(context->autotrack, &libmv_tracked_marker);
+                       BLI_spin_unlock(&context->spin_lock);
+               }
+               else {
+                       options->is_failed = true;
+                       options->failed_frame = frame + frame_delta;
+               }
+               ok = true;
        }
-
+       /* Advance the frame. */
        BLI_spin_lock(&context->spin_lock);
        context->user.framenr += frame_delta;
        BLI_spin_unlock(&context->spin_lock);
-
        return ok;
 }
 
index fef0a3bc0ac5c1780d665e6be6b3bc36141e5970..b1a092517defd3a05b34157d51895015b35af9f2 100644 (file)
 
 #include "libmv-capi.h"
 
+/* Uncomment this to have caching-specific debug prints. */
+// #define DEBUG_CACHE
+
+#ifdef DEBUG_CACHE
+#  define CACHE_PRINTF(...) printf(__VA_ARGS__)
+#else
+#  define CACHE_PRINTF(...)
+#endif
+
 /*********************** Tracks map *************************/
 
 TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size)
@@ -523,6 +532,8 @@ typedef struct AccessCacheKey {
        int frame;
        int downscale;
        libmv_InputMode input_mode;
+       bool has_region;
+       float region_min[2], region_max[2];
        int64_t transform_key;
 } AccessCacheKey;
 
@@ -537,23 +548,44 @@ static bool accesscache_hashcmp(const void *a_v, const void *b_v)
 {
        const AccessCacheKey *a = (const AccessCacheKey *) a_v;
        const AccessCacheKey *b = (const AccessCacheKey *) b_v;
-
-#define COMPARE_FIELD(field)
-       { \
-               if (a->clip_index != b->clip_index) { \
-                       return false; \
-               } \
-       } (void) 0
-
-       COMPARE_FIELD(clip_index);
-       COMPARE_FIELD(frame);
-       COMPARE_FIELD(downscale);
-       COMPARE_FIELD(input_mode);
-       COMPARE_FIELD(transform_key);
-
-#undef COMPARE_FIELD
-
-       return true;
+       if (a->clip_index != b->clip_index ||
+           a->frame != b->frame ||
+           a->downscale != b->downscale ||
+           a->input_mode != b->input_mode ||
+           a->has_region != b->has_region ||
+           a->transform_key != b->transform_key)
+       {
+               return true;
+       }
+       /* If there is region applied, compare it. */
+       if (a->has_region) {
+               if (!equals_v2v2(a->region_min, b->region_min) ||
+                   !equals_v2v2(a->region_max, b->region_max))
+               {
+                       return true;
+               }
+       }
+       return false;
+}
+
+static void accesscache_construct_key(AccessCacheKey *key,
+                                      int clip_index,
+                                      int frame,
+                                      libmv_InputMode input_mode,
+                                      int downscale,
+                                      const libmv_Region *region,
+                                      int64_t transform_key)
+{
+       key->clip_index = clip_index;
+       key->frame = frame;
+       key->input_mode = input_mode;
+       key->downscale = downscale;
+       key->has_region = (region != NULL);
+       if (key->has_region) {
+               copy_v2_v2(key->region_min, region->min);
+               copy_v2_v2(key->region_max, region->max);
+       }
+       key->transform_key = transform_key;
 }
 
 static void accesscache_put(TrackingImageAccessor *accessor,
@@ -561,15 +593,13 @@ static void accesscache_put(TrackingImageAccessor *accessor,
                             int frame,
                             libmv_InputMode input_mode,
                             int downscale,
+                            const libmv_Region *region,
                             int64_t transform_key,
                             ImBuf *ibuf)
 {
        AccessCacheKey key;
-       key.clip_index = clip_index;
-       key.frame = frame;
-       key.input_mode = input_mode;
-       key.downscale = downscale;
-       key.transform_key = transform_key;
+       accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+                                 region, transform_key);
        IMB_moviecache_put(accessor->cache, &key, ibuf);
 }
 
@@ -578,14 +608,12 @@ static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
                               int frame,
                               libmv_InputMode input_mode,
                               int downscale,
+                              const libmv_Region *region,
                               int64_t transform_key)
 {
        AccessCacheKey key;
-       key.clip_index = clip_index;
-       key.frame = frame;
-       key.input_mode = input_mode;
-       key.downscale = downscale;
-       key.transform_key = transform_key;
+       accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+                                 region, transform_key);
        return IMB_moviecache_get(accessor->cache, &key);
 }
 
@@ -674,29 +702,37 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
 {
        ImBuf *ibuf, *orig_ibuf, *final_ibuf;
        int64_t transform_key = 0;
-
        if (transform != NULL) {
                transform_key = libmv_frameAccessorgetTransformKey(transform);
        }
-
        /* First try to get fully processed image from the cache. */
+       BLI_spin_lock(&accessor->cache_lock);
        ibuf = accesscache_get(accessor,
                               clip_index,
                               frame,
                               input_mode,
                               downscale,
+                              region,
                               transform_key);
+       BLI_spin_unlock(&accessor->cache_lock);
        if (ibuf != NULL) {
+               CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
+               /* This is a little heuristic here: if we re-used image once, this is
+                * a high probability of the image to be related to a keyframe matched
+                * reference image. Those images we don't want to be thrown away because
+                * if we toss them out we'll be re-calculating them at the next
+                * iteration.
+                */
+               ibuf->userflags |= IB_PERSISTENT;
                return ibuf;
        }
-
+       CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
        /* And now we do postprocessing of the original frame. */
        orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
-
        if (orig_ibuf == NULL) {
                return NULL;
        }
-
+       /* Cut a region if requested. */
        if (region != NULL) {
                int width = region->max[0] - region->min[0],
                    height = region->max[1] - region->min[1];
@@ -756,7 +792,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
                BLI_unlock_thread(LOCK_MOVIECLIP);
                final_ibuf = orig_ibuf;
        }
-
+       /* Downscale if needed. */
        if (downscale > 0) {
                if (final_ibuf == orig_ibuf) {
                        final_ibuf = IMB_dupImBuf(orig_ibuf);
@@ -765,7 +801,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
                               orig_ibuf->x / (1 << downscale),
                               orig_ibuf->y / (1 << downscale));
        }
-
+       /* Apply possible transformation. */
        if (transform != NULL) {
                libmv_FloatImage input_image, output_image;
                ibuf_to_float_image(final_ibuf, &input_image);
@@ -778,12 +814,13 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
                final_ibuf = float_image_to_ibuf(&output_image);
                libmv_floatImageDestroy(&output_image);
        }
-
+       /* Transform number of channels. */
        if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
                BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
                /* pass */
        }
        else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+               BLI_assert(input_mode == LIBMV_IMAGE_MODE_MONO);
                if (final_ibuf->channels != 1) {
                        ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
                        if (final_ibuf != orig_ibuf) {
@@ -793,37 +830,24 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
                        final_ibuf = grayscale_ibuf;
                }
        }
-
-       /* it's possible processing still didn't happen at this point,
+       /* It's possible processing still didn't happen at this point,
         * but we really need a copy of the buffer to be transformed
         * and to be put to the cache.
         */
        if (final_ibuf == orig_ibuf) {
                final_ibuf = IMB_dupImBuf(orig_ibuf);
        }
-
        IMB_freeImBuf(orig_ibuf);
-
-       /* We put postprocessed frame to the cache always for now,
-        * not the smartest thing in the world, but who cares at this point.
-        */
-
-       /* TODO(sergey): Disable cache for now, because we don't store region
-        * in the cache key and can't check whether cached version is usable for
-        * us or not.
-        *
-        * Need to think better about what to cache and when.
-        */
-       if (false) {
-               accesscache_put(accessor,
-                               clip_index,
-                               frame,
-                               input_mode,
-                               downscale,
-                               transform_key,
-                               final_ibuf);
-       }
-
+       BLI_spin_lock(&accessor->cache_lock);
+       /* Put final buffer to cache. */
+       accesscache_put(accessor,
+                       clip_index,
+                       frame,
+                       input_mode,
+                       downscale,
+                       region,
+                       transform_key,
+                       final_ibuf);
        return final_ibuf;
 }
 
@@ -958,6 +982,8 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
                                       accessor_get_mask_for_track_callback,
                                       accessor_release_mask_callback);
 
+       BLI_spin_init(&accessor->cache_lock);
+
        return accessor;
 }
 
index 1a68a1cac6af00f5c1b1b4799f1829564a763d5f..07236fb2096591d6ba7ae65df7fc5d82b94870e9 100644 (file)
@@ -125,6 +125,7 @@ typedef struct TrackingImageAccessor {
        int num_tracks;
        int start_frame;
        struct libmv_FrameAccessor *libmv_accessor;
+       SpinLock cache_lock;
 } TrackingImageAccessor;
 
 TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],