Merging r42178 through r42192 form trunk into soc-2011-tomato
authorSergey Sharybin <sergey.vfx@gmail.com>
Sun, 27 Nov 2011 19:35:46 +0000 (19:35 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Sun, 27 Nov 2011 19:35:46 +0000 (19:35 +0000)
24 files changed:
extern/libmv/CMakeLists.txt
extern/libmv/libmv-capi.cpp
extern/libmv/libmv-capi.h
extern/libmv/libmv/numeric/tinyvector.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/callbacks.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/callbacks.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/pipeline.cc
extern/libmv/libmv/simple_pipeline/pipeline.h
extern/libmv/third_party/ssba/README.libmv [changed mode: 0644->0755]
intern/ghost/intern/GHOST_System.cpp
release/scripts/presets/camera/Nikon_D35.py [new file with mode: 0644]
release/scripts/presets/tracking_settings/blurry_movie.py [new file with mode: 0644]
release/scripts/presets/tracking_settings/default.py [new file with mode: 0644]
release/scripts/presets/tracking_settings/fast_motion.py [new file with mode: 0644]
release/scripts/startup/bl_operators/presets.py
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/blenloader/intern/readfile.c
source/blender/editors/space_clip/clip_draw.c
source/blender/editors/space_clip/tracking_ops.c
source/blender/makesdna/DNA_tracking_types.h
source/blender/makesrna/intern/rna_tracking.c

index cd1f572197ce988c33e3b86d9d1f9eb440e4cf50..6f0d5f3d126cd67b02922cc3beb39fc02a571918 100644 (file)
@@ -39,6 +39,7 @@ set(SRC
        libmv-capi.cpp
        libmv/numeric/numeric.cc
        libmv/numeric/poly.cc
+       libmv/simple_pipeline/callbacks.cc
        libmv/simple_pipeline/reconstruction.cc
        libmv/simple_pipeline/resect.cc
        libmv/simple_pipeline/intersect.cc
@@ -83,6 +84,7 @@ set(SRC
        libmv/numeric/poly.h
        libmv/numeric/function_derivative.h
        libmv/numeric/numeric.h
+       libmv/simple_pipeline/callbacks.h
        libmv/simple_pipeline/resect.h
        libmv/simple_pipeline/reconstruction.h
        libmv/simple_pipeline/camera_intrinsics.h
index 8c453944e9de780485a2631d341da0a33af12bbb..f08aea9fbd1359c651359def49a920584e925963 100644 (file)
@@ -31,6 +31,8 @@
 #include "libmv-capi.h"
 
 #include "glog/logging.h"
+#include "libmv/logging/logging.h"
+
 #include "Math/v3d_optimization.h"
 
 #include "libmv/tracking/esm_region_tracker.h"
@@ -41,6 +43,7 @@
 
 #include "libmv/tracking/sad.h"
 
+#include "libmv/simple_pipeline/callbacks.h"
 #include "libmv/simple_pipeline/tracks.h"
 #include "libmv/simple_pipeline/initialize_reconstruction.h"
 #include "libmv/simple_pipeline/bundle.h"
@@ -339,6 +342,26 @@ void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
 
 /* ************ Reconstruction solver ************ */
 
+class ReconstructUpdateCallback : public libmv::ProgressUpdateCallback {
+public:
+       ReconstructUpdateCallback(reconstruct_progress_update_cb progress_update_callback,
+                       void *callback_customdata)
+       {
+               progress_update_callback_ = progress_update_callback;
+               callback_customdata_ = callback_customdata;
+       }
+
+       void invoke(double progress, const char *message)
+       {
+               if(progress_update_callback_) {
+                       progress_update_callback_(callback_customdata_, progress, message);
+               }
+       }
+protected:
+       reconstruct_progress_update_cb progress_update_callback_;
+       void *callback_customdata_;
+};
+
 int libmv_refineParametersAreValid(int parameters) {
        return (parameters == (LIBMV_REFINE_FOCAL_LENGTH))         ||
               (parameters == (LIBMV_REFINE_FOCAL_LENGTH           |
@@ -356,7 +379,8 @@ int libmv_refineParametersAreValid(int parameters) {
 
 
 libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyframe1, int keyframe2,
-               int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3)
+                       int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       reconstruct_progress_update_cb progress_update_callback, void *callback_customdata)
 {
        /* Invert the camera intrinsics. */
        libmv::vector<libmv::Marker> markers = ((libmv::Tracks*)tracks)->AllMarkers();
@@ -364,6 +388,9 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra
        libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
        libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
 
+       ReconstructUpdateCallback update_callback =
+               ReconstructUpdateCallback(progress_update_callback, callback_customdata);
+
        intrinsics->SetFocalLength(focal_length, focal_length);
        intrinsics->SetPrincipalPoint(principal_x, principal_y);
        intrinsics->SetRadialDistortion(k1, k2, k3);
@@ -377,15 +404,16 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra
 
        libmv::Tracks normalized_tracks(markers);
 
-       // printf("frames to init from: %d, %d\n", keyframe1, keyframe2);
+       LG << "frames to init from: " << keyframe1 << " " << keyframe2;
        libmv::vector<libmv::Marker> keyframe_markers =
                normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
-       // printf("number of markers for init: %d\n", keyframe_markers.size());
+       LG << "number of markers for init: " << keyframe_markers.size();
+
+       update_callback.invoke(0, "Initial reconstruction");
 
        libmv::EuclideanReconstructTwoFrames(keyframe_markers, reconstruction);
        libmv::EuclideanBundle(normalized_tracks, reconstruction);
-
-       libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction);
+       libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction, &update_callback);
 
        if (refine_intrinsics) {
                /* only a few combinations are supported but trust the caller */
@@ -402,9 +430,13 @@ libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyfra
                if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) {
                        libmv_refine_flags |= libmv::BUNDLE_RADIAL_K2;
                }
-               libmv::EuclideanBundleCommonIntrinsics(*(libmv::Tracks *)tracks, libmv_refine_flags, reconstruction, intrinsics);
+
+               progress_update_callback(callback_customdata, 1.0, "Refining solution");
+               libmv::EuclideanBundleCommonIntrinsics(*(libmv::Tracks *)tracks, libmv_refine_flags,
+                       reconstruction, intrinsics);
        }
 
+       progress_update_callback(callback_customdata, 1.0, "Finishing solution");
        libmv_reconstruction->tracks = *(libmv::Tracks *)tracks;
        libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics);
 
index 8252a11739b2306e012cc1b5cda31460971cd2da..536f8a5f14cf4edb5fa631cd965c14ef5733d6ed 100644 (file)
@@ -64,10 +64,14 @@ void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
 #define LIBMV_REFINE_PRINCIPAL_POINT   (1<<1)
 #define LIBMV_REFINE_RADIAL_DISTORTION_K1 (1<<2)
 #define LIBMV_REFINE_RADIAL_DISTORTION_K2 (1<<4)
+
+typedef void (*reconstruct_progress_update_cb) (void *customdata, double progress, const char *message);
+
 int libmv_refineParametersAreValid(int parameters);
 
 struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2,
-                       int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3);
+                       int refine_intrinsics, double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       reconstruct_progress_update_cb progress_update_callback, void *callback_customdata);
 int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]);
 double libmv_reporojectionErrorForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track);
 double libmv_reporojectionErrorForImage(struct libmv_Reconstruction *libmv_reconstruction, int image);
diff --git a/extern/libmv/libmv/numeric/tinyvector.cc b/extern/libmv/libmv/numeric/tinyvector.cc
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/extern/libmv/libmv/simple_pipeline/callbacks.cc b/extern/libmv/libmv/simple_pipeline/callbacks.cc
new file mode 100644 (file)
index 0000000..7e4bca6
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#include "libmv/simple_pipeline/callbacks.h"
+
+namespace libmv {
+
+void ProgressUpdateCallback::invoke(double progress, const char* message)
+{
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/simple_pipeline/callbacks.h b/extern/libmv/libmv/simple_pipeline/callbacks.h
new file mode 100644 (file)
index 0000000..675f73c
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright (c) 2011 libmv authors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+
+#ifndef LIBMV_SIMPLE_PIPELINE_CALLBACKS_H_
+#define LIBMV_SIMPLE_PIPELINE_CALLBACKS_H_
+
+namespace libmv {
+
+class ProgressUpdateCallback {
+ public:
+  virtual void invoke(double progress, const char *message);
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_SIMPLE_PIPELINE_MARKERS_H_
index 9512a41c00f33cd6d1a53fbfc96d73aca015be2e..382365e579f379b9bb46bad646ae1ce63c38a5c8 100644 (file)
@@ -21,6 +21,7 @@
 #include <cstdio>
 
 #include "libmv/logging/logging.h"
+#include "libmv/simple_pipeline/pipeline.h"
 #include "libmv/simple_pipeline/bundle.h"
 #include "libmv/simple_pipeline/intersect.h"
 #include "libmv/simple_pipeline/resect.h"
@@ -117,14 +118,32 @@ struct ProjectivePipelineRoutines {
 
 }  // namespace
 
+static void CompleteReconstructionLogProress(ProgressUpdateCallback *update_callback,
+    double progress,
+    const char *step = NULL)
+{
+  if(update_callback) {
+    char message[256];
+
+    if(step)
+      snprintf(message, sizeof(message), "Completing solution %d%% | %s", (int)(progress*100), step);
+    else
+      snprintf(message, sizeof(message), "Completing solution %d%%", (int)(progress*100));
+
+    update_callback->invoke(progress, message);
+  }
+}
+
 template<typename PipelineRoutines>
 void InternalCompleteReconstruction(
     const Tracks &tracks,
-    typename PipelineRoutines::Reconstruction *reconstruction) {
+    typename PipelineRoutines::Reconstruction *reconstruction,
+    ProgressUpdateCallback *update_callback = NULL) {
   int max_track = tracks.MaxTrack();
   int max_image = tracks.MaxImage();
   int num_resects = -1;
   int num_intersects = -1;
+  int tot_resects = 0;
   LG << "Max track: " << max_track;
   LG << "Max image: " << max_image;
   LG << "Number of markers: " << tracks.NumMarkers();
@@ -148,12 +167,17 @@ void InternalCompleteReconstruction(
       LG << "Got " << reconstructed_markers.size()
          << " reconstructed markers for track " << track;
       if (reconstructed_markers.size() >= 2) {
+        CompleteReconstructionLogProress(update_callback,
+                                         (double)tot_resects/(max_image));
         PipelineRoutines::Intersect(reconstructed_markers, reconstruction);
         num_intersects++;
         LG << "Ran Intersect() for track " << track;
       }
     }
     if (num_intersects) {
+      CompleteReconstructionLogProress(update_callback,
+                                       (double)tot_resects/(max_image),
+                                       "Bundling...");
       PipelineRoutines::Bundle(tracks, reconstruction);
       LG << "Ran Bundle() after intersections.";
     }
@@ -178,8 +202,11 @@ void InternalCompleteReconstruction(
       LG << "Got " << reconstructed_markers.size()
          << " reconstructed markers for image " << image;
       if (reconstructed_markers.size() >= 5) {
+        CompleteReconstructionLogProress(update_callback,
+                                         (double)tot_resects/(max_image));
         if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, false)) {
           num_resects++;
+          tot_resects++;
           LG << "Ran Resect() for image " << image;
         } else {
           LG << "Failed Resect() for image " << image;
@@ -187,6 +214,9 @@ void InternalCompleteReconstruction(
       }
     }
     if (num_resects) {
+      CompleteReconstructionLogProress(update_callback,
+                                       (double)tot_resects/(max_image),
+                                       "Bundling...");
       PipelineRoutines::Bundle(tracks, reconstruction);
     }
     LG << "Did " << num_resects << " resects.";
@@ -208,6 +238,8 @@ void InternalCompleteReconstruction(
       }
     }
     if (reconstructed_markers.size() >= 5) {
+      CompleteReconstructionLogProress(update_callback,
+                                       (double)tot_resects/(max_image));
       if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, true)) {
         num_resects++;
         LG << "Ran Resect() for image " << image;
@@ -217,6 +249,9 @@ void InternalCompleteReconstruction(
     }
   }
   if (num_resects) {
+    CompleteReconstructionLogProress(update_callback,
+                                     (double)tot_resects/(max_image),
+                                     "Bundling...");
     PipelineRoutines::Bundle(tracks, reconstruction);
   }
 }
@@ -244,7 +279,7 @@ double InternalReprojectionError(const Tracks &image_tracks,
         PipelineRoutines::ProjectMarker(*point, *camera, intrinsics);
     double ex = reprojected_marker.x - markers[i].x;
     double ey = reprojected_marker.y - markers[i].y;
-
+#if 0
     const int N = 100;
     char line[N];
     snprintf(line, N,
@@ -262,6 +297,7 @@ double InternalReprojectionError(const Tracks &image_tracks,
            ex,
            ey,
            sqrt(ex*ex + ey*ey));
+#endif
     total_error += sqrt(ex*ex + ey*ey);
   }
   LG << "Skipped " << num_skipped << " markers.";
@@ -289,9 +325,11 @@ double ProjectiveReprojectionError(
 }
 
 void EuclideanCompleteReconstruction(const Tracks &tracks,
-                                     EuclideanReconstruction *reconstruction) {
+                                     EuclideanReconstruction *reconstruction,
+                                     ProgressUpdateCallback *update_callback) {
   InternalCompleteReconstruction<EuclideanPipelineRoutines>(tracks,
-                                                            reconstruction);
+                                                            reconstruction,
+                                                            update_callback);
 }
 
 void ProjectiveCompleteReconstruction(const Tracks &tracks,
index b7dfcb7993a7ed33ccc8b878ebc69b42843749b3..e940b57bc0ddbaccc8edcd4075f759a72aa0beb2 100644 (file)
@@ -21,6 +21,7 @@
 #ifndef LIBMV_SIMPLE_PIPELINE_PIPELINE_H_
 #define LIBMV_SIMPLE_PIPELINE_PIPELINE_H_
 
+#include "libmv/simple_pipeline/callbacks.h"
 #include "libmv/simple_pipeline/tracks.h"
 #include "libmv/simple_pipeline/reconstruction.h"
 
@@ -46,7 +47,8 @@ namespace libmv {
     \sa EuclideanResect, EuclideanIntersect, EuclideanBundle
 */
 void EuclideanCompleteReconstruction(const Tracks &tracks,
-                                     EuclideanReconstruction *reconstruction);
+                                     EuclideanReconstruction *reconstruction,
+                                     ProgressUpdateCallback *update_callback = NULL);
 
 /*!
     Estimate camera matrices and homogeneous 3D coordinates for all frames and
old mode 100644 (file)
new mode 100755 (executable)
index 839e014aff6d4fbad16ffcbfad3cd5e9373a1741..afc54d3c6a025139d33653365a29cf116decf3be 100644 (file)
@@ -136,7 +136,7 @@ bool GHOST_System::validWindow(GHOST_IWindow* window)
 
 
 GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window,
-                                                                                        const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
+                                                                                        const bool stereoVisual)
 {
        GHOST_TSuccess success = GHOST_kFailure;
        GHOST_ASSERT(m_windowManager, "GHOST_System::beginFullScreen(): invalid window manager")
@@ -148,7 +148,7 @@ GHOST_TSuccess GHOST_System::beginFullScreen(const GHOST_DisplaySetting& setting
                        success = m_displayManager->setCurrentDisplaySetting(GHOST_DisplayManager::kMainDisplay, setting);
                        if (success == GHOST_kSuccess) {
                                //GHOST_PRINT("GHOST_System::beginFullScreen(): creating full-screen window\n");
-                               success = createFullScreenWindow((GHOST_Window**)window, stereoVisual, numOfAASamples);
+                               success = createFullScreenWindow((GHOST_Window**)window, stereoVisual);
                                if (success == GHOST_kSuccess) {
                                        m_windowManager->beginFullScreen(*window, stereoVisual);
                                }
@@ -330,7 +330,7 @@ GHOST_TSuccess GHOST_System::exit()
 }
 
 
-GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, const bool stereoVisual, const GHOST_TUns16 numOfAASamples)
+GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, const bool stereoVisual)
 {
        GHOST_TSuccess success;
        GHOST_ASSERT(m_displayManager, "GHOST_System::createFullScreenWindow(): invalid display manager")
@@ -344,8 +344,7 @@ GHOST_TSuccess GHOST_System::createFullScreenWindow(GHOST_Window** window, const
                                        0, 0, settings.xPixels, settings.yPixels,
                                        GHOST_kWindowStateFullScreen,
                                        GHOST_kDrawingContextTypeOpenGL,
-                                       stereoVisual,
-                                       numOfAASamples);
+                                       stereoVisual);
                success = *window == 0 ? GHOST_kFailure : GHOST_kSuccess;
        }
        return success;
diff --git a/release/scripts/presets/camera/Nikon_D35.py b/release/scripts/presets/camera/Nikon_D35.py
new file mode 100644 (file)
index 0000000..e6dc62d
--- /dev/null
@@ -0,0 +1,4 @@
+import bpy
+bpy.context.object.data.sensor_width = 36.0
+bpy.context.object.data.sensor_height = 23.9
+bpy.context.object.data.sensor_fit = 'HORIZONTAL'
diff --git a/release/scripts/presets/tracking_settings/blurry_movie.py b/release/scripts/presets/tracking_settings/blurry_movie.py
new file mode 100644 (file)
index 0000000..ad96533
--- /dev/null
@@ -0,0 +1,8 @@
+import bpy
+settings = bpy.context.edit_movieclip.tracking.settings
+
+settings.default_tracker = 'KLT'
+settings.default_pyramid_levels = 4
+settings.default_correlation_min = 0.75
+settings.default_pattern_size = 11
+settings.default_search_size = 202
diff --git a/release/scripts/presets/tracking_settings/default.py b/release/scripts/presets/tracking_settings/default.py
new file mode 100644 (file)
index 0000000..4f1e23f
--- /dev/null
@@ -0,0 +1,8 @@
+import bpy
+settings = bpy.context.edit_movieclip.tracking.settings
+
+settings.default_tracker = 'KLT'
+settings.default_pyramid_levels = 2
+settings.default_correlation_min = 0.75
+settings.default_pattern_size = 11
+settings.default_search_size = 51
diff --git a/release/scripts/presets/tracking_settings/fast_motion.py b/release/scripts/presets/tracking_settings/fast_motion.py
new file mode 100644 (file)
index 0000000..0ca768a
--- /dev/null
@@ -0,0 +1,8 @@
+import bpy
+settings = bpy.context.edit_movieclip.tracking.settings
+
+settings.default_tracker = 'KLT'
+settings.default_pyramid_levels = 2
+settings.default_correlation_min = 0.75
+settings.default_pattern_size = 11
+settings.default_search_size = 121
index 100b21fc303e05b5cd2a8c006d6f2da40511ed23..1eeae28783ea35afdf04ad7235cb099eaf37111e 100644 (file)
@@ -360,6 +360,27 @@ class AddPresetTrackingTrackColor(AddPresetBase, Operator):
     preset_subdir = "tracking_track_color"
 
 
+class AddPresetTrackingSettings(AddPresetBase, Operator):
+    '''Add a motion tracking settings preset'''
+    bl_idname = "clip.tracking_settings_preset_add"
+    bl_label = "Add Tracking Settings Preset"
+    preset_menu = "CLIP_MT_tracking_settings_presets"
+
+    preset_defines = [
+        "settings = bpy.context.edit_movieclip.tracking.settings"
+    ]
+
+    preset_values = [
+        "settings.default_tracker",
+        "settings.default_pyramid_levels",
+        "settings.default_correlation_min",
+        "settings.default_pattern_size",
+        "settings.default_search_size",
+    ]
+
+    preset_subdir = "tracking_settings"
+
+
 class AddPresetKeyconfig(AddPresetBase, Operator):
     '''Add a Keyconfig Preset'''
     bl_idname = "wm.keyconfig_preset_add"
index b04d81b6b2a6aeaab2b24bb3e239796a30ac8a7e..dbfa6a24ec3df0a137a870e08c4d9f8d8ac43fd4 100644 (file)
@@ -92,6 +92,9 @@ class CLIP_PT_tools_marker(Panel):
         return clip and sc.mode == 'TRACKING'
 
     def draw(self, context):
+        sc = context.space_data
+        clip = sc.clip
+        settings = clip.tracking.settings
         layout = self.layout
 
         col = layout.column(align=True)
@@ -99,6 +102,36 @@ class CLIP_PT_tools_marker(Panel):
         col.operator("clip.detect_features")
         col.operator("clip.delete_track")
 
+        box = layout.box()
+        row = box.row(align=True)
+        row.prop(settings, "show_default_expanded", text="", emboss=False)
+        row.label(text="Default Settings")
+
+        if settings.show_default_expanded:
+            col = box.column()
+            row = col.row(align=True)
+            label = bpy.types.CLIP_MT_tracking_settings_presets.bl_label
+            row.menu('CLIP_MT_tracking_settings_presets', text=label)
+            row.operator("clip.tracking_settings_preset_add",
+                         text="", icon='ZOOMIN')
+            props = row.operator("clip.track_color_preset_add",
+                                 text="", icon='ZOOMOUT')
+            props.remove_active = True
+
+            col.separator()
+
+            col2 = col.column(align=True)
+            col2.prop(settings, "default_pattern_size")
+            col2.prop(settings, "default_search_size")
+
+            col.label(text="Tracker:")
+            col.prop(settings, "default_tracker", text="")
+
+            if settings.default_tracker == 'KLT':
+                col.prop(settings, "default_pyramid_levels")
+            else:
+                col.prop(settings, "default_correlation_min")
+
 
 class CLIP_PT_tools_tracking(Panel):
     bl_space_type = 'CLIP_EDITOR'
@@ -447,18 +480,24 @@ class CLIP_PT_track_settings(Panel):
         clip = context.space_data.clip
         settings = clip.tracking.settings
 
+        col = layout.column()
+
         active = clip.tracking.tracks.active
         if active:
-            layout.prop(active, "tracker")
+            col.prop(active, "tracker")
+
             if active.tracker == 'KLT':
-                layout.prop(active, "pyramid_levels")
+                col.prop(active, "pyramid_levels")
             elif active.tracker == 'SAD':
-                layout.prop(active, "correlation_min")
+                col.prop(active, "correlation_min")
+
+            col.separator()
+            col.label(text="Global Settings:")
 
-        layout.prop(settings, "frames_adjust")
-        layout.prop(settings, "speed")
-        layout.prop(settings, "frames_limit")
-        layout.prop(settings, "margin")
+        col.prop(settings, "speed")
+        col.prop(settings, "frames_adjust")
+        col.prop(settings, "frames_limit")
+        col.prop(settings, "margin")
 
 
 class CLIP_PT_stabilization(Panel):
@@ -866,6 +905,14 @@ class CLIP_MT_track_color_presets(Menu):
     draw = bpy.types.Menu.draw_preset
 
 
+class CLIP_MT_tracking_settings_presets(Menu):
+    """Predefined track color"""
+    bl_label = "Tracking Settings"
+    preset_subdir = "tracking_settings"
+    preset_operator = "script.execute_preset"
+    draw = bpy.types.Menu.draw_preset
+
+
 class CLIP_MT_track_color_specials(Menu):
     bl_label = "Track Color Specials"
 
index 1c25547b146cbf65d9bef08a79760dfe7d8de8d7..e55d40ebfe5aa99a89a035ec25dfe67918cca961 100644 (file)
@@ -34,6 +34,7 @@
 
 struct bGPDlayer;
 struct ImBuf;
+struct MovieReconstructContext;
 struct MovieTrackingTrack;
 struct MovieTrackingMarker;
 struct MovieTracking;
@@ -44,6 +45,7 @@ struct Camera;
 struct Object;
 struct Scene;
 
+void BKE_tracking_init_settings(struct MovieTracking *tracking);
 void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event);
 void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear);
 
@@ -90,9 +92,14 @@ void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingCont
 int BKE_tracking_next(struct MovieTrackingContext *context);
 
 /* Camera solving */
-int BKE_tracking_can_solve(struct MovieTracking *tracking, char *error_msg, int error_size);
-
-float BKE_tracking_solve_reconstruction(struct MovieTracking *tracking, int width, int height);
+int BKE_tracking_can_reconstruct(struct MovieTracking *tracking, char *error_msg, int error_size);
+
+struct MovieReconstructContext* BKE_tracking_reconstruction_context_new(struct MovieTracking *tracking,
+                       int keyframe1, int keyframe2, int width, int height);
+void BKE_tracking_reconstruction_context_free(struct MovieReconstructContext *context);
+void BKE_tracking_solve_reconstruction(struct MovieReconstructContext *context,
+                       short *stop, short *do_update, float *progress, char *stats_message, int message_size);
+int BKE_tracking_finish_reconstruction(struct MovieReconstructContext *context, struct MovieTracking *tracking);
 
 struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr);
 void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]);
index 382e1d7038723cb2ebb75fb485aa2b6462fe115f..75d8ec584e85ddfeac56380258a89603b3b0ea40 100644 (file)
@@ -369,19 +369,7 @@ static MovieClip *movieclip_alloc(const char *name)
 
        clip->aspx= clip->aspy= 1.0f;
 
-       clip->tracking.camera.sensor_width= 35.0f;
-       clip->tracking.camera.pixel_aspect= 1.0f;
-       clip->tracking.camera.units= CAMERA_UNITS_MM;
-
-       clip->tracking.settings.frames_limit= 0;
-       clip->tracking.settings.keyframe1= 1;
-       clip->tracking.settings.keyframe2= 30;
-       clip->tracking.settings.dist= 1;
-
-       clip->tracking.stabilization.scaleinf= 1.0f;
-       clip->tracking.stabilization.locinf= 1.0f;
-       clip->tracking.stabilization.rotinf= 1.0f;
-       clip->tracking.stabilization.maxscale= 2.0f;
+       BKE_tracking_init_settings(&clip->tracking);
 
        clip->proxy.build_size_flag= IMB_PROXY_25;
        clip->proxy.build_tc_flag= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN;
index 45e708a8233cf57e53c0ff5d4436d4da0db4542a..4c54e9f22f51b0af55fc0a5ce2e573ec2d7eb9b5 100644 (file)
@@ -70,14 +70,38 @@ typedef struct MovieDistortion {
 
 /*********************** common functions *************************/
 
+void BKE_tracking_init_settings(MovieTracking *tracking)
+{
+       tracking->camera.sensor_width= 35.0f;
+       tracking->camera.pixel_aspect= 1.0f;
+       tracking->camera.units= CAMERA_UNITS_MM;
+
+       tracking->settings.default_tracker= TRACKER_KLT;
+       tracking->settings.default_pyramid_levels= 2;
+       tracking->settings.default_minimum_correlation= 0.75;
+       tracking->settings.default_pattern_size= 11;
+       tracking->settings.default_search_size= 51;
+       tracking->settings.default_pyramid_levels= 2;
+       tracking->settings.frames_limit= 0;
+       tracking->settings.keyframe1= 1;
+       tracking->settings.keyframe2= 30;
+       tracking->settings.dist= 1;
+
+       tracking->stabilization.scaleinf= 1.0f;
+       tracking->stabilization.locinf= 1.0f;
+       tracking->stabilization.rotinf= 1.0f;
+       tracking->stabilization.maxscale= 2.0f;
+}
+
 void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
 {
        int a;
        float pat_min[2];
        float pat_max[2];
        float max_pyramid_level_factor = 1.0;
+
        if (track->tracker == TRACKER_KLT) {
-               max_pyramid_level_factor = 1 << (track->pyramid_levels - 1);
+               max_pyramid_level_factor= 1 << (track->pyramid_levels - 1);
        }
 
        /* sort */
@@ -146,7 +170,7 @@ void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event)
                float dim[2];
                sub_v2_v2v2(dim, track->pat_max, track->pat_min);
                {
-                       float search_ratio = 2.3f * max_pyramid_level_factor;
+                       float search_ratio= 2.3f * max_pyramid_level_factor;
 
                        /* resize the search area to something sensible based
                         * on the number of pyramid levels */
@@ -190,25 +214,27 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, flo
 {
        MovieTrackingTrack *track;
        MovieTrackingMarker marker;
+       MovieTrackingSettings *settings= &tracking->settings;
 
-       /* pick reasonable defaults */
-       float pat[2]= {5.5f, 5.5f}, search[2]= {25.5f, 25.5f}; /* TODO: move to default setting? */
+       float half_pattern= (float)settings->default_pattern_size/2.0f;
+       float half_search= (float)settings->default_search_size/2.0f;
+       float pat[2], search[2];
 
-       pat[0] /= (float)width;
-       pat[1] /= (float)height;
+       pat[0]= half_pattern/(float)width;
+       pat[1]= half_pattern/(float)height;
 
-       search[0] /= (float)width;
-       search[1] /= (float)height;
+       search[0]= half_search/(float)width;
+       search[1]= half_search/(float)height;
 
        track= MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
        strcpy(track->name, "Track");
 
        /* default to KLT tracker */
-       track->tracker = TRACKER_KLT;
-       track->pyramid_levels = 2;
+       track->tracker = settings->default_tracker;
+       track->pyramid_levels = settings->default_pyramid_levels;
 
        /* set SAD defaults even though it's not selected by default */
-       track->minimum_correlation= 0.75f;
+       track->minimum_correlation= settings->default_minimum_correlation;
 
        memset(&marker, 0, sizeof(marker));
        marker.pos[0]= x;
@@ -223,6 +249,8 @@ MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, flo
 
        BKE_tracking_insert_marker(track, &marker);
 
+       BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS);
+
        BLI_addtail(&tracking->tracks, track);
        BKE_track_unique_name(tracking, track);
 
@@ -1250,7 +1278,7 @@ int BKE_tracking_next(MovieTrackingContext *context)
                                        #pragma omp critical
                                        {
                                                /* check if there's no keyframe/tracked markers before tracking marker.
-                                                   if so -- create disabled marker before currently tracking "segment" */
+                                                  if so -- create disabled marker before currently tracking "segment" */
                                                put_disabled_marker(track, marker, 1, 0);
                                        }
                                }
@@ -1302,6 +1330,36 @@ int BKE_tracking_next(MovieTrackingContext *context)
        return ok;
 }
 
+/*********************** camera solving *************************/
+
+typedef struct MovieReconstructContext {
+#ifdef WITH_LIBMV
+       struct libmv_Tracks *tracks;
+       int keyframe1, keyframe2;
+       short refine_flags;
+
+       struct libmv_Reconstruction *reconstruction;
+#endif
+
+       float focal_length;
+       float principal_point[2];
+       float k1, k2, k3;
+
+       float reprojection_error;
+
+       TracksMap *tracks_map;
+
+       int sfra, efra;
+} MovieReconstructContext;
+
+typedef struct ReconstructProgressData {
+       short *stop;
+       short *do_update;
+       float *progress;
+       char *stats_message;
+       int message_size;
+} ReconstructProgressData;
+
 #if WITH_LIBMV
 static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height)
 {
@@ -1328,8 +1386,9 @@ static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int wid
        return tracks;
 }
 
-static void retrieve_libmv_reconstruct_intrinscis(MovieTracking *tracking, struct libmv_Reconstruction *libmv_reconstruction)
+static void retrieve_libmv_reconstruct_intrinscis(MovieReconstructContext *context, MovieTracking *tracking)
 {
+       struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
        struct libmv_CameraIntrinsics *libmv_intrinsics = libmv_ReconstructionExtractIntrinsics(libmv_reconstruction);
 
        float aspy= 1.0f/tracking->camera.pixel_aspect;
@@ -1349,14 +1408,14 @@ static void retrieve_libmv_reconstruct_intrinscis(MovieTracking *tracking, struc
        tracking->camera.k2= k2;
 }
 
-static int retrieve_libmv_reconstruct_tracks(MovieTracking *tracking, struct libmv_Reconstruction *libmv_reconstruction)
+static int retrieve_libmv_reconstruct_tracks(MovieReconstructContext *context, MovieTracking *tracking)
 {
-       int tracknr= 0;
-       int sfra= INT_MAX, efra= INT_MIN, a, origin_set= 0;
-       MovieTrackingTrack *track;
+       struct libmv_Reconstruction *libmv_reconstruction= context->reconstruction;
        MovieTrackingReconstruction *reconstruction= &tracking->reconstruction;
        MovieReconstructedCamera *reconstructed;
-       int ok= 1;
+       MovieTrackingTrack *track;
+       int ok= 1, tracknr= 0, a, origin_set= 0;
+       int sfra= context->sfra, efra= context->efra;
        float imat[4][4];
 
        unit_m4(imat);
@@ -1379,30 +1438,6 @@ static int retrieve_libmv_reconstruct_tracks(MovieTracking *tracking, struct lib
                        printf("No bundle for track #%d '%s'\n", tracknr, track->name);
                }
 
-               if(track->markersnr) {
-                       int first= 0, last= track->markersnr;
-                       MovieTrackingMarker *first_marker= &track->markers[0];
-                       MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1];
-
-                       /* find first not-disabled marker */
-                       while(first<track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
-                               first++;
-                               first_marker++;
-                       }
-
-                       /* find last not-disabled marker */
-                       while(last>=0 && last_marker->flag&MARKER_DISABLED) {
-                               last--;
-                               last_marker--;
-                       }
-
-                       if(first<track->markersnr-1)
-                               sfra= MIN2(sfra, first_marker->framenr);
-
-                       if(last>=0)
-                               efra= MAX2(efra, last_marker->framenr);
-               }
-
                track= track->next;
                tracknr++;
        }
@@ -1465,12 +1500,14 @@ static int retrieve_libmv_reconstruct_tracks(MovieTracking *tracking, struct lib
        return ok;
 }
 
-static int retrieve_libmv_reconstruct(MovieTracking *tracking, struct libmv_Reconstruction *libmv_reconstruction)
+static int retrieve_libmv_reconstruct(MovieReconstructContext *context, MovieTracking *tracking)
 {
+       tracks_map_merge(context->tracks_map, tracking);
+
        /* take the intrinscis back from libmv */
-       retrieve_libmv_reconstruct_intrinscis(tracking, libmv_reconstruction);
+       retrieve_libmv_reconstruct_intrinscis(context, tracking);
 
-       return retrieve_libmv_reconstruct_tracks(tracking, libmv_reconstruction);
+       return retrieve_libmv_reconstruct_tracks(context, tracking);
 }
 
 static int get_refine_intrinsics_flags(MovieTracking *tracking)
@@ -1512,7 +1549,7 @@ static int count_tracks_on_both_keyframes(MovieTracking *tracking)
 }
 #endif
 
-int BKE_tracking_can_solve(MovieTracking *tracking, char *error_msg, int error_size)
+int BKE_tracking_can_reconstruct(MovieTracking *tracking, char *error_msg, int error_size)
 {
 #if WITH_LIBMV
        if(count_tracks_on_both_keyframes(tracking)<8) {
@@ -1523,46 +1560,161 @@ int BKE_tracking_can_solve(MovieTracking *tracking, char *error_msg, int error_s
        return 1;
 #else
        BLI_strncpy(error_msg, "Blender is compiled without motion tracking library", error_size);
-       (void)tracking;
+       (void) tracking;
 
        return 0;
 #endif
 }
 
-float BKE_tracking_solve_reconstruction(MovieTracking *tracking, int width, int height)
+MovieReconstructContext* BKE_tracking_reconstruction_context_new(MovieTracking *tracking,
+                       int keyframe1, int keyframe2, int width, int height)
 {
-#if WITH_LIBMV
-       {
-               MovieTrackingCamera *camera= &tracking->camera;
-               float aspy= 1.0f/tracking->camera.pixel_aspect;
-               struct libmv_Tracks *tracks= create_libmv_tracks(tracking, width, height*aspy);
-               struct libmv_Reconstruction *reconstruction = libmv_solveReconstruction(tracks,
-                       tracking->settings.keyframe1, tracking->settings.keyframe2,
-                       get_refine_intrinsics_flags(tracking),
-                       camera->focal,
-                       camera->principal[0], camera->principal[1]*aspy,
-                       camera->k1, camera->k2, camera->k3);
-               float error= libmv_reprojectionError(reconstruction);
+       MovieReconstructContext *context= MEM_callocN(sizeof(MovieReconstructContext), "MovieReconstructContext data");
+       MovieTrackingCamera *camera= &tracking->camera;
+       float aspy= 1.0f/tracking->camera.pixel_aspect;
+       int num_tracks= BLI_countlist(&tracking->tracks);
+       int sfra= INT_MAX, efra= INT_MIN;
+       MovieTrackingTrack *track;
+
+       context->tracks_map= tracks_map_new(num_tracks, 0);
+       track= tracking->tracks.first;
+       while(track) {
+               int first= 0, last= track->markersnr;
+               MovieTrackingMarker *first_marker= &track->markers[0];
+               MovieTrackingMarker *last_marker= &track->markers[track->markersnr-1];
+
+               /* find first not-disabled marker */
+               while(first<track->markersnr-1 && first_marker->flag&MARKER_DISABLED) {
+                       first++;
+                       first_marker++;
+               }
 
-               tracking->reconstruction.error= error;
+               /* find last not-disabled marker */
+               while(last>=0 && last_marker->flag&MARKER_DISABLED) {
+                       last--;
+                       last_marker--;
+               }
 
-               if(!retrieve_libmv_reconstruct(tracking, reconstruction))
-                       error= -1.0f;
+               if(first<track->markersnr-1)
+                       sfra= MIN2(sfra, first_marker->framenr);
 
-               libmv_destroyReconstruction(reconstruction);
-               libmv_tracksDestroy(tracks);
+               if(last>=0)
+                       efra= MAX2(efra, last_marker->framenr);
 
-               tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
+               tracks_map_insert(context->tracks_map, track, NULL);
 
-               return error;
+               track= track->next;
        }
+
+       context->sfra= sfra;
+       context->efra= efra;
+
+#ifdef WITH_LIBMV
+       context->tracks= create_libmv_tracks(tracking, width, height*aspy);
+       context->keyframe1= keyframe1;
+       context->keyframe2= keyframe2;
+       context->refine_flags= get_refine_intrinsics_flags(tracking);
 #else
-       (void)tracking;
-       (void)width;
-       (void)height;
+       (void) width;
+       (void) height;
+       (void) keyframe1;
+       (void) keyframe2;
+#endif
+
+       context->focal_length= camera->focal;
+       context->principal_point[0]= camera->principal[0];
+       context->principal_point[1]= camera->principal[1]*aspy;
+
+       context->k1= camera->k1;
+       context->k2= camera->k2;
+       context->k2= camera->k2;
+
+       return context;
+}
+
+void BKE_tracking_reconstruction_context_free(MovieReconstructContext *context)
+{
+#ifdef WITH_LIBMV
+       if(context->reconstruction)
+                       libmv_destroyReconstruction(context->reconstruction);
+
+       libmv_tracksDestroy(context->tracks);
+#endif
+
+       tracks_map_free(context->tracks_map, NULL);
+
+       MEM_freeN(context);
+}
+
+static void solve_reconstruction_update_cb(void *customdata, double progress, const char *message)
+{
+       ReconstructProgressData *progressdata= customdata;
+
+       if(progressdata->progress) {
+               *progressdata->progress= progress;
+               *progressdata->do_update= 1;
+       }
+
+       BLI_snprintf(progressdata->stats_message, progressdata->message_size,
+                       "Solving camera | %s", message);
+}
 
-       return -1.0f;
+#if 0
+static int solve_reconstruction_testbreak_cb(void *customdata)
+{
+       ReconstructProgressData *progressdata= customdata;
+
+       if(progressdata->stop && *progressdata->stop)
+               return 1;
+
+       return G.afbreek;
+}
 #endif
+
+void BKE_tracking_solve_reconstruction(MovieReconstructContext *context, short *stop,
+                       short *do_update, float *progress, char *stats_message, int message_size)
+{
+#ifdef WITH_LIBMV
+       float error;
+
+       ReconstructProgressData progressdata;
+
+       progressdata.stop= stop;
+       progressdata.do_update= do_update;
+       progressdata.progress= progress;
+       progressdata.stats_message= stats_message;
+       progressdata.message_size= message_size;
+
+       context->reconstruction = libmv_solveReconstruction(context->tracks,
+               context->keyframe1, context->keyframe2,
+               context->refine_flags,
+               context->focal_length,
+               context->principal_point[0], context->principal_point[1],
+               context->k1, context->k2, context->k3,
+               solve_reconstruction_update_cb, &progressdata);
+
+       error= libmv_reprojectionError(context->reconstruction);
+
+       context->reprojection_error= error;
+#else
+       (void) context;
+       (void) stop;
+       (void) do_update;
+       (void) progress;
+#endif
+}
+
+int BKE_tracking_finish_reconstruction(MovieReconstructContext *context, MovieTracking *tracking)
+{
+       tracking->reconstruction.error= context->reprojection_error;
+       tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED;
+
+#ifdef WITH_LIBMV
+       if(!retrieve_libmv_reconstruct(context, tracking))
+               return 0;
+#endif
+
+       return 1;
 }
 
 void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track)
index e69823886e566500fbcbc7e366c7180df32cd29f..3db36a075d7ee40c71ad2a91237ef214025fc62a 100644 (file)
@@ -5966,6 +5966,7 @@ static void direct_link_movieclip(FileData *fd, MovieClip *clip)
 
        clip->anim= NULL;
        clip->tracking_context= NULL;
+       clip->tracking.stats= NULL;
 
        clip->tracking.stabilization.ok= 0;
        clip->tracking.stabilization.scaleibuf= NULL;
@@ -12606,11 +12607,25 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        /* put compatibility code here until next subversion bump */
        {
                Scene *sce;
+               MovieClip *clip;
+
                for(sce = main->scene.first; sce; sce = sce->id.next) {
                        if (sce->r.im_format.depth == 0) {
                                do_versions_image_settings_2_60(sce);
                        }
                }
+
+               for (clip= main->movieclip.first; clip; clip= clip->id.next) {
+                       MovieTrackingSettings *settings= &clip->tracking.settings;
+
+                       if(settings->default_pyramid_levels==0) {
+                               settings->default_tracker= TRACKER_KLT;
+                               settings->default_pyramid_levels= 2;
+                               settings->default_minimum_correlation= 0.75;
+                               settings->default_pattern_size= 11;
+                               settings->default_search_size= 51;
+                       }
+               }
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
index 630038d4c6be6ce7bde02b12da742fdd2e5599bd..a53da4ce0069c998cf66e7bdc016e0bb8471f0a2 100644 (file)
@@ -191,27 +191,38 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc
 
 static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
 {
+       MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
        char str[256]= {0};
+       int block= 0;
 
-       if(sc->flag&SC_LOCK_SELECTION)
-               strcpy(str, "Locked");
+       if(tracking->stats) {
+               BLI_strncpy(str, tracking->stats->message, sizeof(str));
+               block= 1;
+       } else {
+               if(sc->flag&SC_LOCK_SELECTION)
+                       strcpy(str, "Locked");
+       }
 
        if(str[0]) {
                uiStyle *style= UI_GetStyle();
-               int fontsize, fontwidth;
                int fontid= style->widget.uifont_id;
+               int fontwidth;
+
+               BLF_size(fontid, 11.0f, 72);
 
-               BLF_size(fontid, 11.0f, U.dpi);
-               fontsize= BLF_height(fontid, str);
-               fontwidth= BLF_width(fontid, str);
+               if(block)
+                       fontwidth= ar->winx;
+               else
+                       fontwidth= BLF_width(fontid, str);
 
                glEnable(GL_BLEND);
 
                glColor4f(0.0f, 0.0f, 0.0f, 0.6f);
-               glRecti(0, ar->winy-fontsize-9, fontwidth+12, ar->winy);
+               glRecti(0, ar->winy-17, fontwidth+12, ar->winy);
 
                glColor3f(1.0f, 1.0f, 1.0f);
-               BLF_position(fontid, 6.0f, ar->winy-fontsize-5.0f, 0.0f);
+               BLF_position(fontid, 6.0f, ar->winy-13.0f, 0.0f);
                BLF_draw(fontid, str, strlen(str));
 
                glDisable(GL_BLEND);
index 6eb5e511bc43feb0795ec2c68dff0b5d8e5cbb10..e91331e5252afd845bbdf42429674a6b565c622d 100644 (file)
@@ -741,7 +741,7 @@ static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, MovieClip *clip, fl
                                d2= dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max);
 
                        /* distance to search boundbox */
-                       if(sc->flag&SC_SHOW_MARKER_SEARCH && TRACK_VIEW_SELECTED(sc, cur))
+                       if(sc->flag&SC_SHOW_MARKER_SEARCH)
                                d3= dist_to_rect(co, marker->pos, cur->search_min, cur->search_max);
 
                        /* choose minimal distance. useful for cases of overlapped markers. */
@@ -1473,7 +1473,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
 
 static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
 {
-       /* no running blender, remove handler and pass through */
+       /* no running tracking, remove handler and pass through */
        if(0==WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C)))
                return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
 
@@ -1510,61 +1510,201 @@ void CLIP_OT_track_markers(wmOperatorType *ot)
 
 /********************** solve camera operator *********************/
 
-static int solve_camera_exec(bContext *C, wmOperator *op)
+typedef struct {
+       Scene *scene;
+       MovieClip *clip;
+       MovieClipUser user;
+
+       ReportList *reports;
+
+       char stats_message[256];
+
+       struct MovieReconstructContext *context;
+} SolveCameraJob;
+
+static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op, char *error_msg, int max_error)
 {
        SpaceClip *sc= CTX_wm_space_clip(C);
        MovieClip *clip= ED_space_clip(sc);
        Scene *scene= CTX_data_scene(C);
        MovieTracking *tracking= &clip->tracking;
+       MovieTrackingSettings *settings= &clip->tracking.settings;
        int width, height;
-       float error;
-       char error_msg[255];
 
-       if(!BKE_tracking_can_solve(tracking, error_msg, sizeof(error_msg))) {
-               BKE_report(op->reports, RPT_ERROR, error_msg);
-
-               return OPERATOR_CANCELLED;
-       }
+       if(!BKE_tracking_can_reconstruct(tracking, error_msg, max_error))
+               return 0;
 
        /* could fail if footage uses images with different sizes */
        BKE_movieclip_get_size(clip, &sc->user, &width, &height);
 
-       error= BKE_tracking_solve_reconstruction(tracking, width, height);
+       scj->clip= clip;
+       scj->scene= scene;
+       scj->reports= op->reports;
+       scj->user= sc->user;
+
+       scj->context= BKE_tracking_reconstruction_context_new(tracking,
+                       settings->keyframe1, settings->keyframe2, width, height);
+
+       tracking->stats= MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats");
+
+       return 1;
+}
+
+static void solve_camera_updatejob(void *scv)
+{
+       SolveCameraJob *scj= (SolveCameraJob *)scv;
+       MovieTracking *tracking= &scj->clip->tracking;
+
+       BLI_strncpy(tracking->stats->message, scj->stats_message, sizeof(tracking->stats->message));
+}
+
+static void solve_camera_startjob(void *scv, short *stop, short *do_update, float *progress)
+{
+       SolveCameraJob *scj= (SolveCameraJob *)scv;
+
+       BKE_tracking_solve_reconstruction(scj->context, stop, do_update, progress,
+                       scj->stats_message, sizeof(scj->stats_message));
+}
+
+static void solve_camera_freejob(void *scv)
+{
+       SolveCameraJob *scj= (SolveCameraJob *)scv;
+       MovieTracking *tracking= &scj->clip->tracking;
+       Scene *scene= scj->scene;
+       MovieClip *clip= scj->clip;
+       int solved;
+
+       if(!scj->context) {
+               /* job weren't fully initialized due to some error */
+               MEM_freeN(scj);
+               return;
+       }
 
-       if(error<0)
-               BKE_report(op->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details");
+       solved= BKE_tracking_finish_reconstruction(scj->context, tracking);
+
+       if(!solved)
+               BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details");
        else
-               BKE_reportf(op->reports, RPT_INFO, "Average reprojection error %.3f", error);
+               BKE_reportf(scj->reports, RPT_INFO, "Average reprojection error %.3f", tracking->reconstruction.error);
 
+       /* set currently solved clip as active for scene */
        if(scene->clip)
                id_us_min(&clip->id);
 
        scene->clip= clip;
        id_us_plus(&clip->id);
 
+       /* set blender camera focal length so result would look fine there */
        if(!scene->camera)
                scene->camera= scene_find_camera(scene);
 
        if(scene->camera) {
-               /* set blender camera focal length so result would look fine there */
                Camera *camera= (Camera*)scene->camera->data;
+               int width, height;
+
+               BKE_movieclip_get_size(clip, &scj->user, &width, &height);
 
                BKE_tracking_camera_to_blender(tracking, scene, camera, width, height);
 
-               WM_event_add_notifier(C, NC_OBJECT, camera);
+               WM_main_add_notifier(NC_OBJECT, camera);
        }
 
+       MEM_freeN(tracking->stats);
+       tracking->stats= NULL;
+
        DAG_id_tag_update(&clip->id, 0);
 
-       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
-       WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
+       WM_main_add_notifier(NC_MOVIECLIP|NA_EVALUATED, clip);
+       WM_main_add_notifier(NC_OBJECT|ND_TRANSFORM, NULL);
 
        /* update active clip displayed in scene buttons */
-       WM_event_add_notifier(C, NC_SCENE, scene);
+       WM_main_add_notifier(NC_SCENE, scene);
+
+       BKE_tracking_reconstruction_context_free(scj->context);
+       MEM_freeN(scj);
+}
+
+static int solve_camera_exec(bContext *C, wmOperator *op)
+{
+       SolveCameraJob *scj;
+       char error_msg[256]= "\0";
+
+       scj= MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
+       if(!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
+               if(error_msg[0])
+                       BKE_report(op->reports, RPT_ERROR, error_msg);
+
+               solve_camera_freejob(scj);
+
+               return OPERATOR_CANCELLED;
+       }
+
+       solve_camera_startjob(scj, NULL, NULL, NULL);
+
+       solve_camera_freejob(scj);
 
        return OPERATOR_FINISHED;
 }
 
+static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+{
+       SolveCameraJob *scj;
+       ScrArea *sa= CTX_wm_area(C);
+       SpaceClip *sc= CTX_wm_space_clip(C);
+       MovieClip *clip= ED_space_clip(sc);
+       MovieTracking *tracking= &clip->tracking;
+       wmJob *steve;
+       char error_msg[256]= "\0";
+
+       scj= MEM_callocN(sizeof(SolveCameraJob), "SolveCameraJob data");
+       if(!solve_camera_initjob(C, scj, op, error_msg, sizeof(error_msg))) {
+               if(error_msg[0])
+                       BKE_report(op->reports, RPT_ERROR, error_msg);
+
+               solve_camera_freejob(scj);
+
+               return OPERATOR_CANCELLED;
+       }
+
+       BLI_strncpy(tracking->stats->message, "Solving camera | Preparing solve", sizeof(tracking->stats->message));
+
+       /* hide reconstruction statistics from previous solve */
+       clip->tracking.reconstruction.flag&= ~TRACKING_RECONSTRUCTED;
+       WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip);
+
+       /* setup job */
+       steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Solve Camera", WM_JOB_PROGRESS);
+       WM_jobs_customdata(steve, scj, solve_camera_freejob);
+       WM_jobs_timer(steve, 0.1, NC_MOVIECLIP|NA_EVALUATED, 0);
+       WM_jobs_callbacks(steve, solve_camera_startjob, NULL, solve_camera_updatejob, NULL);
+
+       G.afbreek= 0;
+
+       WM_jobs_start(CTX_wm_manager(C), steve);
+       WM_cursor_wait(0);
+
+       /* add modal handler for ESC */
+       WM_event_add_modal_handler(C, op);
+
+       return OPERATOR_RUNNING_MODAL;
+}
+
+static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+{
+       /* no running solver, remove handler and pass through */
+       if(0==WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C)))
+               return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
+
+       /* running tracking */
+       switch (event->type) {
+               case ESCKEY:
+                       return OPERATOR_RUNNING_MODAL;
+                       break;
+       }
+
+       return OPERATOR_PASS_THROUGH;
+}
+
 void CLIP_OT_solve_camera(wmOperatorType *ot)
 {
        /* identifiers */
@@ -1574,6 +1714,8 @@ void CLIP_OT_solve_camera(wmOperatorType *ot)
 
        /* api callbacks */
        ot->exec= solve_camera_exec;
+       ot->invoke= solve_camera_invoke;
+       ot->modal= solve_camera_modal;
        ot->poll= ED_space_clip_poll;
 
        /* flags */
index cbac3721ac38df2316234b153382b79bb46bfc08..931ed6fb8c69caff0e5ec62e55d7641617fdbc3f 100644 (file)
@@ -107,16 +107,25 @@ typedef struct MovieTrackingTrack {
        float minimum_correlation;                      /* minimal correlation which is still treated as successful tracking */
 
        /* ** KLT tracker settings ** */
-       int pyramid_levels;             /* number of pyramid levels to use for KLT tracking */
-       char pad5[4];
+       short pyramid_levels;           /* number of pyramid levels to use for KLT tracking */
+       char pad5[6];
 } MovieTrackingTrack;
 
 typedef struct MovieTrackingSettings {
+       /* ** default tracker settings */
+       short default_tracker;                          /* tracking algorithm used by default */
+       short default_pyramid_levels;           /* number of pyramid levels to use for KLT tracking */
+       float default_minimum_correlation;      /* minimal correlation which is still treated as successful tracking */
+       short default_pattern_size;                     /* size of pattern area for new tracks */
+       short default_search_size;                      /* size of search area for new tracks */
+
        /* ** common tracker settings ** */
        short speed;                    /* speed of tracking */
        short frames_limit;             /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */
        short margin;                   /* margin from frame boundaries */
-       char pad[2];
+
+       short pad;
+       int flag;
 
        int adjframes;                  /* re-adjust every N frames */
 
@@ -125,8 +134,7 @@ typedef struct MovieTrackingSettings {
 
        /* ** which camera intrinsics to refine. uses on the REFINE_* flags */
        short refine_camera_intrinsics;
-
-       char pad2[6];
+       short pad2;
 
        /* ** tool settings ** */
 
@@ -165,15 +173,19 @@ typedef struct MovieTrackingReconstruction {
        struct MovieReconstructedCamera *cameras;       /* reconstructed cameras */
 } MovieTrackingReconstruction;
 
+typedef struct MovieTrackingStats {
+       char message[256];
+} MovieTrackingStats;
+
 typedef struct MovieTracking {
        MovieTrackingSettings settings; /* different tracking-related settings */
-       char pad2[4];
-
        MovieTrackingCamera camera;             /* camera intrinsics */
        ListBase tracks;                                /* all tracks */
        MovieTrackingReconstruction reconstruction;     /* reconstruction data */
        MovieTrackingStabilization stabilization;       /* stabilization data */
        MovieTrackingTrack *act_track;          /* active track */
+
+       MovieTrackingStats *stats;              /* statistics displaying in clip editor */
 } MovieTracking;
 
 /* MovieTrackingCamera->units */
@@ -197,6 +209,9 @@ enum {
 #define TRACK_CUSTOMCOLOR      (1<<7)
 #define TRACK_USE_2D_STAB      (1<<8)
 
+/* MovieTrackingSettings->flag */
+#define TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED        (1<<0)
+
 /* MovieTrackingSettings->tracker */
 #define TRACKER_KLT            0
 #define TRACKER_SAD            1
index eb3512083aa03a56e38f19df5a79dde91e970a93..8d20aeafa5454f65a6964b43429ec893664a424a 100644 (file)
 
 #include "WM_api.h"
 
+static void rna_tracking_defaultSettings_levelsUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingSettings *settings= &tracking->settings;
+
+       if(settings->default_tracker==TRACKER_KLT) {
+               int max_pyramid_level_factor= 1 << (settings->default_pyramid_levels - 1);
+               float search_ratio= 2.3f * max_pyramid_level_factor;
+
+               settings->default_search_size= settings->default_pattern_size*search_ratio;
+       }
+}
+
+static void rna_tracking_defaultSettings_patternUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingSettings *settings= &tracking->settings;
+
+       if(settings->default_search_size<settings->default_pattern_size)
+               settings->default_search_size= settings->default_pattern_size;
+}
+
+static void rna_tracking_defaultSettings_searchUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr)
+{
+       MovieClip *clip= (MovieClip*)ptr->id.data;
+       MovieTracking *tracking= &clip->tracking;
+       MovieTrackingSettings *settings= &tracking->settings;
+
+       if(settings->default_pattern_size>settings->default_search_size)
+               settings->default_pattern_size= settings->default_search_size;
+}
+
 static void rna_tracking_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
 {
        MovieClip *clip= (MovieClip*)ptr->id.data;
@@ -232,6 +266,11 @@ static MovieTrackingMarker *rna_trackingTrack_marker_find_frame(MovieTrackingTra
 
 #else
 
+static EnumPropertyItem tracker_items[] = {
+       {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi tracker which works with most of video clips, a bit slower than SAD"},
+       {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker which can be used when MLT tracker fails"},
+       {0, NULL, 0, NULL, NULL}};
+
 static int rna_matrix_dimsize_4x4[]= {4, 4};
 
 static void rna_def_trackingSettings(BlenderRNA *brna)
@@ -348,6 +387,56 @@ static void rna_def_trackingSettings(BlenderRNA *brna)
        RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
        RNA_def_property_enum_items(prop, cleanup_items);
        RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute");
+
+       /* ** default tracker settings ** */
+
+       prop= RNA_def_property(srna, "show_default_expanded", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_SETTINGS_SHOW_DEFAULT_EXPANDED);
+       RNA_def_property_ui_text(prop, "Show Expanded", "Show the expanded in the user interface");
+       RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1);
+
+       /* tracking algorithm */
+       prop= RNA_def_property(srna, "default_tracker", PROP_ENUM, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_enum_items(prop, tracker_items);
+       RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate");
+       RNA_def_property_ui_text(prop, "Tracker", "Tracking algorithm to use");
+
+       /* pyramid level for pyramid klt tracking */
+       prop= RNA_def_property(srna, "default_pyramid_levels", PROP_INT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_sdna(prop, NULL, "default_pyramid_levels");
+       RNA_def_property_range(prop, 1, 16);
+       RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_levelsUpdate");
+       RNA_def_property_ui_text(prop, "Pyramid levels", "Default number of pyramid levels (increase on blurry footage)");
+
+       /* minmal correlation - only used for SAD tracker */
+       prop= RNA_def_property(srna, "default_correlation_min", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_float_sdna(prop, NULL, "default_minimum_correlation");
+       RNA_def_property_range(prop, -1.0f, 1.0f);
+       RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3);
+       RNA_def_property_ui_text(prop, "Correlation", "Default minimal value of correlation between matched pattern and reference which is still treated as successful tracking");
+
+       /* default pattern size */
+       prop= RNA_def_property(srna, "default_pattern_size", PROP_INT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_sdna(prop, NULL, "default_pattern_size");
+       RNA_def_property_range(prop, 5, 1000);
+       RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_patternUpdate");
+       RNA_def_property_ui_text(prop, "Pattern Size", "Size of pattern area for newly creating tracks");
+
+       /* default search size */
+       prop= RNA_def_property(srna, "default_search_size", PROP_INT, PROP_NONE);
+       RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+       RNA_def_property_int_sdna(prop, NULL, "default_search_size");
+       RNA_def_property_range(prop, 5, 1000);
+       RNA_def_property_update(prop, 0, "rna_tracking_defaultSettings_searchUpdate");
+       RNA_def_property_ui_text(prop, "Search Size", "Size of search area for newly creating tracks");
 }
 
 static void rna_def_trackingCamera(BlenderRNA *brna)
@@ -465,11 +554,6 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        FunctionRNA *func;
        PropertyRNA *parm;
 
-       static EnumPropertyItem tracker_items[] = {
-               {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi tracker which works with most of video clips, a bit slower than SAD"},
-               {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker which can be used when MLT tracker fails"},
-               {0, NULL, 0, NULL, NULL}};
-
        rna_def_trackingMarker(brna);
 
        srna= RNA_def_struct(brna, "MovieTrackingTrack", NULL);
@@ -535,7 +619,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna)
        RNA_def_property_float_sdna(prop, NULL, "minimum_correlation");
        RNA_def_property_range(prop, -1.0f, 1.0f);
        RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3);
-       RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between mathed pattern and reference which is still treated as successful tracking");
+       RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between matched pattern and reference which is still treated as successful tracking");
 
        /* markers */
        prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE);