Merge with trunk r41625
authorMiika Hamalainen <blender@miikah.org>
Mon, 7 Nov 2011 16:36:49 +0000 (16:36 +0000)
committerMiika Hamalainen <blender@miikah.org>
Mon, 7 Nov 2011 16:36:49 +0000 (16:36 +0000)
635 files changed:
CMakeLists.txt
GNUmakefile
build_files/cmake/config/blender_lite.cmake
build_files/cmake/macros.cmake
build_files/scons/tools/Blender.py
build_files/scons/tools/btools.py
doc/doxygen/Doxyfile
extern/CMakeLists.txt
extern/SConscript
extern/libmv/CMakeLists.txt [new file with mode: 0644]
extern/libmv/ChangeLog [new file with mode: 0644]
extern/libmv/SConscript [new file with mode: 0644]
extern/libmv/bundle.sh [new file with mode: 0755]
extern/libmv/files.txt [new file with mode: 0644]
extern/libmv/libmv-capi.cpp [new file with mode: 0644]
extern/libmv/libmv-capi.h [new file with mode: 0644]
extern/libmv/libmv/base/id_generator.h [new file with mode: 0644]
extern/libmv/libmv/base/scoped_ptr.h [new file with mode: 0644]
extern/libmv/libmv/base/vector.h [new file with mode: 0644]
extern/libmv/libmv/base/vector_utils.h [new file with mode: 0644]
extern/libmv/libmv/image/array_nd.cc [new file with mode: 0644]
extern/libmv/libmv/image/array_nd.h [new file with mode: 0644]
extern/libmv/libmv/image/convolve.cc [new file with mode: 0644]
extern/libmv/libmv/image/convolve.h [new file with mode: 0644]
extern/libmv/libmv/image/image.h [new file with mode: 0644]
extern/libmv/libmv/image/sample.h [new file with mode: 0644]
extern/libmv/libmv/image/tuple.h [new file with mode: 0644]
extern/libmv/libmv/logging/logging.h [new file with mode: 0644]
extern/libmv/libmv/multiview/conditioning.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/conditioning.h [new file with mode: 0644]
extern/libmv/libmv/multiview/euclidean_resection.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/euclidean_resection.h [new file with mode: 0644]
extern/libmv/libmv/multiview/fundamental.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/fundamental.h [new file with mode: 0644]
extern/libmv/libmv/multiview/nviewtriangulation.h [new file with mode: 0644]
extern/libmv/libmv/multiview/projection.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/projection.h [new file with mode: 0644]
extern/libmv/libmv/multiview/resection.h [new file with mode: 0644]
extern/libmv/libmv/multiview/triangulation.cc [new file with mode: 0644]
extern/libmv/libmv/multiview/triangulation.h [new file with mode: 0644]
extern/libmv/libmv/numeric/dogleg.h [new file with mode: 0644]
extern/libmv/libmv/numeric/function_derivative.h [new file with mode: 0644]
extern/libmv/libmv/numeric/levenberg_marquardt.h [new file with mode: 0644]
extern/libmv/libmv/numeric/numeric.cc [new file with mode: 0644]
extern/libmv/libmv/numeric/numeric.h [new file with mode: 0644]
extern/libmv/libmv/numeric/poly.cc [new file with mode: 0644]
extern/libmv/libmv/numeric/poly.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/bundle.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/bundle.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/camera_intrinsics.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/detect.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/detect.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/intersect.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/intersect.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/pipeline.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/pipeline.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/reconstruction.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/reconstruction.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/resect.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/resect.h [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/tracks.cc [new file with mode: 0644]
extern/libmv/libmv/simple_pipeline/tracks.h [new file with mode: 0644]
extern/libmv/libmv/tracking/klt_region_tracker.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/klt_region_tracker.h [new file with mode: 0644]
extern/libmv/libmv/tracking/pyramid_region_tracker.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/pyramid_region_tracker.h [new file with mode: 0644]
extern/libmv/libmv/tracking/region_tracker.h [new file with mode: 0644]
extern/libmv/libmv/tracking/retrack_region_tracker.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/retrack_region_tracker.h [new file with mode: 0644]
extern/libmv/libmv/tracking/sad.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/sad.h [new file with mode: 0644]
extern/libmv/libmv/tracking/trklt_region_tracker.cc [new file with mode: 0644]
extern/libmv/libmv/tracking/trklt_region_tracker.h [new file with mode: 0644]
extern/libmv/mkfiles.sh [new file with mode: 0755]
extern/libmv/patches/bundle_tweaks.patch [new file with mode: 0644]
extern/libmv/patches/config_mac.patch [new file with mode: 0644]
extern/libmv/patches/detect.patch [new file with mode: 0644]
extern/libmv/patches/fast.patch [new file with mode: 0644]
extern/libmv/patches/function_derivative.patch [new file with mode: 0644]
extern/libmv/patches/high_distortion_crash_fix.patch [new file with mode: 0644]
extern/libmv/patches/levenberg_marquardt.patch [new file with mode: 0644]
extern/libmv/patches/mingw.patch [new file with mode: 0644]
extern/libmv/patches/msvc2010.patch [new file with mode: 0644]
extern/libmv/patches/overscan.patch [new file with mode: 0644]
extern/libmv/patches/scaled_distortion.patch [new file with mode: 0644]
extern/libmv/patches/series [new file with mode: 0644]
extern/libmv/patches/snrptinf_fix.patch [new file with mode: 0644]
extern/libmv/patches/v3d_verbosity.patch [new file with mode: 0644]
extern/libmv/third_party/fast/LICENSE [new file with mode: 0644]
extern/libmv/third_party/fast/README [new file with mode: 0644]
extern/libmv/third_party/fast/README.libmv [new file with mode: 0644]
extern/libmv/third_party/fast/fast.c [new file with mode: 0644]
extern/libmv/third_party/fast/fast.h [new file with mode: 0644]
extern/libmv/third_party/fast/fast_10.c [new file with mode: 0644]
extern/libmv/third_party/fast/fast_11.c [new file with mode: 0644]
extern/libmv/third_party/fast/fast_12.c [new file with mode: 0644]
extern/libmv/third_party/fast/fast_9.c [new file with mode: 0644]
extern/libmv/third_party/fast/nonmax.c [new file with mode: 0644]
extern/libmv/third_party/gflags/README.libmv [new file with mode: 0644]
extern/libmv/third_party/gflags/config.h [new file with mode: 0644]
extern/libmv/third_party/gflags/gflags.cc [new file with mode: 0644]
extern/libmv/third_party/gflags/gflags.h [new file with mode: 0644]
extern/libmv/third_party/gflags/gflags_completions.cc [new file with mode: 0644]
extern/libmv/third_party/gflags/gflags_completions.h [new file with mode: 0644]
extern/libmv/third_party/gflags/gflags_reporting.cc [new file with mode: 0644]
extern/libmv/third_party/gflags/mutex.h [new file with mode: 0644]
extern/libmv/third_party/glog/AUTHORS [new file with mode: 0644]
extern/libmv/third_party/glog/COPYING [new file with mode: 0644]
extern/libmv/third_party/glog/ChangeLog [new file with mode: 0644]
extern/libmv/third_party/glog/NEWS [new file with mode: 0644]
extern/libmv/third_party/glog/README [new file with mode: 0644]
extern/libmv/third_party/glog/README.libmv [new file with mode: 0644]
extern/libmv/third_party/glog/src/base/commandlineflags.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/base/googleinit.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/base/mutex.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/config.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/config_linux.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/config_mac.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/demangle.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/demangle.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/glog/log_severity.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/glog/logging.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/glog/raw_logging.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/glog/vlog_is_on.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/logging.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/raw_logging.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/signalhandler.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace_generic-inl.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace_x86-inl.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/symbolize.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/symbolize.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/utilities.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/utilities.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/vlog_is_on.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/config.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/glog/log_severity.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/glog/logging.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/glog/raw_logging.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/port.cc [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/port.h [new file with mode: 0644]
extern/libmv/third_party/glog/src/windows/preprocess.sh [new file with mode: 0755]
extern/libmv/third_party/ldl/CMakeLists.txt [new file with mode: 0644]
extern/libmv/third_party/ldl/Doc/ChangeLog [new file with mode: 0644]
extern/libmv/third_party/ldl/Doc/lesser.txt [new file with mode: 0644]
extern/libmv/third_party/ldl/Include/ldl.h [new file with mode: 0644]
extern/libmv/third_party/ldl/README.libmv [new file with mode: 0644]
extern/libmv/third_party/ldl/README.txt [new file with mode: 0644]
extern/libmv/third_party/ldl/Source/ldl.c [new file with mode: 0644]
extern/libmv/third_party/msinttypes/README.libmv [new file with mode: 0644]
extern/libmv/third_party/msinttypes/inttypes.h [new file with mode: 0644]
extern/libmv/third_party/msinttypes/stdint.h [new file with mode: 0644]
extern/libmv/third_party/ssba/COPYING.TXT [new file with mode: 0644]
extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Geometry/v3d_distortion.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp [new file with mode: 0644]
extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Math/v3d_linear.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Math/v3d_linear_utils.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Math/v3d_mathutilities.h [new file with mode: 0644]
extern/libmv/third_party/ssba/Math/v3d_optimization.cpp [new file with mode: 0644]
extern/libmv/third_party/ssba/Math/v3d_optimization.h [new file with mode: 0644]
extern/libmv/third_party/ssba/README.TXT [new file with mode: 0644]
extern/libmv/third_party/ssba/README.libmv [new file with mode: 0755]
po/POTFILES.in [deleted file]
po/README.txt [deleted file]
po/check_po.py [deleted file]
po/clean_po.py [deleted file]
po/merge_po.py [deleted file]
po/update_mo.py [deleted file]
po/update_msg.py [deleted file]
po/update_po.py [deleted file]
po/update_pot.py [deleted file]
release/datafiles/blender_icons.png
release/scripts/modules/bpy_extras/keyconfig_utils.py
release/scripts/presets/tracking_camera/Blender.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_1100D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_1D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_1DS.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_500D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_550D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_5D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_600D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_60D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Canon_7D.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D300S.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D3100.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D35.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D5000.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D5100.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D7000.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Nikon_D90.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Red_Epic.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Red_One_2K.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Red_One_3K.py [new file with mode: 0644]
release/scripts/presets/tracking_camera/Red_One_4K.py [new file with mode: 0644]
release/scripts/presets/tracking_track_color/default.py [new file with mode: 0644]
release/scripts/presets/tracking_track_color/far_plane.py [new file with mode: 0644]
release/scripts/presets/tracking_track_color/near_plane.py [new file with mode: 0644]
release/scripts/startup/bl_operators/__init__.py
release/scripts/startup/bl_operators/clip.py [new file with mode: 0644]
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_ui/__init__.py
release/scripts/startup/bl_ui/properties_object.py
release/scripts/startup/bl_ui/properties_object_constraint.py
release/scripts/startup/bl_ui/properties_scene.py
release/scripts/startup/bl_ui/space_clip.py [new file with mode: 0644]
release/scripts/startup/bl_ui/space_filebrowser.py
release/scripts/startup/bl_ui/space_time.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/CMakeLists.txt
source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_bvhutils.h
source/blender/blenkernel/BKE_camera.h [new file with mode: 0644]
source/blender/blenkernel/BKE_context.h
source/blender/blenkernel/BKE_customdata_file.h
source/blender/blenkernel/BKE_effect.h
source/blender/blenkernel/BKE_lamp.h [new file with mode: 0644]
source/blender/blenkernel/BKE_lattice.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/BKE_movieclip.h [new file with mode: 0644]
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/BKE_pointcache.h
source/blender/blenkernel/BKE_property.h
source/blender/blenkernel/BKE_scene.h
source/blender/blenkernel/BKE_sequencer.h
source/blender/blenkernel/BKE_text.h
source/blender/blenkernel/BKE_tracking.h [new file with mode: 0644]
source/blender/blenkernel/BKE_unit.h
source/blender/blenkernel/BKE_writeffmpeg.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/boids.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/bvhutils.c
source/blender/blenkernel/intern/camera.c [new file with mode: 0644]
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/customdata_file.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/fluidsim.c
source/blender/blenkernel/intern/group.c
source/blender/blenkernel/intern/idcode.c
source/blender/blenkernel/intern/key.c
source/blender/blenkernel/intern/lamp.c [new file with mode: 0644]
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/mesh.c
source/blender/blenkernel/intern/movieclip.c [new file with mode: 0644]
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/blenkernel/intern/property.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/blenkernel/intern/smoke.c
source/blender/blenkernel/intern/softbody.c
source/blender/blenkernel/intern/speaker.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/tracking.c [new file with mode: 0644]
source/blender/blenkernel/intern/unit.c
source/blender/blenkernel/intern/world.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenlib/BLI_kdopbvh.h
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/blenlib/intern/bpath.c
source/blender/blenlib/intern/graph.c
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenlib/intern/threads.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/readfile.h
source/blender/blenloader/intern/writefile.c
source/blender/collada/AnimationExporter.cpp
source/blender/collada/AnimationExporter.h
source/blender/collada/DocumentImporter.cpp
source/blender/editors/CMakeLists.txt
source/blender/editors/SConscript
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_markers.c
source/blender/editors/animation/keyframing.c
source/blender/editors/armature/armature_intern.h
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/editarmature_retarget.c
source/blender/editors/armature/editarmature_sketch.c
source/blender/editors/armature/meshlaplacian.c
source/blender/editors/armature/poseUtils.c
source/blender/editors/curve/editcurve.c
source/blender/editors/datafiles/blender_icons.png.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/editaction_gpencil.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_anim_api.h
source/blender/editors/include/ED_armature.h
source/blender/editors/include/ED_clip.h [new file with mode: 0644]
source/blender/editors/include/ED_fluidsim.h
source/blender/editors/include/ED_logic.h
source/blender/editors/include/ED_particle.h
source/blender/editors/include/ED_space_api.h
source/blender/editors/include/ED_transform.h
source/blender/editors/include/ED_view3d.h
source/blender/editors/include/UI_icons.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/mesh/editmesh.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_lattice.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_relations.c
source/blender/editors/object/object_transform.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/particle_object.c
source/blender/editors/render/render_preview.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_utils.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/space_api/spacetypes.c
source/blender/editors/space_buttons/buttons_ops.c
source/blender/editors/space_clip/CMakeLists.txt [new file with mode: 0644]
source/blender/editors/space_clip/SConscript [new file with mode: 0644]
source/blender/editors/space_clip/clip_buttons.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_draw.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_editor.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_graph_draw.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_graph_ops.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_intern.h [new file with mode: 0644]
source/blender/editors/space_clip/clip_ops.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_toolbar.c [new file with mode: 0644]
source/blender/editors/space_clip/clip_utils.c [new file with mode: 0644]
source/blender/editors/space_clip/space_clip.c [new file with mode: 0644]
source/blender/editors/space_clip/tracking_ops.c [new file with mode: 0644]
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filelist.h
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_intern.h
source/blender/editors/space_info/textview.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/drawvolume.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_input.c
source/blender/editors/transform/transform_ops.c
source/blender/editors/transform/transform_orientations.c
source/blender/editors/util/CMakeLists.txt
source/blender/editors/util/crazyspace.c
source/blender/editors/util/editmode_undo.c
source/blender/editors/util/undo.c
source/blender/editors/util/util_intern.h
source/blender/editors/uvedit/uvedit_draw.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/gpu/intern/gpu_material.c
source/blender/ikplugin/intern/iksolver_plugin.c
source/blender/ikplugin/intern/itasc_plugin.cpp
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_action_types.h
source/blender/makesdna/DNA_constraint_types.h
source/blender/makesdna/DNA_movieclip_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_object_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_tracking_types.h [new file with mode: 0644]
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_view3d_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/CMakeLists.txt
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_camera_api.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_movieclip.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_screen.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_texture_api.c
source/blender/makesrna/intern/rna_tracking.c [new file with mode: 0644]
source/blender/makesrna/intern/rna_ui_api.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/makesrna/intern/rna_wm.c
source/blender/modifiers/intern/MOD_build.c
source/blender/modifiers/intern/MOD_explode.c
source/blender/modifiers/intern/MOD_particleinstance.c
source/blender/modifiers/intern/MOD_simpledeform.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/node_composite_util.c
source/blender/nodes/composite/node_composite_util.h
source/blender/nodes/composite/nodes/node_composite_alphaOver.c
source/blender/nodes/composite/nodes/node_composite_blur.c
source/blender/nodes/composite/nodes/node_composite_colorMatte.c
source/blender/nodes/composite/nodes/node_composite_curves.c
source/blender/nodes/composite/nodes/node_composite_diffMatte.c
source/blender/nodes/composite/nodes/node_composite_distanceMatte.c
source/blender/nodes/composite/nodes/node_composite_filter.c
source/blender/nodes/composite/nodes/node_composite_hueSatVal.c
source/blender/nodes/composite/nodes/node_composite_image.c
source/blender/nodes/composite/nodes/node_composite_invert.c
source/blender/nodes/composite/nodes/node_composite_mixrgb.c
source/blender/nodes/composite/nodes/node_composite_movieclip.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_moviedistortion.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_normal.c
source/blender/nodes/composite/nodes/node_composite_normalize.c
source/blender/nodes/composite/nodes/node_composite_rgb.c
source/blender/nodes/composite/nodes/node_composite_scale.c
source/blender/nodes/composite/nodes/node_composite_splitViewer.c
source/blender/nodes/composite/nodes/node_composite_stabilize2d.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_texture.c
source/blender/nodes/composite/nodes/node_composite_transform.c [new file with mode: 0644]
source/blender/nodes/composite/nodes/node_composite_zcombine.c
source/blender/nodes/shader/node_shader_util.c
source/blender/nodes/shader/nodes/node_shader_camera.c
source/blender/nodes/shader/nodes/node_shader_geom.c
source/blender/nodes/shader/nodes/node_shader_hueSatVal.c
source/blender/nodes/shader/nodes/node_shader_invert.c
source/blender/nodes/shader/nodes/node_shader_material.c
source/blender/nodes/shader/nodes/node_shader_mixRgb.c
source/blender/nodes/shader/nodes/node_shader_normal.c
source/blender/nodes/shader/nodes/node_shader_output.c
source/blender/nodes/shader/nodes/node_shader_rgb.c
source/blender/nodes/shader/nodes/node_shader_texture.c
source/blender/nodes/texture/nodes/node_texture_bricks.c
source/blender/nodes/texture/nodes/node_texture_hueSatVal.c
source/blender/nodes/texture/nodes/node_texture_image.c
source/blender/nodes/texture/nodes/node_texture_invert.c
source/blender/nodes/texture/nodes/node_texture_mixRgb.c
source/blender/nodes/texture/nodes/node_texture_proc.c
source/blender/nodes/texture/nodes/node_texture_texture.c
source/blender/python/generic/bgl.c
source/blender/python/generic/bgl.h
source/blender/python/generic/blf_py_api.c
source/blender/python/generic/bpy_internal_import.c
source/blender/python/generic/noise_py_api.c
source/blender/python/generic/py_capi_utils.c
source/blender/python/intern/bpy.c
source/blender/python/intern/bpy_app.c
source/blender/python/intern/bpy_app_handlers.c
source/blender/python/intern/bpy_driver.c
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_interface_atexit.c
source/blender/python/intern/bpy_intern_string.c
source/blender/python/intern/bpy_library.c
source/blender/python/intern/bpy_operator.c
source/blender/python/intern/bpy_operator_wrap.c
source/blender/python/intern/bpy_props.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna_anim.c
source/blender/python/intern/bpy_rna_array.c
source/blender/python/intern/bpy_rna_callback.c
source/blender/python/intern/bpy_traceback.c
source/blender/python/intern/bpy_util.c
source/blender/python/intern/gpu.c
source/blender/python/mathutils/mathutils_geometry.c
source/blender/render/intern/include/rendercore.h
source/blender/render/intern/include/zbuf.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/initrender.c
source/blender/render/intern/source/occlusion.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/pixelshading.c
source/blender/render/intern/source/pointdensity.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeinput.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/sss.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/volume_precache.c
source/blender/render/intern/source/voxeldata.c
source/blender/render/intern/source/zbuf.c
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/CMakeLists.txt
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/creator/creator.c
source/gameengine/Converter/BL_ActionActuator.cpp
source/gameengine/Converter/BL_ActionActuator.h
source/gameengine/Converter/BL_ArmatureActuator.h
source/gameengine/Converter/BL_ArmatureConstraint.h
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_ArmatureObject.h
source/gameengine/Converter/BL_ShapeActionActuator.h
source/gameengine/Expressions/Expression.h
source/gameengine/Expressions/ListValue.h
source/gameengine/Expressions/PyObjectPlus.cpp
source/gameengine/Expressions/PyObjectPlus.h
source/gameengine/Expressions/Value.cpp
source/gameengine/Expressions/Value.h
source/gameengine/GameLogic/SCA_2DFilterActuator.h
source/gameengine/GameLogic/SCA_ANDController.h
source/gameengine/GameLogic/SCA_ActuatorSensor.h
source/gameengine/GameLogic/SCA_AlwaysSensor.h
source/gameengine/GameLogic/SCA_DelaySensor.h
source/gameengine/GameLogic/SCA_ExpressionController.h
source/gameengine/GameLogic/SCA_IController.h
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GameLogic/SCA_IObject.h
source/gameengine/GameLogic/SCA_ISensor.h
source/gameengine/GameLogic/SCA_JoystickSensor.h
source/gameengine/GameLogic/SCA_KeyboardSensor.h
source/gameengine/GameLogic/SCA_MouseSensor.h
source/gameengine/GameLogic/SCA_NANDController.h
source/gameengine/GameLogic/SCA_NORController.h
source/gameengine/GameLogic/SCA_ORController.h
source/gameengine/GameLogic/SCA_PropertyActuator.h
source/gameengine/GameLogic/SCA_PropertySensor.h
source/gameengine/GameLogic/SCA_PythonController.cpp
source/gameengine/GameLogic/SCA_PythonController.h
source/gameengine/GameLogic/SCA_PythonKeyboard.h
source/gameengine/GameLogic/SCA_PythonMouse.h
source/gameengine/GameLogic/SCA_RandomActuator.h
source/gameengine/GameLogic/SCA_RandomSensor.h
source/gameengine/GameLogic/SCA_XNORController.h
source/gameengine/GameLogic/SCA_XORController.h
source/gameengine/Ketsji/BL_Shader.h
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h
source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h
source/gameengine/Ketsji/KX_ArmatureSensor.h
source/gameengine/Ketsji/KX_BlenderMaterial.h
source/gameengine/Ketsji/KX_Camera.h
source/gameengine/Ketsji/KX_CameraActuator.h
source/gameengine/Ketsji/KX_ConstraintActuator.h
source/gameengine/Ketsji/KX_ConstraintWrapper.h
source/gameengine/Ketsji/KX_FontObject.h
source/gameengine/Ketsji/KX_GameActuator.h
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_IpoActuator.h
source/gameengine/Ketsji/KX_Light.h
source/gameengine/Ketsji/KX_MeshProxy.cpp
source/gameengine/Ketsji/KX_MeshProxy.h
source/gameengine/Ketsji/KX_MouseFocusSensor.h
source/gameengine/Ketsji/KX_NavMeshObject.h
source/gameengine/Ketsji/KX_NearSensor.h
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_ParentActuator.h
source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h
source/gameengine/Ketsji/KX_PolyProxy.cpp
source/gameengine/Ketsji/KX_PolyProxy.h
source/gameengine/Ketsji/KX_PolygonMaterial.cpp
source/gameengine/Ketsji/KX_PolygonMaterial.h
source/gameengine/Ketsji/KX_RadarSensor.h
source/gameengine/Ketsji/KX_RaySensor.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_SCA_DynamicActuator.h
source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h
source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SceneActuator.h
source/gameengine/Ketsji/KX_SoundActuator.h
source/gameengine/Ketsji/KX_StateActuator.h
source/gameengine/Ketsji/KX_SteeringActuator.h
source/gameengine/Ketsji/KX_TouchSensor.h
source/gameengine/Ketsji/KX_TrackToActuator.h
source/gameengine/Ketsji/KX_VehicleWrapper.h
source/gameengine/Ketsji/KX_VertexProxy.h
source/gameengine/Ketsji/KX_VisibilityActuator.h

index 0e06f39..43f52ef 100644 (file)
@@ -202,6 +202,9 @@ option(WITH_JACK          "Enable Jack Support (http://www.jackaudio.org)" OFF)
 option(WITH_LZO           "Enable fast LZO compression (used for pointcache)" ON)
 option(WITH_LZMA          "Enable best LZMA compression, (used for pointcache)" ON)
 
+# Camera/motion tracking
+option(WITH_LIBMV         "Enable libmv structure from motion library" ON)
+
 # Misc
 option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
 option(WITH_RAYOPTIMIZATION    "Enable use of SIMD (SSE) optimizations for the raytracer" ON)
@@ -488,6 +491,36 @@ if(UNIX AND NOT APPLE)
                endif()
        endif()
 
+       if(WITH_BOOST)
+               set(BOOST "/usr" CACHE PATH "Boost Directory")
+
+               if(NOT BOOST_CUSTOM)
+                       set(BOOST_ROOT ${BOOST})
+                       set(Boost_USE_MULTITHREADED ON)
+                       find_package(Boost 1.34 REQUIRED COMPONENTS filesystem regex system thread)
+               endif()
+
+               set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
+               set(BOOST_LIBRARIES ${Boost_LIBRARIES})
+               set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS})
+               set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+       endif()
+
+       if(WITH_OPENIMAGEIO)
+               set(OPENIMAGEIO "/usr" CACHE PATH "OpenImageIO Directory")
+
+               set(OPENIMAGEIO_ROOT_DIR ${OPENIMAGEIO})
+               find_package(OpenImageIO REQUIRED)
+
+               set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES})
+               set(OPENIMAGEIO_LIBPATH)  # TODO, remove and reference the absolute path everywhere
+               set(OPENIMAGEIO_DEFINITIONS)
+
+               if(NOT OPENIMAGEIO_FOUND)
+                       set(WITH_OPENIMAGEIO OFF)
+               endif()
+       endif()
+
        # OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed
        set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++")
 
@@ -774,6 +807,28 @@ elseif(WIN32)
                        set(PYTHON_LIBRARIES  "${PYTHON_LIBRARY}")
                endif()
 
+               if(WITH_BOOST)
+                       set(BOOST ${LIBDIR}/boost)
+                       set(BOOST_INCLUDE_DIR ${BOOST}/include)
+                       set(BOOST_POSTFIX "vc90-mt-s-1_47.lib")
+                       set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_47.lib")
+                       set(BOOST_LIBRARIES
+                               optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX}
+                               libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX}
+                               debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX}
+                               libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX})
+                       set(BOOST_LIBPATH ${BOOST}/lib)
+                       set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+               endif()
+                       
+               if(WITH_OPENIMAGEIO)
+                       set(OPENIMAGEIO ${LIBDIR}/openimageio)
+                       set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+                       set(OPENIMAGEIO_LIBRARIES OpenImageIO)
+                       set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
+                       set(OPENIMAGEIO_DEFINITIONS)
+               endif()
+
                set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib")
 
                # MSVC only, Mingw doesnt need
@@ -884,6 +939,28 @@ elseif(WIN32)
                        set(PYTHON_LIBRARIES  "${PYTHON_LIBRARY}")
                endif()
 
+               if(WITH_BOOST)
+                       set(BOOST ${LIBDIR}/boost)
+                       set(BOOST_INCLUDE_DIR ${BOOST}/include)
+                       set(BOOST_POSTFIX "vc90-mt-s-1_46_1")
+                       set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_46_1")
+                       set(BOOST_LIBRARIES
+                               optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX}
+                               libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX}
+                               debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX}
+                               libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX})
+                       set(BOOST_LIBPATH ${BOOST}/lib)
+                       set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB")
+               endif()
+                       
+               if(WITH_OPENIMAGEIO)
+                       set(OPENIMAGEIO ${LIBDIR}/openimageio)
+                       set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+                       set(OPENIMAGEIO_LIBRARIES OpenImageIO)
+                       set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib)
+                       set(OPENIMAGEIO_DEFINITIONS)
+               endif()
+
                set(PLATFORM_LINKFLAGS "--stack,2097152")
 
        endif()
@@ -1087,6 +1164,22 @@ elseif(APPLE)
                # linker needs "-weak_framework 3DconnexionClient"
        endif()
 
+       if(WITH_BOOST)
+               set(BOOST ${LIBDIR}/boost)
+               set(BOOST_INCLUDE_DIR ${BOOST}/include)
+               set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt)
+               set(BOOST_LIBPATH ${BOOST}/lib)
+               set(BOOST_DEFINITIONS)
+       endif()
+
+       if(WITH_OPENIMAGEIO)
+               set(OPENIMAGEIO ${LIBDIR}/openimageio)
+               set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include)
+               set(OPENIMAGEIO_LIBRARIES OpenImageIO ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
+               set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH})
+               set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD")
+       endif()
+
        set(EXETYPE MACOSX_BUNDLE)
 
        set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g")
index f6a6ee9..640e90d 100644 (file)
@@ -135,9 +135,6 @@ help:
        @echo "  * package_pacman  - build an arch linux pacmanpackage"
        @echo "  * package_archive - build an archive package"
        @echo ""
-       @echo "Other Targets (not assosiated with building blender)"
-       @echo "  * translations  - update blenders translation files in po/"
-       @echo ""
        @echo "Testing Targets (not assosiated with building blender)"
        @echo "  * test            - run ctest, currently tests import/export, operator execution and that python modules load"
        @echo "  * test_cmake      - runs our own cmake file checker which detects errors in the cmake file list definitions"
@@ -170,16 +167,6 @@ package_archive:
        @echo archive in "$(BUILD_DIR)/release"
 
 
-# -----------------------------------------------------------------------------
-# Other Targets
-#
-translations:
-       $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python po/update_msg.py
-       python3 po/update_pot.py
-       python3 po/update_po.py
-       python3 po/update_mo.py
-
-
 # -----------------------------------------------------------------------------
 # Tests
 #
index 6791028..0da28a9 100644 (file)
@@ -13,6 +13,7 @@ set(WITH_BULLET              OFF CACHE FORCE BOOL)
 set(WITH_CODEC_FFMPEG        OFF CACHE FORCE BOOL)
 set(WITH_CODEC_SNDFILE       OFF CACHE FORCE BOOL)
 set(WITH_FFTW3               OFF CACHE FORCE BOOL)
+set(WITH_LIBMV               OFF CACHE FORCE BOOL)
 set(WITH_GAMEENGINE          OFF CACHE FORCE BOOL)
 set(WITH_IK_ITASC            OFF CACHE FORCE BOOL)
 set(WITH_IMAGE_CINEON        OFF CACHE FORCE BOOL)
index 10f8979..c9a04f8 100644 (file)
@@ -165,6 +165,12 @@ macro(SETUP_LIBDIRS)
        if(WITH_IMAGE_TIFF)
                link_directories(${TIFF_LIBPATH})
        endif()
+       if(WITH_BOOST)
+               link_directories(${BOOST_LIBPATH})
+       endif()
+       if(WITH_OPENIMAGEIO)
+               link_directories(${OPENIMAGEIO_LIBPATH})
+       endif()
        if(WITH_IMAGE_OPENJPEG AND UNIX AND NOT APPLE)
                link_directories(${OPENJPEG_LIBPATH})
        endif()
@@ -259,6 +265,12 @@ macro(setup_liblinks
        if(WITH_IMAGE_TIFF)
                target_link_libraries(${target} ${TIFF_LIBRARY})
        endif()
+       if(WITH_OPENIMAGEIO)
+               target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES})
+       endif()
+       if(WITH_BOOST)
+               target_link_libraries(${target} ${BOOST_LIBRARIES})
+       endif()
        if(WITH_IMAGE_OPENEXR)
                if(WIN32 AND NOT UNIX)
                        file_list_suffix(OPENEXR_LIBRARIES_DEBUG "${OPENEXR_LIBRARIES}" "_d")
@@ -618,3 +630,38 @@ macro(blender_project_hack_post)
        endif()
 
 endmacro()
+
+# pair of macros to allow libraries to be specify files to install, but to
+# only install them at the end so the directories don't get cleared with
+# the files in them. used by cycles to install addon.
+macro(delayed_install
+       base
+       files
+       destination)
+
+       foreach(f ${files})
+               set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f})
+               set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination})
+       endforeach()
+endmacro()
+
+# note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir
+# does not get expanded in calling but is preserved
+function(delayed_do_install
+       targetdir)
+
+       get_property(files GLOBAL PROPERTY DELAYED_INSTALL_FILES)
+       get_property(destinations GLOBAL PROPERTY DELAYED_INSTALL_DESTINATIONS)
+
+       if(files)
+               list(LENGTH files n)
+               math(EXPR n "${n}-1")
+
+               foreach(i RANGE ${n})
+                       list(GET files ${i} f)
+                       list(GET destinations ${i} d)
+                       install(FILES ${f} DESTINATION ${targetdir}/${d})
+               endforeach()
+       endif()
+endfunction()
+
index 44f9a4c..ba15f1c 100644 (file)
@@ -329,6 +329,10 @@ def creator(env):
     if env['WITH_BF_SDL']:
         defs.append('WITH_SDL')
 
+    if env['WITH_BF_LIBMV']:
+        incs.append('#/extern/libmv')
+        defs.append('WITH_LIBMV')
+
     if env['WITH_BF_PYTHON']:
         incs.append('#/source/blender/python')
         defs.append('WITH_PYTHON')
index 68054fe..5c78dc6 100644 (file)
@@ -515,6 +515,8 @@ def read_opts(env, cfg, args):
         (BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)),
         (BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)),
         
+        (BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)),
+
         ('BF_X264_CONFIG', 'configuration flags for x264', ''),
         ('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''),
 #        (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)),
index dd112ed..e8fb065 100644 (file)
@@ -44,7 +44,7 @@ PROJECT_BRIEF          =
 # exceed 55 pixels and the maximum width should not exceed 200 pixels. 
 # Doxygen will copy the logo to the output directory.
 
-PROJECT_LOGO           = ../../release/freedesktop/icons/48x48/blender.png
+PROJECT_LOGO           = ../../release/freedesktop/icons/48x48/apps/blender.png
 
 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
 # base path where the generated documentation will be put. 
index 321ebc1..a5dd3b1 100644 (file)
@@ -63,3 +63,7 @@ endif()
 if(WITH_LZMA)
        add_subdirectory(lzma)
 endif()
+
+if(WITH_LIBMV)
+       add_subdirectory(libmv)
+endif()
index f363d75..031471a 100644 (file)
@@ -28,3 +28,6 @@ if env['WITH_BF_LZO']:
 
 if env['WITH_BF_LZMA']:
     SConscript(['lzma/SConscript'])
+
+if env['WITH_BF_LIBMV']:
+    SConscript(['libmv/SConscript'])
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
new file mode 100644 (file)
index 0000000..41fc39c
--- /dev/null
@@ -0,0 +1,210 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+#                 Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+       .
+       ../Eigen3
+       ./third_party/ssba
+       ./third_party/ldl/Include
+       ../colamd/Include
+)
+
+set(INC_SYS
+       ${PNG_INCLUDE_DIR}
+       ${ZLIB_INCLUDE_DIRS}
+)
+
+set(SRC
+       libmv-capi.cpp
+       libmv/numeric/numeric.cc
+       libmv/numeric/poly.cc
+       libmv/simple_pipeline/reconstruction.cc
+       libmv/simple_pipeline/resect.cc
+       libmv/simple_pipeline/intersect.cc
+       libmv/simple_pipeline/initialize_reconstruction.cc
+       libmv/simple_pipeline/camera_intrinsics.cc
+       libmv/simple_pipeline/pipeline.cc
+       libmv/simple_pipeline/detect.cc
+       libmv/simple_pipeline/tracks.cc
+       libmv/simple_pipeline/bundle.cc
+       libmv/image/convolve.cc
+       libmv/image/array_nd.cc
+       libmv/tracking/pyramid_region_tracker.cc
+       libmv/tracking/sad.cc
+       libmv/tracking/trklt_region_tracker.cc
+       libmv/tracking/klt_region_tracker.cc
+       libmv/tracking/retrack_region_tracker.cc
+       libmv/multiview/projection.cc
+       libmv/multiview/conditioning.cc
+       libmv/multiview/fundamental.cc
+       libmv/multiview/euclidean_resection.cc
+       libmv/multiview/triangulation.cc
+
+       third_party/ssba/Geometry/v3d_metricbundle.cpp
+       third_party/ssba/Math/v3d_optimization.cpp
+       third_party/gflags/gflags.cc
+       third_party/gflags/gflags_reporting.cc
+       third_party/gflags/gflags_completions.cc
+       third_party/fast/fast_9.c
+       third_party/fast/fast_10.c
+       third_party/fast/fast_11.c
+       third_party/fast/fast_12.c
+       third_party/fast/fast.c
+       third_party/fast/nonmax.c
+       third_party/ldl/Source/ldl.c
+
+       libmv-capi.h
+       libmv/logging/logging.h
+       libmv/numeric/dogleg.h
+       libmv/numeric/levenberg_marquardt.h
+       libmv/numeric/poly.h
+       libmv/numeric/function_derivative.h
+       libmv/numeric/numeric.h
+       libmv/simple_pipeline/resect.h
+       libmv/simple_pipeline/reconstruction.h
+       libmv/simple_pipeline/camera_intrinsics.h
+       libmv/simple_pipeline/tracks.h
+       libmv/simple_pipeline/detect.h
+       libmv/simple_pipeline/pipeline.h
+       libmv/simple_pipeline/intersect.h
+       libmv/simple_pipeline/bundle.h
+       libmv/simple_pipeline/initialize_reconstruction.h
+       libmv/image/convolve.h
+       libmv/image/tuple.h
+       libmv/image/array_nd.h
+       libmv/image/sample.h
+       libmv/image/image.h
+       libmv/tracking/region_tracker.h
+       libmv/tracking/retrack_region_tracker.h
+       libmv/tracking/sad.h
+       libmv/tracking/pyramid_region_tracker.h
+       libmv/tracking/trklt_region_tracker.h
+       libmv/tracking/klt_region_tracker.h
+       libmv/base/id_generator.h
+       libmv/base/vector.h
+       libmv/base/scoped_ptr.h
+       libmv/base/vector_utils.h
+       libmv/multiview/nviewtriangulation.h
+       libmv/multiview/resection.h
+       libmv/multiview/euclidean_resection.h
+       libmv/multiview/triangulation.h
+       libmv/multiview/projection.h
+       libmv/multiview/fundamental.h
+       libmv/multiview/conditioning.h
+
+       third_party/ssba/Geometry/v3d_metricbundle.h
+       third_party/ssba/Geometry/v3d_cameramatrix.h
+       third_party/ssba/Geometry/v3d_distortion.h
+       third_party/ssba/Math/v3d_linear_utils.h
+       third_party/ssba/Math/v3d_optimization.h
+       third_party/ssba/Math/v3d_mathutilities.h
+       third_party/ssba/Math/v3d_linear.h
+       third_party/gflags/gflags_completions.h
+       third_party/gflags/mutex.h
+       third_party/gflags/config.h
+       third_party/gflags/gflags.h
+       third_party/fast/fast.h
+       third_party/ldl/Include/ldl.h
+       third_party/msinttypes/stdint.h
+       third_party/msinttypes/inttypes.h
+)
+
+IF(WIN32)
+       list(APPEND SRC
+               third_party/glog/src/logging.cc
+               third_party/glog/src/raw_logging.cc
+               third_party/glog/src/utilities.cc
+               third_party/glog/src/vlog_is_on.cc
+               third_party/glog/src/windows/port.cc
+
+               third_party/glog/src/utilities.h
+               third_party/glog/src/stacktrace_generic-inl.h
+               third_party/glog/src/stacktrace.h
+               third_party/glog/src/stacktrace_x86_64-inl.h
+               third_party/glog/src/base/googleinit.h
+               third_party/glog/src/base/mutex.h
+               third_party/glog/src/base/commandlineflags.h
+               third_party/glog/src/stacktrace_powerpc-inl.h
+               third_party/glog/src/stacktrace_x86-inl.h
+               third_party/glog/src/config.h
+               third_party/glog/src/stacktrace_libunwind-inl.h
+               third_party/glog/src/windows/glog/raw_logging.h
+               third_party/glog/src/windows/glog/vlog_is_on.h
+               third_party/glog/src/windows/glog/logging.h
+               third_party/glog/src/windows/glog/log_severity.h
+               third_party/glog/src/windows/port.h
+               third_party/glog/src/windows/config.h
+       )
+
+       list(APPEND INC
+               ./third_party/glog/src/windows
+               ./third_party/msinttypes
+       )
+
+       IF(MSVC)
+               set(MSVC_OFLAGS O1 O2 Ox)
+               foreach(FLAG )
+                       string(REPLACE "" "Od" CMAKE_CXX_FLAGS_RELEASE "")
+                       string(REPLACE "" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "")
+               endforeach()
+       ENDIF(MSVC)
+ELSE(WIN32)
+       list(APPEND SRC
+               third_party/glog/src/utilities.cc
+               third_party/glog/src/symbolize.cc
+               third_party/glog/src/vlog_is_on.cc
+               third_party/glog/src/signalhandler.cc
+               third_party/glog/src/logging.cc
+               third_party/glog/src/demangle.cc
+               third_party/glog/src/raw_logging.cc
+
+               third_party/glog/src/utilities.h
+               third_party/glog/src/stacktrace_generic-inl.h
+               third_party/glog/src/config_mac.h
+               third_party/glog/src/stacktrace.h
+               third_party/glog/src/stacktrace_x86_64-inl.h
+               third_party/glog/src/symbolize.h
+               third_party/glog/src/base/googleinit.h
+               third_party/glog/src/base/mutex.h
+               third_party/glog/src/base/commandlineflags.h
+               third_party/glog/src/stacktrace_powerpc-inl.h
+               third_party/glog/src/stacktrace_x86-inl.h
+               third_party/glog/src/config.h
+               third_party/glog/src/demangle.h
+               third_party/glog/src/stacktrace_libunwind-inl.h
+               third_party/glog/src/glog/raw_logging.h
+               third_party/glog/src/glog/vlog_is_on.h
+               third_party/glog/src/glog/logging.h
+               third_party/glog/src/glog/log_severity.h
+               third_party/glog/src/config_linux.h
+       )
+
+       list(APPEND INC
+               ./third_party/glog/src
+       )
+ENDIF(WIN32)
+
+add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=)
+
+blender_add_lib(extern_libmv "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog
new file mode 100644 (file)
index 0000000..7e10abf
--- /dev/null
@@ -0,0 +1,312 @@
+commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sat Aug 20 00:00:42 2011 +0200
+
+    Display warped pattern in marker preview.
+
+commit bb5c27e671b6f8eb56ddf490f0795d59bede591b
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 18:37:48 2011 +0200
+
+    Fix CMake build.
+
+commit 2ac7281ff6b9545b425dd84fb03bf9c5c98b4de2
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 17:34:45 2011 +0200
+
+    Avoid symbol shadowing.
+
+commit 2a7c3de4acc60e0433b4952f69e30528dbafe0d2
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 17:22:47 2011 +0200
+
+    Better dragging behavior when hitting borders.
+
+commit a14eb3953c9521b2e08ff9ddd45b33ff1f8aeafb
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 17:12:12 2011 +0200
+
+    Update marker preview to new affine tracking.
+
+commit 5299ea67043459eda147950e589c2d327a8fbced
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 16:05:54 2011 +0200
+
+    sqrt takes double precision.
+
+commit 9f9221ce151d788c49b48f6f293ab2e2f8813978
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 16:04:37 2011 +0200
+
+    MSVC compatibility: heap allocate pattern, explicit float cast.
+
+commit 702658d2f8616964a6eeb3743fd85e97ac7ff09d
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 14:59:24 2011 +0200
+
+    Expose regularization parameters (areaPenalty and conditionPenalty) in API.
+
+commit 3e84ae5fbac10451d4935418f6281a90cedace11
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 14:19:27 2011 +0200
+
+    Add LaplaceFilter.
+    Add regularization in affine SAD Tracker (keep constant area and good condition number).
+    UI: Better track display (+enable line antialiasing).
+
+commit 6d26d9a8ccc4ce009fbf253898fea8864dd5001a
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 10:25:26 2011 +0200
+
+    Add optimization for integer pixel search.
+    Allows more agressive settings for affine coordinate descent.
+
+commit 70ceae81c0ab561b07e640ecb9933f0a902b57cd
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 19 00:02:12 2011 +0200
+
+    Document coordinate descent method in affine SAD matcher.
+    Add heuristic to prevent high distortions.
+
+commit 75520f4bc4ccbb272a1b4149d3b8d05a90f7f896
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 23:14:17 2011 +0200
+
+    Fix affine iteration.
+
+commit 4e8e0aa6018e3eb2fbebdad7f1cbd6c909d26e79
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 23:03:26 2011 +0200
+
+    Handle rotations.
+
+commit 3ce41cf3c1b5c136a61d8f4c63ccae3cafbdb8da
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 22:24:47 2011 +0200
+
+    Slow brute-force affine diamond search implementation.
+
+commit 1c4acd03e030c1c50dc6fc36c419c72ea69a0713
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 20:51:43 2011 +0200
+
+    Fix detect.cc.
+
+commit ec18cc5ea9ae2e641075a847e82d0aacb8415ad8
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 17:45:37 2011 +0200
+
+    Compute and return Pearson product-moment correlation coefficient between reference and matched pattern.
+
+commit 21d4245c63a01bfc736192d55baf10983e7c9ec7
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Aug 18 16:18:44 2011 +0200
+
+    UI and API support for affine tracking.
+
+commit a4876d8c40dcde615b44009c38c49e9a1b1d4698
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Aug 17 20:26:01 2011 +0200
+
+    Hack to make sad.cc compile with MSVC on system without support for the SSE instruction set.
+
+commit 0de723dfce5bbe44dbd19be8cd6dd6e9b03b7924
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Aug 17 20:10:46 2011 +0200
+
+    Fix slow path (for computers without SSE2).
+    Heap allocate scores in detect.cc
+
+commit 65a9d496f81e8b37eae39a4063957b8be9a4e6f0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Aug 17 19:25:17 2011 +0200
+
+    Fix compilation on OSX.
+
+commit d22720e618456329388d2c107422c3b371657cba
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Aug 17 14:14:45 2011 +0200
+
+    Improve Detect and SAD Tracker API and documentation.
+
+commit 5d6cd4ad365b061901bad40695b51d568487a0cf
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Aug 17 11:57:29 2011 +0200
+
+    MSVC support fixes.
+
+commit 50f0323173c6deebd6aaf9c126f0b51b2a79c3c1
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 23:21:37 2011 +0200
+
+    Detector can detect features similar to a given pattern.
+
+commit 5734cc27bbf84c2b6edcfcc1ea736798e12d5820
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 22:53:54 2011 +0200
+
+    Ensure SAD Tracker is C compatible.
+    Update Detect API documentation.
+
+commit 701c42842574064fea992f8822e3899cb9066108
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 21:56:42 2011 +0200
+
+    Remove FAST detector.
+    Add Moravec detector.
+    This detector is more suited to tracking since it try to choose patterns which are unlikely to drift by computing SAD with neighbouring patches.
+    It could be improved to better avoid edges.
+
+commit 9bdf93e13fc880c78b6f34397da673388c16040e
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 21:55:08 2011 +0200
+
+    Fix Qt Tracker GL to work with AMD drivers.
+
+commit 81613ee0cc94b315f333c9632b18b95d426aad05
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 21:54:12 2011 +0200
+
+    Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv.
+
+commit a1d9a8fa8b01ef7cf2a79b3b891633fc333fc9cf
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 21:24:51 2011 +0200
+
+    Fix SAD tracker. Pattern was transposed by affine pattern sampler.
+
+commit c3b794da2e7fd23f2fbdf90dbd71de0e6b3bc811
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 16 21:19:02 2011 +0200
+
+    Fix SAD tracker. Pattern was transposed by affine pattern sampler.
+
+commit a9b61bf3356f27174cdd983f562f99c3a6a2cc35
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sun Aug 14 09:56:51 2011 +0200
+
+    Clarify CameraIntrinsics documentation.
+    Edit CameraInstrinsics test to fail.
+
+commit 10bdad9ad2cea2603896263cde5a5339169a9af0
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 12 21:05:32 2011 +0200
+
+    Fix out of bound access in warp bilinear sampling.
+
+commit dd9a418db021a28af2c1198d5e5b9e68fe048a03
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 12 19:14:36 2011 +0200
+
+    Fix compilation with -funsigned-char.
+
+commit bd1a268ede39b67f2ba4b360f6fc693419e7cd7f
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Aug 12 18:39:27 2011 +0200
+
+    CameraIntrinsics fixes.
+
+commit ae513b39fb779632f96ceff7c1e014fb8e68702a
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 19:38:58 2011 +0200
+
+    Remove stray QDebug include.
+
+commit 1e58f55078ce6009a885be30ae0316aec6ed8239
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 14:16:31 2011 +0200
+
+    Make API future-proof (for an eventual affine or planar tracker).
+
+commit c2af303e7bf0dddcb02937323ac5846b1801e6cc
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 11:13:29 2011 +0200
+
+    Remove reconstruction breaking debug code.
+
+commit 8792a633e5c5f1c1f12e164b9e8897ca0790ac59
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 10:49:18 2011 +0200
+
+    Remove getchar()s.
+
+commit 63a9bdee0cbd1197e0315d01c27bfc2361bd5656
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 10:35:07 2011 +0200
+
+    Adapt patch to new PipelineRoutines code generation strategy.
+
+commit 096ff1a4070f7212c50fb0a4b2feec7ca9d97158
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 09:54:12 2011 +0200
+
+    Merge max_image and max_track fix from tomato.
+
+commit d8450cd3c37278a397482cd36b1e2419f154cfb9
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Tue Aug 9 09:38:49 2011 +0200
+
+    Synchronize tree with Tomato: Merge patch for better resection, keep deprecated KLT tracker.
+
+commit e9b2dca920cf9575c15150a4988634b00e343a41
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Mon Aug 8 17:07:08 2011 +0200
+
+    Fixes, Documentation.
+
+commit 4fc1c57a2d92442808ac4a3676e6d9a25a51e310
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sun Aug 7 14:35:08 2011 +0200
+
+    Improve tracker resilience by penalizing large motion vectors.
+
+commit cc8e7e8e08cd91f75c080a0091461ca9fe969664
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sun Aug 7 09:28:09 2011 +0200
+
+    Leverage SSE2 SAD instruction for 16x speed improvement in integer pixel search resulting in ~1ms per marker for 16x16 pattern on 128x128 region.
+
+commit f362ab4999a768370fca57552464b459eb9fbddc
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sun Aug 7 09:06:04 2011 +0200
+
+    Improve SAD Tracker subpixel precision (avoid drift even when adapting at each frame).
+
+commit fce7a214c561b5f5f0e17115c31fb48814bde2db
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Sat Aug 6 21:57:06 2011 +0200
+
+    Track using simple Sum of Absolute Differences matching.
+    This method is simpler, more robust, faster and accurate.
+
+commit 620a7a35d9a2818bf6e9dbf5d11debda4be6bc26
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Fri Jul 29 12:35:57 2011 +0200
+
+    Add Intersect unit test.
+
+commit a2bf58fa57be11215eb17ff7f7de58f97d480ec3
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Thu Jul 28 11:08:06 2011 +0200
+
+    Remove tests depending on dead code.
+    Fix CameraIntrinsics test.
+    Add Intersect and Resect tests.
+
+commit 19bddee10b4879c8cd2238ccdf5b8f7620cf8384
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Jul 27 12:07:21 2011 +0200
+
+    Image Distortion: Fixes and more testing.
+
+commit 0454d97da328fb0eda8c6c50511ac31864a6d3d6
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Jul 27 10:32:37 2011 +0200
+
+    Test float image distortion.
+
+commit 8db01595a8721f766d85931a8d92b780461d8741
+Author: Matthias Fauconneau <matthias.fauconneau@gmail.com>
+Date:   Wed Jul 27 10:27:07 2011 +0200
+
+    Image Distortion: Bilinear sampling, Optimization, Instantiate all variants (Distort/Undistort, float/ubyte, 1-4 channels).
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
new file mode 100644 (file)
index 0000000..1ffc623
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+import sys
+import os
+
+Import('env')
+
+defs = []
+
+cflags_libmv = Split(env['CFLAGS'])
+ccflags_libmv = Split(env['CCFLAGS'])
+cxxflags_libmv = Split(env['CXXFLAGS'])
+
+defs.append('V3DLIB_ENABLE_SUITESPARSE')
+defs.append('GOOGLE_GLOG_DLL_DECL=')
+
+src = env.Glob("*.cpp")
+src += env.Glob('libmv/image/*.cc')
+src += env.Glob('libmv/multiview/*.cc')
+src += env.Glob('libmv/numeric/*.cc')
+src += env.Glob('libmv/simple_pipeline/*.cc')
+src += env.Glob('libmv/tracking/*.cc')
+src += env.Glob('third_party/fast/*.c')
+src += env.Glob('third_party/gflags/*.cc')
+src += env.Glob('third_party/ldl/Source/*.c')
+src += env.Glob('third_party/ssba/Geometry/*.cpp')
+src += env.Glob('third_party/ssba/Math/*.cpp')
+
+incs = '. ../Eigen3'
+incs += ' ' + env['BF_PNG_INC']
+incs += ' ' + env['BF_ZLIB_INC']
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+    incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes'
+
+    src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+    src += ['./third_party/glog/src/windows/port.cc']
+
+    if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+        cflags_libmv.append('/Od')
+        ccflags_libmv.append('/Od')
+        cxxflags_libmv.append('/Od')
+
+        if not env['BF_DEBUG']:
+            defs.append('NDEBUG')
+    else:
+        if not env['BF_DEBUG']:
+            cflags_libmv = Split(env['REL_CFLAGS'])
+            ccflags_libmv = Split(env['REL_CCFLAGS'])
+            cxxflags_libmv = Split(env['REL_CXXFLAGS'])
+else:
+    src += env.Glob("third_party/glog/src/*.cc")
+    incs += ' ./third_party/glog/src'
+    if not env['BF_DEBUG']:
+        cflags_libmv = Split(env['REL_CFLAGS'])
+        ccflags_libmv = Split(env['REL_CCFLAGS'])
+        cxxflags_libmv = Split(env['REL_CXXFLAGS'])
+
+incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
+
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
new file mode 100755 (executable)
index 0000000..c8df8ae
--- /dev/null
@@ -0,0 +1,250 @@
+#!/bin/sh
+
+#BRANCH="keir"
+BRANCH="Matthias-Fauconneau"
+
+if [ -d ./.svn ]; then
+  echo "This script is supposed to work only when using git-svn"
+  exit 1
+fi
+
+repo="git://github.com/${BRANCH}/libmv.git"
+tmp=`mktemp -d`
+
+git clone $repo $tmp/libmv
+
+#git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log --since="1 month ago" > ChangeLog
+git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log -n 50 > ChangeLog
+
+for p in `cat ./patches/series`; do
+  echo "Applying patch $p..."
+  cat ./patches/$p | patch -d $tmp/libmv -p1
+done
+
+rm -rf libmv
+rm -rf third_party
+
+cat "files.txt" | while f=`line`; do
+  mkdir -p `dirname $f`
+  cp $tmp/libmv/src/$f $f
+done
+
+rm -rf $tmp
+
+chmod 664 ./third_party/glog/src/windows/*.cc ./third_party/glog/src/windows/*.h ./third_party/glog/src/windows/glog/*.h
+
+sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'`
+headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/'`
+
+third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/'`
+third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/'`
+
+third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'`
+third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'`
+
+src_dir=`find ./libmv -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort | uniq`
+src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/'  | sort | uniq`
+src=""
+win_src=""
+for x in $src_dir $src_third_dir; do
+  t=""
+
+  if test  `echo "$x" | grep -c glog ` -eq 1; then
+    continue;
+  fi
+
+  if stat $x/*.cpp > /dev/null 2>&1; then
+    t="src += env.Glob('`echo $x'/*.cpp'`')"
+  fi
+
+  if stat $x/*.c > /dev/null 2>&1; then
+    if [ -z "$t" ]; then
+      t="src += env.Glob('`echo $x'/*.c'`')"
+    else
+      t="$t + env.Glob('`echo $x'/*.c'`')"
+    fi
+  fi
+
+  if stat $x/*.cc > /dev/null 2>&1; then
+    if [ -z "$t" ]; then
+      t="src += env.Glob('`echo $x'/*.cc'`')"
+    else
+      t="$t + env.Glob('`echo $x'/*.cc'`')"
+    fi
+  fi
+
+  if test `echo $x | grep -c windows ` -eq 0; then
+    if [ -z "$src" ]; then
+      src=$t
+    else
+      src=`echo "$src\n$t"`
+    fi
+  else
+    if [ -z "$win_src" ]; then
+      win_src=`echo "    $t"`
+    else
+      win_src=`echo "$win_src\n    $t"`
+    fi
+  fi
+done
+
+cat > CMakeLists.txt << EOF
+# \$Id\$
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2011, Blender Foundation
+# All rights reserved.
+#
+# Contributor(s): Blender Foundation,
+#                 Sergey Sharybin
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+       .
+       ../Eigen3
+       ./third_party/ssba
+       ./third_party/ldl/Include
+       ../colamd/Include
+)
+
+set(INC_SYS
+       ${PNG_INCLUDE_DIR}
+       ${ZLIB_INCLUDE_DIRS}
+)
+
+set(SRC
+       libmv-capi.cpp
+${sources}
+
+${third_sources}
+
+       libmv-capi.h
+${headers}
+
+${third_headers}
+)
+
+IF(WIN32)
+       list(APPEND SRC
+               third_party/glog/src/logging.cc
+               third_party/glog/src/raw_logging.cc
+               third_party/glog/src/utilities.cc
+               third_party/glog/src/vlog_is_on.cc
+               third_party/glog/src/windows/port.cc
+
+               third_party/glog/src/utilities.h
+               third_party/glog/src/stacktrace_generic-inl.h
+               third_party/glog/src/stacktrace.h
+               third_party/glog/src/stacktrace_x86_64-inl.h
+               third_party/glog/src/base/googleinit.h
+               third_party/glog/src/base/mutex.h
+               third_party/glog/src/base/commandlineflags.h
+               third_party/glog/src/stacktrace_powerpc-inl.h
+               third_party/glog/src/stacktrace_x86-inl.h
+               third_party/glog/src/config.h
+               third_party/glog/src/stacktrace_libunwind-inl.h
+               third_party/glog/src/windows/glog/raw_logging.h
+               third_party/glog/src/windows/glog/vlog_is_on.h
+               third_party/glog/src/windows/glog/logging.h
+               third_party/glog/src/windows/glog/log_severity.h
+               third_party/glog/src/windows/port.h
+               third_party/glog/src/windows/config.h
+       )
+
+       list(APPEND INC
+               ./third_party/glog/src/windows
+               ./third_party/msinttypes
+       )
+
+       IF(MSVC)
+               set(MSVC_OFLAGS O1 O2 Ox)
+               foreach(FLAG ${MSVC_OFLAGS})
+                       string(REPLACE "${FLAG}" "Od" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+                       string(REPLACE "${FLAG}" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+               endforeach()
+       ENDIF(MSVC)
+ELSE(WIN32)
+       list(APPEND SRC
+${third_glog_sources}
+
+${third_glog_headers}
+       )
+
+       list(APPEND INC
+               ./third_party/glog/src
+       )
+ENDIF(WIN32)
+
+add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=)
+
+blender_add_lib(extern_libmv "\${SRC}" "\${INC}" "\${INC_SYS}")
+EOF
+
+cat > SConscript << EOF
+#!/usr/bin/python
+import sys
+import os
+
+Import('env')
+
+defs = []
+
+cflags_libmv = Split(env['CFLAGS'])
+ccflags_libmv = Split(env['CCFLAGS'])
+cxxflags_libmv = Split(env['CXXFLAGS'])
+
+defs.append('V3DLIB_ENABLE_SUITESPARSE')
+defs.append('GOOGLE_GLOG_DLL_DECL=')
+
+src = env.Glob("*.cpp")
+$src
+
+incs = '. ../Eigen3'
+incs += ' ' + env['BF_PNG_INC']
+incs += ' ' + env['BF_ZLIB_INC']
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
+    incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes'
+${win_src}
+    src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc']
+    src += ['./third_party/glog/src/windows/port.cc']
+
+    if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
+        cflags_libmv.append('/Od')
+        ccflags_libmv.append('/Od')
+        cxxflags_libmv.append('/Od')
+
+        if not env['BF_DEBUG']:
+            defs.append('NDEBUG')
+    else:
+        if not env['BF_DEBUG']:
+            cflags_libmv = Split(env['REL_CFLAGS'])
+            ccflags_libmv = Split(env['REL_CCFLAGS'])
+            cxxflags_libmv = Split(env['REL_CXXFLAGS'])
+else:
+    src += env.Glob("third_party/glog/src/*.cc")
+    incs += ' ./third_party/glog/src'
+    if not env['BF_DEBUG']:
+        cflags_libmv = Split(env['REL_CFLAGS'])
+        ccflags_libmv = Split(env['REL_CCFLAGS'])
+        cxxflags_libmv = Split(env['REL_CXXFLAGS'])
+
+incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include'
+
+env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv )
+EOF
diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt
new file mode 100644 (file)
index 0000000..fe6be5d
--- /dev/null
@@ -0,0 +1,141 @@
+libmv/logging/logging.h
+libmv/numeric/dogleg.h
+libmv/numeric/levenberg_marquardt.h
+libmv/numeric/poly.h
+libmv/numeric/numeric.cc
+libmv/numeric/function_derivative.h
+libmv/numeric/poly.cc
+libmv/numeric/tinyvector.cc
+libmv/numeric/numeric.h
+libmv/simple_pipeline/reconstruction.cc
+libmv/simple_pipeline/resect.h
+libmv/simple_pipeline/resect.cc
+libmv/simple_pipeline/reconstruction.h
+libmv/simple_pipeline/camera_intrinsics.h
+libmv/simple_pipeline/intersect.cc
+libmv/simple_pipeline/initialize_reconstruction.cc
+libmv/simple_pipeline/camera_intrinsics.cc
+libmv/simple_pipeline/pipeline.cc
+libmv/simple_pipeline/tracks.h
+libmv/simple_pipeline/detect.h
+libmv/simple_pipeline/detect.cc
+libmv/simple_pipeline/pipeline.h
+libmv/simple_pipeline/tracks.cc
+libmv/simple_pipeline/bundle.cc
+libmv/simple_pipeline/intersect.h
+libmv/simple_pipeline/bundle.h
+libmv/simple_pipeline/initialize_reconstruction.h
+libmv/image/convolve.h
+libmv/image/tuple.h
+libmv/image/array_nd.h
+libmv/image/convolve.cc
+libmv/image/array_nd.cc
+libmv/image/sample.h
+libmv/image/image.h
+libmv/tracking/pyramid_region_tracker.cc
+libmv/tracking/region_tracker.h
+libmv/tracking/sad.cc
+libmv/tracking/trklt_region_tracker.cc
+libmv/tracking/klt_region_tracker.cc
+libmv/tracking/retrack_region_tracker.h
+libmv/tracking/sad.h
+libmv/tracking/pyramid_region_tracker.h
+libmv/tracking/trklt_region_tracker.h
+libmv/tracking/retrack_region_tracker.cc
+libmv/tracking/klt_region_tracker.h
+libmv/base/id_generator.h
+libmv/base/vector.h
+libmv/base/scoped_ptr.h
+libmv/base/vector_utils.h
+libmv/multiview/projection.cc
+libmv/multiview/conditioning.cc
+libmv/multiview/nviewtriangulation.h
+libmv/multiview/resection.h
+libmv/multiview/fundamental.cc
+libmv/multiview/euclidean_resection.cc
+libmv/multiview/euclidean_resection.h
+libmv/multiview/triangulation.h
+libmv/multiview/projection.h
+libmv/multiview/triangulation.cc
+libmv/multiview/fundamental.h
+libmv/multiview/conditioning.h
+third_party/ssba/README.TXT
+third_party/ssba/COPYING.TXT
+third_party/ssba/Geometry/v3d_metricbundle.h
+third_party/ssba/Geometry/v3d_metricbundle.cpp
+third_party/ssba/Geometry/v3d_cameramatrix.h
+third_party/ssba/Geometry/v3d_distortion.h
+third_party/ssba/README.libmv
+third_party/ssba/Math/v3d_linear_utils.h
+third_party/ssba/Math/v3d_optimization.h
+third_party/ssba/Math/v3d_mathutilities.h
+third_party/ssba/Math/v3d_linear.h
+third_party/ssba/Math/v3d_optimization.cpp
+third_party/gflags/gflags_completions.h
+third_party/gflags/mutex.h
+third_party/gflags/gflags.cc
+third_party/gflags/gflags_reporting.cc
+third_party/gflags/README.libmv
+third_party/gflags/config.h
+third_party/gflags/gflags_completions.cc
+third_party/gflags/gflags.h
+third_party/fast/fast_9.c
+third_party/fast/fast_10.c
+third_party/fast/fast_11.c
+third_party/fast/fast.h
+third_party/fast/LICENSE
+third_party/fast/fast_12.c
+third_party/fast/fast.c
+third_party/fast/README
+third_party/fast/README.libmv
+third_party/fast/nonmax.c
+third_party/ldl/Include/ldl.h
+third_party/ldl/CMakeLists.txt
+third_party/ldl/README.libmv
+third_party/ldl/Doc/ChangeLog
+third_party/ldl/Doc/lesser.txt
+third_party/ldl/README.txt
+third_party/ldl/Source/ldl.c
+third_party/glog/ChangeLog
+third_party/glog/COPYING
+third_party/glog/src/utilities.cc
+third_party/glog/src/utilities.h
+third_party/glog/src/symbolize.cc
+third_party/glog/src/stacktrace_generic-inl.h
+third_party/glog/src/config_mac.h
+third_party/glog/src/vlog_is_on.cc
+third_party/glog/src/signalhandler.cc
+third_party/glog/src/stacktrace.h
+third_party/glog/src/stacktrace_x86_64-inl.h
+third_party/glog/src/symbolize.h
+third_party/glog/src/base/googleinit.h
+third_party/glog/src/base/mutex.h
+third_party/glog/src/base/commandlineflags.h
+third_party/glog/src/windows/preprocess.sh
+third_party/glog/src/windows/port.h
+third_party/glog/src/windows/config.h
+third_party/glog/src/windows/glog/raw_logging.h
+third_party/glog/src/windows/glog/vlog_is_on.h
+third_party/glog/src/windows/glog/logging.h
+third_party/glog/src/windows/glog/log_severity.h
+third_party/glog/src/windows/port.cc
+third_party/glog/src/logging.cc
+third_party/glog/src/stacktrace_powerpc-inl.h
+third_party/glog/src/stacktrace_x86-inl.h
+third_party/glog/src/demangle.cc
+third_party/glog/src/config.h
+third_party/glog/src/demangle.h
+third_party/glog/src/stacktrace_libunwind-inl.h
+third_party/glog/src/glog/raw_logging.h
+third_party/glog/src/glog/vlog_is_on.h
+third_party/glog/src/glog/logging.h
+third_party/glog/src/glog/log_severity.h
+third_party/glog/src/raw_logging.cc
+third_party/glog/src/config_linux.h
+third_party/glog/NEWS
+third_party/glog/README
+third_party/glog/README.libmv
+third_party/glog/AUTHORS
+third_party/msinttypes/stdint.h
+third_party/msinttypes/inttypes.h
+third_party/msinttypes/README.libmv
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
new file mode 100644 (file)
index 0000000..2e007bb
--- /dev/null
@@ -0,0 +1,770 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/* define this to generate PNG images with content of search areas
+   tracking between which failed */
+#undef DUMP_FAILURE
+
+#include "libmv-capi.h"
+
+#include "glog/logging.h"
+#include "Math/v3d_optimization.h"
+
+#include "libmv/tracking/klt_region_tracker.h"
+#include "libmv/tracking/trklt_region_tracker.h"
+#include "libmv/tracking/pyramid_region_tracker.h"
+
+#include "libmv/tracking/sad.h"
+
+#include "libmv/simple_pipeline/tracks.h"
+#include "libmv/simple_pipeline/initialize_reconstruction.h"
+#include "libmv/simple_pipeline/bundle.h"
+#include "libmv/simple_pipeline/detect.h"
+#include "libmv/simple_pipeline/pipeline.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+#include <stdlib.h>
+
+#ifdef DUMP_FAILURE
+#  include <png.h>
+#endif
+
+#ifdef _MSC_VER
+#  define snprintf _snprintf
+#endif
+
+#define DEFAULT_WINDOW_HALFSIZE        5
+
+typedef struct libmv_RegionTracker {
+       libmv::TrkltRegionTracker *trklt_region_tracker;
+       libmv::RegionTracker *region_tracker;
+} libmv_RegionTracker;
+
+typedef struct libmv_Reconstruction {
+       libmv::EuclideanReconstruction reconstruction;
+
+       /* used for per-track average error calculation after reconstruction */
+       libmv::Tracks tracks;
+       libmv::CameraIntrinsics intrinsics;
+
+       double error;
+} libmv_Reconstruction;
+
+typedef struct libmv_Features {
+       int count, margin;
+       libmv::Feature *features;
+} libmv_Features;
+
+/* ************ Logging ************ */
+
+void libmv_initLogging(const char *argv0)
+{
+       google::InitGoogleLogging(argv0);
+       google::SetCommandLineOption("logtostderr", "1");
+       google::SetCommandLineOption("v", "0");
+       google::SetCommandLineOption("stderrthreshold", "7");
+       google::SetCommandLineOption("minloglevel", "7");
+       V3D::optimizerVerbosenessLevel = 0;
+}
+
+void libmv_startDebugLogging(void)
+{
+       google::SetCommandLineOption("logtostderr", "1");
+       google::SetCommandLineOption("v", "0");
+       google::SetCommandLineOption("stderrthreshold", "1");
+       google::SetCommandLineOption("minloglevel", "0");
+       V3D::optimizerVerbosenessLevel = 1;
+}
+
+void libmv_setLoggingVerbosity(int verbosity)
+{
+       char val[10];
+       snprintf(val, sizeof(val), "%d", verbosity);
+
+       google::SetCommandLineOption("v", val);
+       V3D::optimizerVerbosenessLevel = verbosity;
+}
+
+/* ************ RegionTracker ************ */
+
+libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level)
+{
+       libmv::TrkltRegionTracker *trklt_region_tracker = new libmv::TrkltRegionTracker;
+
+       trklt_region_tracker->half_window_size = DEFAULT_WINDOW_HALFSIZE;
+       trklt_region_tracker->max_iterations = max_iterations;
+       trklt_region_tracker->min_determinant = 1e-4;
+
+       libmv::PyramidRegionTracker *region_tracker =
+               new libmv::PyramidRegionTracker(trklt_region_tracker, pyramid_level);
+
+       libmv_RegionTracker *configured_region_tracker = new libmv_RegionTracker;
+       configured_region_tracker->trklt_region_tracker = trklt_region_tracker;
+       configured_region_tracker->region_tracker = region_tracker;
+
+       return configured_region_tracker;
+}
+
+static void floatBufToImage(const float *buf, int width, int height, libmv::FloatImage *image)
+{
+       int x, y, a = 0;
+
+       image->resize(height, width);
+
+       for (y = 0; y < height; y++) {
+               for (x = 0; x < width; x++) {
+                       (*image)(y, x, 0) = buf[a++];
+               }
+       }
+}
+
+#ifdef DUMP_FAILURE
+void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name)
+{
+       png_infop info_ptr;
+       png_structp png_ptr;
+       FILE *fp = fopen(file_name, "wb");
+
+       if (!fp)
+               return;
+
+       /* Initialize stuff */
+       png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       info_ptr = png_create_info_struct(png_ptr);
+
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               fclose(fp);
+               return;
+       }
+
+       png_init_io(png_ptr, fp);
+
+       /* write header */
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               fclose(fp);
+               return;
+       }
+
+       png_set_IHDR(png_ptr, info_ptr, width, height,
+               depth, color_type, PNG_INTERLACE_NONE,
+               PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+       png_write_info(png_ptr, info_ptr);
+
+       /* write bytes */
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               fclose(fp);
+               return;
+       }
+
+       png_write_image(png_ptr, row_pointers);
+
+       /* end write */
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               fclose(fp);
+               return;
+       }
+
+       png_write_end(png_ptr, NULL);
+
+       fclose(fp);
+}
+
+static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0)
+{
+       int x, y;
+       png_bytep *row_pointers;
+
+       row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*image.Height());
+
+       for (y = 0; y < image.Height(); y++) {
+               row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width());
+
+               for (x = 0; x < image.Width(); x++) {
+                       if (x0 == x && y0 == y) {
+                               row_pointers[y][x*4+0]= 255;
+                               row_pointers[y][x*4+1]= 0;
+                               row_pointers[y][x*4+2]= 0;
+                               row_pointers[y][x*4+3]= 255;
+                       }
+                       else {
+                               float pixel = image(y, x, 0);
+                               row_pointers[y][x*4+0]= pixel*255;
+                               row_pointers[y][x*4+1]= pixel*255;
+                               row_pointers[y][x*4+2]= pixel*255;
+                               row_pointers[y][x*4+3]= 255;
+                       }
+               }
+       }
+
+       {
+               static int a= 0;
+               char buf[128];
+               snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
+               savePNGImage(row_pointers, image.Width(), image.Height(), 8, PNG_COLOR_TYPE_RGBA, buf);
+       }
+
+       for (y = 0; y < image.Height(); y++) {
+               free(row_pointers[y]);
+       }
+       free(row_pointers);
+}
+
+static void saveBytesImage(char *prefix, unsigned char *data, int width, int height)
+{
+       int x, y;
+       png_bytep *row_pointers;
+
+       row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*height);
+
+       for (y = 0; y < height; y++) {
+               row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*width);
+
+               for (x = 0; x < width; x++) {
+                       char pixel = data[width*y+x];
+                       row_pointers[y][x*4+0]= pixel;
+                       row_pointers[y][x*4+1]= pixel;
+                       row_pointers[y][x*4+2]= pixel;
+                       row_pointers[y][x*4+3]= 255;
+               }
+       }
+
+       {
+               static int a= 0;
+               char buf[128];
+               snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
+               savePNGImage(row_pointers, width, height, 8, PNG_COLOR_TYPE_RGBA, buf);
+       }
+
+       for (y = 0; y < height; y++) {
+               free(row_pointers[y]);
+       }
+       free(row_pointers);
+}
+#endif
+
+int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2,
+                        int width, int height, int half_window_size,
+                        double x1, double y1, double *x2, double *y2)
+{
+       libmv::RegionTracker *region_tracker;
+       libmv::TrkltRegionTracker *trklt_region_tracker;
+       libmv::FloatImage old_patch, new_patch;
+
+       trklt_region_tracker = libmv_tracker->trklt_region_tracker;
+       region_tracker = libmv_tracker->region_tracker;
+
+       trklt_region_tracker->half_window_size = half_window_size;
+
+       floatBufToImage(ima1, width, height, &old_patch);
+       floatBufToImage(ima2, width, height, &new_patch);
+
+#ifndef DUMP_FAILURE
+       return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
+#else
+       {
+               double sx2 = *x2, sy2 = *y2;
+               int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2);
+
+               if (!result) {
+                       saveImage("old_patch", old_patch, x1, y1);
+                       saveImage("new_patch", new_patch, sx2, sy2);
+               }
+
+               return result;
+       }
+#endif
+}
+
+void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker)
+{
+       delete libmv_tracker->region_tracker;
+       delete libmv_tracker;
+}
+
+/* ************ Tracks ************ */
+
+void libmv_SADSamplePattern(unsigned char *image, int stride,
+                       float warp[3][2], unsigned char *pattern)
+{
+       libmv::mat32 mat32;
+
+       memcpy(mat32.data, warp, sizeof(float)*3*2);
+
+       libmv::SamplePattern(image, stride, mat32, pattern, 16);
+}
+
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image, int stride,
+                       int width, int height, float warp[3][2])
+{
+       float result;
+       libmv::mat32 mat32;
+
+       memcpy(mat32.data, warp, sizeof(float)*3*2);
+
+       result = libmv::Track(pattern, warped, 16, image, stride, width, height, &mat32, 16, 16);
+
+       memcpy(warp, mat32.data, sizeof(float)*3*2);
+
+       return result;
+}
+
+/* ************ Tracks ************ */
+
+libmv_Tracks *libmv_tracksNew(void)
+{
+       libmv::Tracks *libmv_tracks = new libmv::Tracks();
+
+       return (libmv_Tracks *)libmv_tracks;
+}
+
+void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y)
+{
+       ((libmv::Tracks*)libmv_tracks)->Insert(image, track, x, y);
+}
+
+void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
+{
+       delete (libmv::Tracks*)libmv_tracks;
+}
+
+/* ************ Reconstruction solver ************ */
+
+libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyframe1, int keyframe2,
+                       double focal_length, double principal_x, double principal_y, double k1, double k2, double k3)
+{
+       /* Invert the camera intrinsics. */
+       libmv::vector<libmv::Marker> markers = ((libmv::Tracks*)tracks)->AllMarkers();
+       libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction();
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+       libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+
+       intrinsics->SetFocalLength(focal_length, focal_length);
+       intrinsics->SetPrincipalPoint(principal_x, principal_y);
+       intrinsics->SetRadialDistortion(k1, k2, k3);
+
+       if(focal_length) {
+               /* do a lens undistortion if focal length is non-zero only */
+               for (int i = 0; i < markers.size(); ++i) {
+                       intrinsics->InvertIntrinsics(markers[i].x,
+                               markers[i].y,
+                               &(markers[i].x),
+                               &(markers[i].y));
+               }
+       }
+
+       libmv::Tracks normalized_tracks(markers);
+
+       libmv::vector<libmv::Marker> keyframe_markers =
+               normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
+
+       libmv::EuclideanReconstructTwoFrames(keyframe_markers, reconstruction);
+       libmv::EuclideanBundle(normalized_tracks, reconstruction);
+       libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction);
+
+       libmv_reconstruction->tracks = *(libmv::Tracks *)tracks;
+       libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics);
+
+       return (libmv_Reconstruction *)libmv_reconstruction;
+}
+
+int libmv_reporojectionPointForTrack(libmv_Reconstruction *libmv_reconstruction, int track, double pos[3])
+{
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+       libmv::EuclideanPoint *point = reconstruction->PointForTrack(track);
+
+       if(point) {
+               pos[0] = point->X[0];
+               pos[1] = point->X[2];
+               pos[2] = point->X[1];
+
+               return 1;
+       }
+
+       return 0;
+}
+
+static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point, const libmv::EuclideanCamera &camera,
+                       const libmv::CameraIntrinsics &intrinsics) {
+       libmv::Vec3 projected = camera.R * point.X + camera.t;
+       projected /= projected(2);
+
+       libmv::Marker reprojected_marker;
+       intrinsics.ApplyIntrinsics(projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y);
+
+       reprojected_marker.image = camera.image;
+       reprojected_marker.track = point.track;
+
+       return reprojected_marker;
+}
+
+double libmv_reporojectionErrorForTrack(libmv_Reconstruction *libmv_reconstruction, int track)
+{
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+       libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+       libmv::vector<libmv::Marker> markers =  libmv_reconstruction->tracks.MarkersForTrack(track);
+
+       int num_reprojected = 0;
+       double total_error = 0.0;
+
+       for (int i = 0; i < markers.size(); ++i) {
+               const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image);
+               const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+
+               if (!camera || !point) {
+                       continue;
+               }
+
+               num_reprojected++;
+
+               libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+               double ex = reprojected_marker.x - markers[i].x;
+               double ey = reprojected_marker.y - markers[i].y;
+
+               total_error += sqrt(ex*ex + ey*ey);
+       }
+
+       return total_error / num_reprojected;
+}
+
+double libmv_reporojectionErrorForImage(libmv_Reconstruction *libmv_reconstruction, int image)
+{
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+       libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics;
+       libmv::vector<libmv::Marker> markers = libmv_reconstruction->tracks.MarkersInImage(image);
+       const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+       int num_reprojected = 0;
+       double total_error = 0.0;
+
+       if (!camera)
+               return 0;
+
+       for (int i = 0; i < markers.size(); ++i) {
+               const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track);
+
+               if (!point) {
+                       continue;
+               }
+
+               num_reprojected++;
+
+               libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics);
+               double ex = reprojected_marker.x - markers[i].x;
+               double ey = reprojected_marker.y - markers[i].y;
+
+               total_error += sqrt(ex*ex + ey*ey);
+       }
+
+       return total_error / num_reprojected;
+}
+
+int libmv_reporojectionCameraForImage(libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4])
+{
+       libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction;
+       libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image);
+
+       if(camera) {
+               for (int j = 0; j < 3; ++j) {
+                       for (int k = 0; k < 3; ++k) {
+                               int l = k;
+
+                               if (k == 1) l = 2;
+                               else if (k == 2) l = 1;
+
+                               if (j == 2) mat[j][l] = -camera->R(j,k);
+                               else mat[j][l] = camera->R(j,k);
+                       }
+                       mat[j][3]= 0.0;
+               }
+
+               libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
+
+               mat[3][0] = optical_center(0);
+               mat[3][1] = optical_center(2);
+               mat[3][2] = optical_center(1);
+
+               mat[3][3]= 1.0;
+
+               return 1;
+       }
+
+       return 0;
+}
+
+double libmv_reprojectionError(libmv_Reconstruction *libmv_reconstruction)
+{
+       return libmv_reconstruction->error;
+}
+
+void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction)
+{
+       delete libmv_reconstruction;
+}
+
+/* ************ feature detector ************ */
+
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+                       int margin, int min_trackness, int min_distance)
+{
+       libmv::Feature *features = NULL;
+       std::vector<libmv::Feature> v;
+       libmv_Features *libmv_features = new libmv_Features();
+       int i= 0, count;
+
+       if(margin) {
+               data += margin*stride+margin;
+               width -= 2*margin;
+               height -= 2*margin;
+       }
+
+       v = libmv::DetectFAST(data, width, height, stride, min_trackness, min_distance);
+
+       count = v.size();
+
+       if(count) {
+               features= new libmv::Feature[count];
+
+               for(std::vector<libmv::Feature>::iterator it = v.begin(); it != v.end(); it++) {
+                       features[i++]= *it;
+               }
+       }
+
+       libmv_features->features = features;
+       libmv_features->count = count;
+       libmv_features->margin = margin;
+
+       return (libmv_Features *)libmv_features;
+}
+
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+                       int margin, int count, int min_distance)
+{
+       libmv::Feature *features = NULL;
+       libmv_Features *libmv_features = new libmv_Features;
+
+       if(count) {
+               if(margin) {
+                       data += margin*stride+margin;
+                       width -= 2*margin;
+                       height -= 2*margin;
+               }
+
+               features = new libmv::Feature[count];
+               libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL);
+       }
+
+       libmv_features->count = count;
+       libmv_features->margin = margin;
+       libmv_features->features = features;
+
+       return libmv_features;
+}
+
+int libmv_countFeatures(struct libmv_Features *libmv_features)
+{
+       return libmv_features->count;
+}
+
+void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size)
+{
+       libmv::Feature feature= libmv_features->features[number];
+
+       *x = feature.x + libmv_features->margin;
+       *y = feature.y + libmv_features->margin;
+       *score = feature.score;
+       *size = feature.size;
+}
+
+void libmv_destroyFeatures(struct libmv_Features *libmv_features)
+{
+       if(libmv_features->features)
+               delete [] libmv_features->features;
+
+       delete libmv_features;
+}
+
+/* ************ camera intrinsics ************ */
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
+                       double k1, double k2, double k3, int width, int height)
+{
+       libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics();
+
+       intrinsics->SetFocalLength(focal_length, focal_length);
+       intrinsics->SetPrincipalPoint(principal_x, principal_y);
+       intrinsics->SetRadialDistortion(k1, k2, k3);
+       intrinsics->SetImageSize(width, height);
+
+       return (struct libmv_CameraIntrinsics *) intrinsics;
+}
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+{
+       libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+       libmv::CameraIntrinsics *new_intrinsics= new libmv::CameraIntrinsics(*orig_intrinsics);
+
+       return (struct libmv_CameraIntrinsics *) new_intrinsics;
+}
+
+void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+       delete intrinsics;
+}
+
+void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
+                       double principal_x, double principal_y, double k1, double k2, double k3, int width, int height)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+       if (intrinsics->focal_length() != focal_length)
+               intrinsics->SetFocalLength(focal_length, focal_length);
+
+       if (intrinsics->principal_point_x() != principal_x || intrinsics->principal_point_y() != principal_y)
+               intrinsics->SetFocalLength(focal_length, focal_length);
+
+       if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3)
+               intrinsics->SetRadialDistortion(k1, k2, k3);
+
+       if (intrinsics->image_width() != width || intrinsics->image_height() != height)
+               intrinsics->SetImageSize(width, height);
+}
+
+void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+       intrinsics->Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       float *src, float *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+       intrinsics->Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+       intrinsics->Distort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       float *src, float *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics;
+
+       intrinsics->Distort(src, dst, width, height, overscan, channels);
+}
+
+/* ************ distortion ************ */
+
+void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       intrinsics.Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       float *src, float *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       intrinsics.Undistort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       intrinsics.Distort(src, dst, width, height, overscan, channels);
+}
+
+void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       float *src, float *dst, int width, int height, float overscan, int channels)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       intrinsics.Distort(src, dst, width, height, overscan, channels);
+}
+
+/* ************ utils ************ */
+
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       if(focal_length) {
+               /* do a lens undistortion if focal length is non-zero only */
+
+               intrinsics.ApplyIntrinsics(x, y, x1, y1);
+       }
+}
+
+void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1)
+{
+       libmv::CameraIntrinsics intrinsics;
+
+       intrinsics.SetFocalLength(focal_length, focal_length);
+       intrinsics.SetPrincipalPoint(principal_x, principal_y);
+       intrinsics.SetRadialDistortion(k1, k2, k3);
+
+       if(focal_length) {
+               /* do a lens distortion if focal length is non-zero only */
+
+               intrinsics.InvertIntrinsics(x, y, x1, y1);
+       }
+}
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
new file mode 100644 (file)
index 0000000..b71a66b
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ *                 Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_H
+#define LIBMV_C_API_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct libmv_RegionTracker;
+struct libmv_Tracks;
+struct libmv_Reconstruction;
+struct libmv_Features;
+struct libmv_CameraIntrinsics;
+
+/* Logging */
+void libmv_initLogging(const char *argv0);
+void libmv_startDebugLogging(void);
+void libmv_setLoggingVerbosity(int verbosity);
+
+/* RegionTracker */
+struct libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level);
+int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2,
+                       int width, int height, int half_window_size,
+                       double  x1, double  y1, double *x2, double *y2);
+void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker);
+
+/* SAD Tracker */
+void libmv_SADSamplePattern(unsigned char *image, int stride,
+                       float warp[3][2], unsigned char *pattern);
+float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image,
+                       int stride, int width, int height, float warp[3][2]);
+
+/* Tracks */
+struct libmv_Tracks *libmv_tracksNew(void);
+void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y);
+void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
+
+/* Reconstruction solver */
+struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2,
+                       double focal_length, double principal_x, double principal_y, double k1, double k2, double k3);
+int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *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);
+int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4]);
+double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction);
+void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction);
+
+/* feature detector */
+struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride,
+                       int margin, int min_trackness, int min_distance);
+struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride,
+                       int margin, int count, int min_distance);
+int libmv_countFeatures(struct libmv_Features *libmv_features);
+void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size);
+void libmv_destroyFeatures(struct libmv_Features *libmv_features);
+
+/* camera intrinsics */
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y,
+                       double k1, double k2, double k3, int width, int height);
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics);
+
+void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length,
+                       double principal_x, double principal_y, double k1, double k2, double k3, int width, int height);
+
+void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       float *src, float *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels);
+
+void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics,
+                       float *src, float *dst, int width, int height, float overscan, int channels);
+
+/* dsitortion */
+void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       unsigned char *src, unsigned char *dst, int width, int height, int channels);
+void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       float *src, float *dst, int width, int height, int channels);
+
+void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       unsigned char *src, unsigned char *dst, int width, int height, int channels);
+void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       float *src, float *dst, int width, int height, int channels);
+
+/* utils */
+void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1);
+void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3,
+                       double x, double y, double *x1, double *y1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_H
diff --git a/extern/libmv/libmv/base/id_generator.h b/extern/libmv/libmv/base/id_generator.h
new file mode 100644 (file)
index 0000000..bf1eafd
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright (c) 2007, 2008 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_ID_GENERATOR_H
+#define LIBMV_ID_GENERATOR_H
+
+namespace libmv {
+
+template <typename ID>
+class IdGenerator {
+ public:
+  IdGenerator() : next_(0) {}
+  ID Generate() { return next_++; }
+ private:
+  ID next_;
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_ID_GENERATOR_H
diff --git a/extern/libmv/libmv/base/scoped_ptr.h b/extern/libmv/libmv/base/scoped_ptr.h
new file mode 100644 (file)
index 0000000..f1e89eb
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (c) 2009 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_BASE_SCOPED_PTR_H
+#define LIBMV_BASE_SCOPED_PTR_H
+
+namespace libmv {
+
+/**
+ * A handle for a heap-allocated resource that should be freed when it goes out
+ * of scope. This looks similar to the one found in TR1.
+ */
+template<typename T>
+class scoped_ptr {
+ public:
+  scoped_ptr(T *resource) : resource_(resource) {}
+  ~scoped_ptr() { reset(0); }
+
+  T *get()             const { return resource_;  }
+  T *operator->()      const { return resource_;  }
+  T &operator*()       const { return *resource_; }
+
+  void reset(T *new_resource) {
+    if (sizeof(T)) {
+      delete resource_;
+    }
+    resource_ = new_resource;
+  }
+
+  T *release() {
+    T *released_resource = resource_;
+    resource_ = 0;
+    return released_resource;
+  }
+
+ private:
+  // No copying allowed.
+  T *resource_;
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_BASE_SCOPED_PTR_H
diff --git a/extern/libmv/libmv/base/vector.h b/extern/libmv/libmv/base/vector.h
new file mode 100644 (file)
index 0000000..9dc4867
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (c) 2007, 2008 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.
+//
+// Get an aligned vector implementation. Must be included before <vector>. The
+// Eigen guys went through some trouble to make a portable override for the
+// fixed size vector types.
+
+#ifndef LIBMV_BASE_VECTOR_H
+#define LIBMV_BASE_VECTOR_H
+
+#include <cstring>
+#include <new>
+
+#include <Eigen/Core>
+
+namespace libmv {
+
+// A simple container class, which guarantees 16 byte alignment needed for most
+// vectorization. Don't use this container for classes that cannot be copied
+// via memcpy.
+// FIXME: this class has some issues:
+// - doesn't support iterators.
+// - impede compatibility with code using STL.
+// - the STL already provide support for custom allocators
+// it could be replaced with a simple 
+// template <T> class vector : std::vector<T, aligned_allocator> {} declaration
+// provided it doesn't break code relying on libmv::vector specific behavior
+template <typename T,
+          typename Allocator = Eigen::aligned_allocator<T> >
+class vector {
+ public:
+  ~vector()                        { clear();                 }
+
+  vector()                         { init();                  }
+  vector(int size)                 { init(); resize(size);    }
+  vector(int size, const T & val)  {
+    init();
+    resize(size);
+    std::fill(data_, data_+size_, val); }
+
+  // Copy constructor and assignment.
+  vector(const vector<T, Allocator> &rhs) {
+    init();
+    copy(rhs);
+  }
+  vector<T, Allocator> &operator=(const vector<T, Allocator> &rhs) {
+    if (&rhs != this) {
+      copy(rhs);
+    }
+    return *this;
+  }
+
+  /// Swaps the contents of two vectors in constant time.
+  void swap(vector<T, Allocator> &other) {
+    std::swap(allocator_, other.allocator_);
+    std::swap(size_, other.size_);
+    std::swap(capacity_, other.capacity_);
+    std::swap(data_, other.data_);
+  }
+
+        T *data()            const { return data_;            }
+  int      size()            const { return size_;            }
+  int      capacity()        const { return capacity_;        }
+  const T& back()            const { return data_[size_ - 1]; }
+        T& back()                  { return data_[size_ - 1]; }
+  const T& front()           const { return data_[0];         }
+        T& front()                 { return data_[0];         }
+  const T& operator[](int n) const { return data_[n];         }
+        T& operator[](int n)       { return data_[n];         }
+  const T * begin()          const { return data_;            }
+  const T * end()            const { return data_+size_;      }
+        T * begin()                { return data_;            }
+        T * end()                  { return data_+size_;      }
+
+  void resize(size_t size) {
+    reserve(size);
+    if (size > size_) {
+      construct(size_, size);
+    } else if (size < size_) {
+      destruct(size, size_);
+    }
+    size_ = size;
+  }
+
+
+
+  void push_back(const T &value) {
+    if (size_ == capacity_) {
+      reserve(size_ ? 2 * size_ : 1);
+    }
+    new (&data_[size_++]) T(value);
+  }
+
+  void pop_back() {
+    resize(size_ - 1);
+  }
+
+  void clear() {
+    destruct(0, size_);
+    deallocate();
+    init();
+  }
+
+  void reserve(unsigned int size) {
+    if (size > size_) {
+      T *data = static_cast<T *>(allocate(size));
+      memcpy(data, data_, sizeof(*data)*size_);
+      allocator_.deallocate(data_, capacity_);
+      data_ = data;
+      capacity_ = size;
+    }
+  }
+
+ private:
+  void construct(int start, int end) {
+    for (int i = start; i < end; ++i) {
+      new (&data_[i]) T;
+    }
+  }
+  void destruct(int start, int end) {
+    for (int i = start; i < end; ++i) {
+      data_[i].~T();
+    }
+  }
+  void init() {
+    size_ = 0;
+    data_ = 0;
+    capacity_ = 0;
+  }
+
+  void *allocate(int size) {
+    return size ? allocator_.allocate(size) : 0;
+  }
+
+  void deallocate() {
+    allocator_.deallocate(data_, size_);
+    data_ = 0;
+  }
+
+  void copy(const vector<T, Allocator> &rhs) {
+    resize(rhs.size());
+    for (int i = 0; i < rhs.size(); ++i) {
+      (*this)[i] = rhs[i];
+    }
+  }
+
+  Allocator allocator_;
+  size_t size_;
+  size_t capacity_;
+  T *data_;
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_BASE_VECTOR_H
diff --git a/extern/libmv/libmv/base/vector_utils.h b/extern/libmv/libmv/base/vector_utils.h
new file mode 100644 (file)
index 0000000..7a0c3ba
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (c) 2009 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_BASE_VECTOR_UTILS_H_
+#define LIBMV_BASE_VECTOR_UTILS_H_
+
+/// Delete the contents of a container.
+template <class Array>
+void DeleteElements(Array *array)  {
+  for (int i = 0; i < array->size(); ++i)  {
+    delete (*array)[i];
+  }
+  array->clear();
+}
+
+#endif // LIBMV_BASE_VECTOR_UTILS_H_
diff --git a/extern/libmv/libmv/image/array_nd.cc b/extern/libmv/libmv/image/array_nd.cc
new file mode 100644 (file)
index 0000000..3a77e3e
--- /dev/null
@@ -0,0 +1,108 @@
+// Copyright (c) 2007, 2008 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/image/image.h"
+#include <iostream>
+#include <cmath>
+
+namespace libmv {
+
+void FloatArrayToScaledByteArray(const Array3Df &float_array,
+                                 Array3Du *byte_array,
+                                 bool automatic_range_detection
+                                ) {
+  byte_array->ResizeLike(float_array);
+  float minval =  HUGE_VAL;
+  float maxval = -HUGE_VAL;
+  if (automatic_range_detection) {
+    for (int i = 0; i < float_array.Height(); ++i) {
+      for (int j = 0; j < float_array.Width(); ++j) {
+        for (int k = 0; k < float_array.Depth(); ++k) {
+          minval = std::min(minval, float_array(i,j,k));
+          maxval = std::max(maxval, float_array(i,j,k));
+        }
+      }
+    }
+  } else {
+    minval = 0;
+    maxval = 1;
+  }
+  for (int i = 0; i < float_array.Height(); ++i) {
+    for (int j = 0; j < float_array.Width(); ++j) {
+      for (int k = 0; k < float_array.Depth(); ++k) {
+        float unscaled = (float_array(i,j,k) - minval) / (maxval - minval);
+        (*byte_array)(i,j,k) = (unsigned char)(255 * unscaled);
+      }
+    }
+  }
+}
+
+void ByteArrayToScaledFloatArray(const Array3Du &byte_array,
+                                 Array3Df *float_array) {
+  float_array->ResizeLike(byte_array);
+  for (int i = 0; i < byte_array.Height(); ++i) {
+    for (int j = 0; j < byte_array.Width(); ++j) {
+      for (int k = 0; k < byte_array.Depth(); ++k) {
+             (*float_array)(i,j,k) = float(byte_array(i,j,k)) / 255.0f;
+      }
+    }
+  }
+}
+
+void SplitChannels(const Array3Df &input,
+                          Array3Df *channel0,
+                          Array3Df *channel1,
+                          Array3Df *channel2) {
+  assert(input.Depth() >= 3);
+  channel0->Resize(input.Height(), input.Width());
+  channel1->Resize(input.Height(), input.Width());
+  channel2->Resize(input.Height(), input.Width());
+  for (int row = 0; row < input.Height(); ++row) {
+    for (int column = 0; column < input.Width(); ++column) {
+      (*channel0)(row, column) = input(row, column, 0);
+      (*channel1)(row, column) = input(row, column, 1);
+      (*channel2)(row, column) = input(row, column, 2);
+    }
+  }
+}
+
+void PrintArray(const Array3Df &array) {
+  using namespace std;
+
+  printf("[\n");
+  for (int r = 0; r < array.Height(); ++r) {
+    printf("[");
+    for (int c = 0; c < array.Width(); ++c) {
+      if (array.Depth() == 1) {
+        printf("%11f, ", array(r, c));
+      } else {
+        printf("[");
+        for (int k = 0; k < array.Depth(); ++k) {
+          printf("%11f, ", array(r, c, k));
+        }
+        printf("],");
+      }
+    }
+    printf("],\n");
+  }
+  printf("]\n");
+}
+
+}  // namespace libmv
diff --git a/extern/libmv/libmv/image/array_nd.h b/extern/libmv/libmv/image/array_nd.h
new file mode 100644 (file)
index 0000000..6d7570c
--- /dev/null
@@ -0,0 +1,473 @@
+// Copyright (c) 2007, 2008 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_IMAGE_ARRAY_ND_H
+#define LIBMV_IMAGE_ARRAY_ND_H
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+#include "libmv/image/tuple.h"
+
+namespace libmv {
+
+class BaseArray {};
+
+/// A multidimensional array class.
+template <typename T, int N>
+class ArrayND : public BaseArray {
+ public:
+  typedef T Scalar;
+
+  /// Type for the multidimensional indices.
+  typedef Tuple<int, N> Index;
+
+  /// Create an empty array.
+  ArrayND() : data_(NULL), own_data(true) { Resize(Index(0)); }
+
+  /// Create an array with the specified shape.
+  ArrayND(const Index &shape) : data_(NULL), own_data(true) { Resize(shape); }
+
+  /// Create an array with the specified shape.
+  ArrayND(int *shape) : data_(NULL), own_data(true) { Resize(shape); }
+
+  /// Copy constructor.
+  ArrayND(const ArrayND<T, N> &b) : data_(NULL), own_data(true) {
+    ResizeLike(b);
+    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
+  }
+
+  ArrayND(int s0) : data_(NULL), own_data(true) { Resize(s0); }
+  ArrayND(int s0, int s1) : data_(NULL), own_data(true) { Resize(s0, s1); }
+  ArrayND(int s0, int s1, int s2) : data_(NULL), own_data(true) { Resize(s0, s1, s2); }
+
+  ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data(false) { Resize(s0, s1, s2); }
+
+  /// Destructor deletes pixel data.
+  ~ArrayND() {
+    delete [] data_;
+  }
+
+  /// Assignation copies pixel data.
+  ArrayND &operator=(const ArrayND<T, N> &b) {
+    assert(this != &b);
+    ResizeLike(b);
+    std::memcpy(Data(), b.Data(), sizeof(T) * Size());
+    return *this;
+  }
+
+  const Index &Shapes() const {
+    return shape_;
+  }
+
+  const Index &Strides() const {
+    return strides_;
+  }
+
+  /// Create an array of shape s.
+  void Resize(const Index &new_shape) {
+    if (data_ != NULL && shape_ == new_shape) {
+      // Don't bother realloacting if the shapes match.
+      return;
+    }
+    shape_.Reset(new_shape);
+    strides_(N - 1) = 1;
+    for (int i = N - 1; i > 0; --i) {
+      strides_(i - 1) = strides_(i) * shape_(i);
+    }
+    if(own_data) {
+      delete [] data_;
+      data_ = NULL;
+      if (Size() > 0) {
+        data_ = new T[Size()];
+      }
+    }
+  }
+
+  template<typename D>
+  void ResizeLike(const ArrayND<D,N> &other) {
+    Resize(other.Shape());
+  }
+
+  /// Resizes the array to shape s.  All data is lost.
+  void Resize(const int *new_shape_array) {
+    Resize(Index(new_shape_array));
+  }
+
+  /// Resize a 1D array to length s0.
+  void Resize(int s0) {
+    assert(N == 1);
+    int shape[] = {s0};
+    Resize(shape);
+  }
+
+  /// Resize a 2D array to shape (s0,s1).
+  void Resize(int s0, int s1) {
+    int shape[N] = {s0, s1};
+    for (int i = 2; i < N; ++i) {
+      shape[i] = 1;
+    }
+    Resize(shape);
+  }
+
+  // Match Eigen2's API.
+  void resize(int rows, int cols) {
+    Resize(rows, cols);
+  }
+
+  /// Resize a 3D array to shape (s0,s1,s2).
+  void Resize(int s0, int s1, int s2) {
+    assert(N == 3);
+    int shape[] = {s0,s1,s2};
+    Resize(shape);
+  }
+
+  template<typename D>
+  void CopyFrom(const ArrayND<D,N> &other) {
+    ResizeLike(other);
+    T *data = Data();
+    const D *other_data = other.Data();
+    for (int i = 0; i < Size(); ++i) {
+      data[i] = T(other_data[i]);
+    }
+  }
+
+  void Fill(T value) {
+    for (int i = 0; i < Size(); ++i) {
+      Data()[i] = value;
+    }
+  }
+
+  // Match Eigen's API.
+  void fill(T value) {
+    for (int i = 0; i < Size(); ++i) {
+      Data()[i] = value;
+    }
+  }
+
+  /// Return a tuple containing the length of each axis.
+  const Index &Shape() const {
+    return shape_;
+  }
+
+  /// Return the length of an axis.
+  int Shape(int axis) const {
+    return shape_(axis);
+  }
+
+  /// Return the distance between neighboring elements along axis.
+  int Stride(int axis) const {
+    return strides_(axis);
+  }
+
+  /// Return the number of elements of the array.
+  int Size() const {
+    int size = 1;
+    for (int i = 0; i < N; ++i)
+      size *= Shape(i);
+    return size;
+  }
+
+  /// Return the total amount of memory used by the array.
+  int MemorySizeInBytes() const {
+    return sizeof(*this) + Size() * sizeof(T);
+  }
+
+  /// Pointer to the first element of the array.
+  T *Data() { return data_; }
+
+  /// Constant pointer to the first element of the array.
+  const T *Data() const { return data_; }
+
+  /// Distance between the first element and the element at position index.
+  int Offset(const Index &index) const {
+    int offset = 0;
+    for (int i = 0; i < N; ++i)
+      offset += index(i) * Stride(i);
+    return offset;
+  }
+
+  /// 1D specialization.
+  int Offset(int i0) const {
+    assert(N == 1);
+    return i0 * Stride(0);
+  }
+
+  /// 2D specialization.
+  int Offset(int i0, int i1) const {
+    assert(N == 2);
+    return i0 * Stride(0) + i1 * Stride(1);
+  }
+
+  /// 3D specialization.
+  int Offset(int i0, int i1, int i2) const {
+    assert(N == 3);
+    return i0 * Stride(0) + i1 * Stride(1) + i2 * Stride(2);
+  }
+
+  /// Return a reference to the element at position index.
+  T &operator()(const Index &index) {
+    // TODO(pau) Boundary checking in debug mode.
+    return *( Data() + Offset(index) );
+  }
+
+  /// 1D specialization.
+  T &operator()(int i0) {
+    return *( Data() + Offset(i0) );
+  }
+
+  /// 2D specialization.
+  T &operator()(int i0, int i1) {
+    assert(0 <= i0 && i0 < Shape(0));
+    assert(0 <= i1 && i1 < Shape(1));
+    return *( Data() + Offset(i0,i1) );
+  }
+
+  /// 3D specialization.
+  T &operator()(int i0, int i1, int i2) {
+    assert(0 <= i0 && i0 < Shape(0));
+    assert(0 <= i1 && i1 < Shape(1));
+    assert(0 <= i2 && i2 < Shape(2));
+    return *( Data() + Offset(i0,i1,i2) );
+  }
+
+  /// Return a constant reference to the element at position index.
+  const T &operator()(const Index &index) const {
+    return *( Data() + Offset(index) );
+  }
+
+  /// 1D specialization.
+  const T &operator()(int i0) const {
+    return *( Data() + Offset(i0) );
+  }
+
+  /// 2D specialization.
+  const T &operator()(int i0, int i1) const {
+    assert(0 <= i0 && i0 < Shape(0));
+    assert(0 <= i1 && i1 < Shape(1));
+    return *( Data() + Offset(i0,i1) );
+  }
+
+  /// 3D specialization.
+  const T &operator()(int i0, int i1, int i2) const {
+    return *( Data() + Offset(i0,i1,i2) );
+  }
+
+  /// True if index is inside array.
+  bool Contains(const Index &index) const {
+    for (int i = 0; i < N; ++i)
+      if (index(i) < 0 || index(i) >= Shape(i))
+        return false;
+    return true;
+  }
+
+  /// 1D specialization.
+  bool Contains(int i0) const {
+    return 0 <= i0 && i0 < Shape(0);
+  }
+
+  /// 2D specialization.
+  bool Contains(int i0, int i1) const {
+    return 0 <= i0 && i0 < Shape(0)
+        && 0 <= i1 && i1 < Shape(1);
+  }
+
+  /// 3D specialization.
+  bool Contains(int i0, int i1, int i2) const {
+    return 0 <= i0 && i0 < Shape(0)
+        && 0 <= i1 && i1 < Shape(1)
+        && 0 <= i2 && i2 < Shape(2);
+  }
+
+  bool operator==(const ArrayND<T, N> &other) const {
+    if (shape_ != other.shape_) return false;
+    if (strides_ != other.strides_) return false;
+    for (int i = 0; i < Size(); ++i) {
+      if (this->Data()[i] != other.Data()[i])
+        return false;
+    }
+    return true;
+  }
+
+  bool operator!=(const ArrayND<T, N> &other) const {
+    return !(*this == other);
+  }
+
+  ArrayND<T, N> operator*(const ArrayND<T, N> &other) const {
+    assert(Shape() = other.Shape());
+    ArrayND<T, N> res;
+    res.ResizeLike(*this);
+    for (int i = 0; i < res.Size(); ++i) {
+      res.Data()[i] = Data()[i] * other.Data()[i];
+    }
+    return res;
+  }
+
+ protected:
+  /// The number of element in each dimension.
+  Index shape_;
+
+  /// How to jump to neighbors in each dimension.
+  Index strides_;
+
+  /// Pointer to the first element of the array.
+  T *data_;
+
+  /// Flag if this Array either own or reference the data
+  bool own_data;
+};
+
+/// 3D array (row, column, channel).
+template <typename T>
+class Array3D : public ArrayND<T, 3> {
+  typedef ArrayND<T, 3> Base;
+ public:
+  Array3D()
+      : Base() {
+  }
+  Array3D(int height, int width, int depth=1)
+      : Base(height, width, depth) {
+  }
+  Array3D(T* data, int height, int width, int depth=1)
+      : Base(data, height, width, depth) {
+  }
+
+  void Resize(int height, int width, int depth=1) {
+    Base::Resize(height, width, depth);
+  }
+
+  int Height() const {
+    return Base::Shape(0);
+  }
+  int Width() const {
+    return Base::Shape(1);
+  }
+  int Depth() const {
+    return Base::Shape(2);
+  }
+
+  // Match Eigen2's API so that Array3D's and Mat*'s can work together via
+  // template magic.
+  int rows() const { return Height(); }
+  int cols() const { return Width(); }
+  int depth() const { return Depth(); }
+
+  int Get_Step() const { return Width()*Depth(); }
+
+  /// Enable accessing with 2 indices for grayscale images.
+  T &operator()(int i0, int i1, int i2 = 0) {
+    assert(0 <= i0 && i0 < Height());
+    assert(0 <= i1 && i1 < Width());
+    return Base::operator()(i0,i1,i2);
+  }
+  const T &operator()(int i0, int i1, int i2 = 0) const {
+    assert(0 <= i0 && i0 < Height());
+    assert(0 <= i1 && i1 < Width());
+    return Base::operator()(i0,i1,i2);
+  }
+};
+
+typedef Array3D<unsigned char> Array3Du;
+typedef Array3D<unsigned int> Array3Dui;
+typedef Array3D<int> Array3Di;
+typedef Array3D<float> Array3Df;
+typedef Array3D<short> Array3Ds;
+
+void SplitChannels(const Array3Df &input,
+                   Array3Df *channel0,
+                   Array3Df *channel1,
+                   Array3Df *channel2);
+
+void PrintArray(const Array3Df &array);
+
+/** Convert a float array into a byte array by scaling values by 255* (max-min).
+ *  where max and min are automatically detected 
+ *  (if automatic_range_detection = true)
+ * \note and TODO this automatic detection only works when the image contains
+ *  at least one pixel of both bounds.
+ **/
+void FloatArrayToScaledByteArray(const Array3Df &float_array,
+                                 Array3Du *byte_array,
+                                 bool automatic_range_detection = false);
+
+//! Convert a byte array into a float array by dividing values by 255.
+void ByteArrayToScaledFloatArray(const Array3Du &byte_array,
+                                 Array3Df *float_array);
+
+template <typename AArrayType, typename BArrayType, typename CArrayType>
+void MultiplyElements( const AArrayType &a,
+           const BArrayType &b,
+           CArrayType *c ) {
+  // This function does an element-wise multiply between
+  // the two Arrays A and B, and stores the result in C.
+  // A and B must have the same dimensions.
+  assert( a.Shape() == b.Shape() );
+  c->ResizeLike(a);
+
+  // To perform the multiplcation, a "current" index into the N-dimensions of
+  // the A and B matrix specifies which elements are being multiplied.
+  typename CArrayType::Index index;
+
+  // The index starts at the maximum value for each dimension
+  const typename CArrayType::Index& cShape = c->Shape();
+  for ( int i = 0; i < CArrayType::Index::SIZE; ++i )
+    index(i) = cShape(i) - 1;
+
+  // After each multiplication, the highest-dimensional index is reduced.
+  // if this reduces it less than zero, it resets to its maximum value
+  // and decrements the index of the next lower dimension.
+  // This ripple-action continues until the entire new array has been
+  // calculated, indicated by dimension zero having a negative index.
+  while ( index(0) >= 0 ) {
+    (*c)(index) = a(index) * b(index);
+
+    int dimension = CArrayType::Index::SIZE - 1;
+    index(dimension) = index(dimension) - 1;
+    while ( dimension > 0 && index(dimension) < 0 ) {
+      index(dimension) = cShape(dimension) - 1;
+      index(dimension - 1) = index(dimension - 1) - 1;
+      --dimension;
+    }
+  }
+}
+
+template <typename TA, typename TB, typename TC>
+void MultiplyElements(const ArrayND<TA, 3> &a,
+                      const ArrayND<TB, 3> &b,
+                      ArrayND<TC, 3> *c) {
+  // Specialization for N==3
+  c->ResizeLike(a);
+  assert(a.Shape(0) == b.Shape(0));
+  assert(a.Shape(1) == b.Shape(1));
+  assert(a.Shape(2) == b.Shape(2));
+  for (int i = 0; i < a.Shape(0); ++i) {
+    for (int j = 0; j < a.Shape(1); ++j) {
+      for (int k = 0; k < a.Shape(2); ++k) {
+        (*c)(i, j, k) = TC(a(i, j, k) * b(i, j, k));
+      }
+    }
+  }
+}
+
+
+}  // namespace libmv
+
+#endif  // LIBMV_IMAGE_ARRAY_ND_H
diff --git a/extern/libmv/libmv/image/convolve.cc b/extern/libmv/libmv/image/convolve.cc
new file mode 100644 (file)
index 0000000..be73a1a
--- /dev/null
@@ -0,0 +1,305 @@
+// Copyright (c) 2007, 2008 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 <cmath>
+
+#include "libmv/image/image.h"
+#include "libmv/image/convolve.h"
+
+namespace libmv {
+
+// Compute a Gaussian kernel and derivative, such that you can take the
+// derivative of an image by convolving with the kernel horizontally then the
+// derivative vertically to get (eg) the y derivative.
+void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative) {
+  assert(sigma >= 0.0);
+
+  // 0.004 implies a 3 pixel kernel with 1 pixel sigma.
+  const float truncation_factor = 0.004f;
+
+  // Calculate the kernel size based on sigma such that it is odd.
+  float precisehalfwidth = GaussianInversePositive(truncation_factor, sigma);
+  int width = lround(2*precisehalfwidth);
+  if (width % 2 == 0) {
+    width++;
+  }
+  // Calculate the gaussian kernel and its derivative.
+  kernel->resize(width);
+  derivative->resize(width);
+  kernel->setZero();
+  derivative->setZero();
+  int halfwidth = width / 2;
+  for (int i = -halfwidth; i <= halfwidth; ++i)  {
+    (*kernel)(i + halfwidth) = Gaussian(i, sigma);
+    (*derivative)(i + halfwidth) = GaussianDerivative(i, sigma);
+  }
+  // Since images should not get brighter or darker, normalize.
+  NormalizeL1(kernel);
+
+  // Normalize the derivative differently. See
+  // www.cs.duke.edu/courses/spring03/cps296.1/handouts/Image%20Processing.pdf
+  double factor = 0.;
+  for (int i = -halfwidth; i <= halfwidth; ++i)  {
+    factor -= i*(*derivative)(i+halfwidth);
+  }
+  *derivative /= factor;
+}
+
+template <int size, bool vertical>
+void FastConvolve(const Vec &kernel, int width, int height,
+                  const float* src, int src_stride, int src_line_stride,
+                  float* dst, int dst_stride) {
+  double coefficients[2 * size + 1];
+  for (int k = 0; k < 2 * size + 1; ++k) {
+    coefficients[k] = kernel(2 * size - k);
+  }
+  // Fast path: if the kernel has a certain size, use the constant sized loops.
+  for (int y = 0; y < height; ++y) {
+    for (int x = 0; x < width; ++x) {
+      double sum = 0;
+      for (int k = -size; k <= size; ++k) {
+        if (vertical) {
+          if (y + k >= 0 && y + k < height) {
+            sum += src[k * src_line_stride] * coefficients[k + size];
+          }
+        } else {
+          if (x + k >= 0 && x + k < width) {
+            sum += src[k * src_stride] * coefficients[k + size];
+          }
+        }
+      }
+      dst[0] = static_cast<float>(sum);
+      src += src_stride;
+      dst += dst_stride;
+    }
+  }
+}
+
+template<bool vertical>
+void Convolve(const Array3Df &in,
+              const Vec &kernel,
+              Array3Df *out_pointer,
+              int plane) {
+  int width = in.Width();
+  int height = in.Height();
+  Array3Df &out = *out_pointer;
+  if (plane == -1) {
+    out.ResizeLike(in);
+    plane = 0;
+  }
+
+  assert(kernel.size() % 2 == 1);
+  assert(&in != out_pointer);
+
+  int src_line_stride = in.Stride(0);
+  int src_stride = in.Stride(1);
+  int dst_stride = out.Stride(1);
+  const float* src = in.Data();
+  float* dst = out.Data() + plane;
+
+  // Use a dispatch table to make most convolutions used in practice use the
+  // fast path.
+  int half_width = kernel.size() / 2;
+  switch (half_width) {
+#define static_convolution( size ) case size: \
+  FastConvolve<size, vertical>(kernel, width, height, src, src_stride, \
+                               src_line_stride, dst, dst_stride); break;
+    static_convolution(1)
+    static_convolution(2)
+    static_convolution(3)
+    static_convolution(4)
+    static_convolution(5)
+    static_convolution(6)
+    static_convolution(7)
+#undef static_convolution
+    default:
+      int dynamic_size = kernel.size() / 2;
+      for (int y = 0; y < height; ++y) {
+        for (int x = 0; x < width; ++x) {
+          double sum = 0;
+          // Slow path: this loop cannot be unrolled.
+          for (int k = -dynamic_size; k <= dynamic_size; ++k) {
+            if(vertical) {
+              if (y + k >= 0 && y + k < height) {
+                sum += src[k * src_line_stride] * kernel(2 * dynamic_size - (k + dynamic_size));
+              }
+            } else {
+              if (x + k >= 0 && x + k < width) {
+                sum += src[k * src_stride] * kernel(2 * dynamic_size - (k + dynamic_size));
+              }
+            }
+          }
+          dst[0] = static_cast<float>(sum);
+          src += src_stride;
+          dst += dst_stride;
+        }
+      }
+  }
+}
+
+void ConvolveHorizontal(const Array3Df &in,
+                        const Vec &kernel,
+                        Array3Df *out_pointer,
+                        int plane) {
+  Convolve<false>(in, kernel, out_pointer, plane);
+}
+
+void ConvolveVertical(const Array3Df &in,
+                      const Vec &kernel,
+                      Array3Df *out_pointer,
+                      int plane) {
+  Convolve<true>(in, kernel, out_pointer, plane);
+}
+
+void ConvolveGaussian(const Array3Df &in,
+                      double sigma,
+                      Array3Df *out_pointer) {
+  Vec kernel, derivative;
+  ComputeGaussianKernel(sigma, &kernel, &derivative);
+
+  Array3Df tmp;
+  ConvolveVertical(in, kernel, &tmp);
+  ConvolveHorizontal(tmp, kernel, out_pointer);
+}
+
+void BlurredImageAndDerivatives(const Array3Df &in,
+                                double sigma,
+                                Array3Df *blurred_image,
+                                Array3Df *gradient_x,
+                                Array3Df *gradient_y) {
+  Vec kernel, derivative;
+  ComputeGaussianKernel(sigma, &kernel, &derivative);
+  Array3Df tmp;
+
+  // Compute convolved image.
+  ConvolveVertical(in, kernel, &tmp);
+  ConvolveHorizontal(tmp, kernel, blurred_image);
+
+  // Compute first derivative in x (reusing vertical convolution above).
+  ConvolveHorizontal(tmp, derivative, gradient_x);
+
+  // Compute first derivative in y.
+  ConvolveHorizontal(in, kernel, &tmp);
+  ConvolveVertical(tmp, derivative, gradient_y);
+}
+
+// Compute the gaussian blur of an image and the derivatives of the blurred
+// image, and store the results in three channels. Since the blurred value and
+// gradients are closer in memory, this leads to better performance if all
+// three values are needed at the same time.
+void BlurredImageAndDerivativesChannels(const Array3Df &in,
+                                        double sigma,
+                                        Array3Df *blurred_and_gradxy) {
+  assert(in.Depth() == 1);
+
+  Vec kernel, derivative;
+  ComputeGaussianKernel(sigma, &kernel, &derivative);
+
+  // Compute convolved image.
+  Array3Df tmp;
+  ConvolveVertical(in, kernel, &tmp);
+  blurred_and_gradxy->Resize(in.Height(), in.Width(), 3);
+  ConvolveHorizontal(tmp, kernel, blurred_and_gradxy, 0);
+
+  // Compute first derivative in x.
+  ConvolveHorizontal(tmp, derivative, blurred_and_gradxy, 1);
+
+  // Compute first derivative in y.
+  ConvolveHorizontal(in, kernel, &tmp);
+  ConvolveVertical(tmp, derivative, blurred_and_gradxy, 2);
+}
+
+void BoxFilterHorizontal(const Array3Df &in,
+                         int window_size,
+                         Array3Df *out_pointer) {
+  Array3Df &out = *out_pointer;
+  out.ResizeLike(in);
+  int half_width = (window_size - 1) / 2;
+
+  for (int k = 0; k < in.Depth(); ++k) {
+    for (int i=0; i<in.Height(); ++i) {
+      float sum = 0;
+      // Init sum.
+      for (int j=0; j<half_width; ++j) {
+        sum += in(i, j, k);
+      }
+      // Fill left border.
+      for (int j=0; j < half_width + 1; ++j) {
+        sum += in(i, j + half_width, k);
+        out(i, j, k) = sum;
+      }
+      // Fill interior.
+      for (int j = half_width + 1; j<in.Width()-half_width; ++j) {
+        sum -= in(i, j - half_width - 1, k);
+        sum += in(i, j + half_width, k);
+        out(i, j, k) = sum;
+      }
+      // Fill right border.
+      for (int j = in.Width() - half_width; j<in.Width(); ++j) {
+        sum -= in(i, j - half_width - 1, k);
+        out(i, j, k) = sum;
+      }
+    }
+  }
+}
+
+void BoxFilterVertical(const Array3Df &in,
+                       int window_size,
+                       Array3Df *out_pointer) {
+  Array3Df &out = *out_pointer;
+  out.ResizeLike(in);
+  int half_width = (window_size - 1) / 2;
+
+  for (int k = 0; k < in.Depth(); ++k) {
+    for (int j = 0; j < in.Width(); ++j) {
+      float sum = 0;
+      // Init sum.
+      for (int i=0; i<half_width; ++i) {
+        sum += in(i, j, k);
+      }
+      // Fill left border.
+      for (int i=0; i < half_width + 1; ++i) {
+        sum += in(i + half_width, j, k);
+        out(i, j, k) = sum;
+      }
+      // Fill interior.
+      for (int i = half_width + 1; i<in.Height()-half_width; ++i) {
+        sum -= in(i - half_width - 1, j, k);
+        sum += in(i + half_width, j, k);
+        out(i, j, k) = sum;
+      }
+      // Fill right border.
+      for (int i = in.Height() - half_width; i<in.Height(); ++i) {
+        sum -= in(i - half_width - 1, j, k);
+        out(i, j, k) = sum;
+      }
+    }
+  }
+}
+
+void BoxFilter(const Array3Df &in,
+               int box_width,
+               Array3Df *out) {
+  Array3Df tmp;
+  BoxFilterHorizontal(in, box_width, &tmp);
+  BoxFilterVertical(tmp, box_width, out);
+}
+
+}  // namespace libmv
diff --git a/extern/libmv/libmv/image/convolve.h b/extern/libmv/libmv/image/convolve.h
new file mode 100644 (file)
index 0000000..c6c995f
--- /dev/null
@@ -0,0 +1,93 @@
+// Copyright (c) 2007, 2008, 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_IMAGE_CONVOLVE_H_
+#define LIBMV_IMAGE_CONVOLVE_H_
+
+#include "libmv/image/image.h"
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+// TODO(keir): Find a better place for these functions. gaussian.h in numeric?
+
+// Zero mean Gaussian.
+inline double Gaussian(double x, double sigma) {
+  return 1/sqrt(2*M_PI*sigma*sigma) * exp(-(x*x/2/sigma/sigma));
+}
+// 2D gaussian (zero mean)
+// (9) in http://mathworld.wolfram.com/GaussianFunction.html
+inline double Gaussian2D(double x, double y, double sigma) {
+  return 1.0/(2.0*M_PI*sigma*sigma) * exp( -(x*x+y*y)/(2.0*sigma*sigma));
+}
+inline double GaussianDerivative(double x, double sigma) {
+  return -x / sigma / sigma * Gaussian(x, sigma);
+}
+// Solve the inverse of the Gaussian for positive x.
+inline double GaussianInversePositive(double y, double sigma) {
+  return sqrt(-2 * sigma * sigma * log(y * sigma * sqrt(2*M_PI)));
+}
+
+void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative);
+void ConvolveHorizontal(const FloatImage &in,
+                        const Vec &kernel,
+                        FloatImage *out_pointer,
+                        int plane = -1);
+void ConvolveVertical(const FloatImage &in,
+                      const Vec &kernel,
+                      FloatImage *out_pointer,
+                      int plane = -1);
+void ConvolveGaussian(const FloatImage &in,
+                      double sigma,
+                      FloatImage *out_pointer);
+
+void ImageDerivatives(const FloatImage &in,
+                      double sigma,
+                      FloatImage *gradient_x,
+                      FloatImage *gradient_y);
+
+void BlurredImageAndDerivatives(const FloatImage &in,
+                                double sigma,
+                                FloatImage *blurred_image,
+                                FloatImage *gradient_x,
+                                FloatImage *gradient_y);
+
+// Blur and take the gradients of an image, storing the results inside the
+// three channels of blurred_and_gradxy.
+void BlurredImageAndDerivativesChannels(const FloatImage &in,
+                                        double sigma,
+                                        FloatImage *blurred_and_gradxy);
+
+void BoxFilterHorizontal(const FloatImage &in,
+                         int window_size,
+                         FloatImage *out_pointer);
+
+void BoxFilterVertical(const FloatImage &in,
+                       int window_size,
+                       FloatImage *out_pointer);
+
+void BoxFilter(const FloatImage &in,
+               int box_width,
+               FloatImage *out);
+
+}  // namespace libmv
+
+#endif  // LIBMV_IMAGE_CONVOLVE_H_
+
diff --git a/extern/libmv/libmv/image/image.h b/extern/libmv/libmv/image/image.h
new file mode 100644 (file)
index 0000000..d158b0e
--- /dev/null
@@ -0,0 +1,158 @@
+// Copyright (c) 2007, 2008 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_IMAGE_IMAGE_H
+#define LIBMV_IMAGE_IMAGE_H
+
+#include <cmath>
+
+#include "libmv/image/array_nd.h"
+
+namespace libmv {
+
+typedef Array3Du ByteImage;  // For backwards compatibility.
+typedef Array3Df FloatImage;
+
+// Type added only to manage special 2D array for feature detection
+typedef Array3Di IntImage;
+typedef Array3Ds ShortImage;
+
+// An image class that is a thin wrapper around Array3D's of various types.
+// TODO(keir): Decide if we should add reference counting semantics... Maybe it
+// is the best solution after all.
+class Image {
+ public:
+
+  // Create an image from an array. The image takes ownership of the array.
+  Image(Array3Du *array) : array_type_(BYTE), array_(array) {}
+  Image(Array3Df *array) : array_type_(FLOAT), array_(array) {}
+
+  Image(const Image &img): array_type_(NONE), array_(NULL) {
+    *this = img;
+  }
+
+  // Underlying data type.
+  enum DataType {
+    NONE,
+    BYTE,
+    FLOAT,
+    INT,
+    SHORT,
+  };
+
+  // Size in bytes that the image takes in memory.
+  int MemorySizeInBytes() {
+    int size;
+    switch (array_type_)
+    {
+      case BYTE:
+        size = reinterpret_cast<Array3Du *>(array_)->MemorySizeInBytes();
+      break;
+      case FLOAT:
+        size = reinterpret_cast<Array3Df *>(array_)->MemorySizeInBytes();
+      break;
+      case INT:
+        size = reinterpret_cast<Array3Di *>(array_)->MemorySizeInBytes();
+      break;
+      case SHORT:
+        size = reinterpret_cast<Array3Ds *>(array_)->MemorySizeInBytes();
+      break;
+    default :
+      size = 0;
+      assert(0);
+    }
+    size += sizeof(*this);
+    return size;
+  }
+
+  ~Image() {
+    switch (array_type_)
+      {
+        case BYTE:
+          delete reinterpret_cast<Array3Du *>(array_);
+
+        break;
+        case FLOAT:
+          delete reinterpret_cast<Array3Df *>(array_);
+
+        break;
+        case INT:
+          delete reinterpret_cast<Array3Di *>(array_);
+
+        break;
+        case SHORT:
+          delete reinterpret_cast<Array3Ds *>(array_);
+
+        break;
+        default:
+          assert(0);
+      }
+  }
+
+  Image& operator= (const Image& f)  {
+    if (this != &f) {
+      array_type_ = f.array_type_;
+      switch (array_type_)
+      {
+        case BYTE:
+          delete reinterpret_cast<Array3Du *>(array_);
+          array_ = new Array3Du( *(Array3Du *)f.array_);
+        break;
+        case FLOAT:
+          delete reinterpret_cast<Array3Df *>(array_);
+          array_ = new Array3Df( *(Array3Df *)f.array_);
+        break;
+        case INT:
+          delete reinterpret_cast<Array3Di *>(array_);
+          array_ = new Array3Di( *(Array3Di *)f.array_);
+        break;
+        case SHORT:
+          delete reinterpret_cast<Array3Ds *>(array_);
+          array_ = new Array3Ds( *(Array3Ds *)f.array_);
+        break;
+        default:
+          assert(0);
+      }
+    }
+    return *this;
+  }
+
+  Array3Du *AsArray3Du() const {
+    if (array_type_ == BYTE) {
+      return reinterpret_cast<Array3Du *>(array_);
+    }
+    return NULL;
+  }
+
+  Array3Df *AsArray3Df() const {
+    if (array_type_ == FLOAT) {
+      return reinterpret_cast<Array3Df *>(array_);
+    }
+    return NULL;
+  }
+
+ private:
+  DataType array_type_;
+  BaseArray *array_;
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_IMAGE_IMAGE_IMAGE_H
diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h
new file mode 100644 (file)
index 0000000..cd36123
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (c) 2007, 2008 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_IMAGE_SAMPLE_H_
+#define LIBMV_IMAGE_SAMPLE_H_
+
+#include "libmv/image/image.h"
+
+namespace libmv {
+
+/// Nearest neighbor interpolation.
+template<typename T>
+inline T SampleNearest(const Array3D<T> &image,
+                       float y, float x, int v = 0) {
+  const int i = int(round(y));
+  const int j = int(round(x));
+  return image(i, j, v);
+}
+
+static inline void LinearInitAxis(float fx, int width,
+                                  int *x1, int *x2,
+                                  float *dx1, float *dx2) {
+  const int ix = int(fx);
+  if (ix < 0) {
+    *x1 = 0;
+    *x2 = 0;
+    *dx1 = 1;
+    *dx2 = 0;
+  } else if (ix > width-2) {
+    *x1 = width-1;
+    *x2 = width-1;
+    *dx1 = 1;
+    *dx2 = 0;
+  } else {
+    *x1 = ix;
+    *x2 = *x1 + 1;
+    *dx1 = *x2 - fx;
+    *dx2 = 1 - *dx1;
+  }
+}
+
+/// Linear interpolation.
+template<typename T>
+inline T SampleLinear(const Array3D<T> &image, float y, float x, int v = 0) {
+  int x1, y1, x2, y2;
+  float dx1, dy1, dx2, dy2;
+
+  LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2);
+  LinearInitAxis(x, image.Width(),  &x1, &x2, &dx1, &dx2);
+
+  const T im11 = image(y1, x1, v);
+  const T im12 = image(y1, x2, v);
+  const T im21 = image(y2, x1, v);
+  const T im22 = image(y2, x2, v);
+
+  return T(dy1 * ( dx1 * im11 + dx2 * im12 ) +
+           dy2 * ( dx1 * im21 + dx2 * im22 ));
+}
+
+// Downsample all channels by 2. If the image has odd width or height, the last
+// row or column is ignored.
+// FIXME(MatthiasF): this implementation shouldn't be in an interface file
+inline void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out) {
+  int height = in.Height() / 2;
+  int width = in.Width() / 2;
+  int depth = in.Depth();
+
+  out->Resize(height, width, depth);
+
+  // 2x2 box filter downsampling.
+  for (int r = 0; r < height; ++r) {
+    for (int c = 0; c < width; ++c) {
+      for (int k = 0; k < depth; ++k) {
+        (*out)(r, c, k) = (in(2 * r,     2 * c,     k) +
+                           in(2 * r + 1, 2 * c,     k) +
+                           in(2 * r,     2 * c + 1, k) +
+                           in(2 * r + 1, 2 * c + 1, k)) / 4.0f;
+      }
+    }
+  }
+
+}
+
+}  // namespace libmv
+
+#endif  // LIBMV_IMAGE_SAMPLE_H_
diff --git a/extern/libmv/libmv/image/tuple.h b/extern/libmv/libmv/image/tuple.h
new file mode 100644 (file)
index 0000000..79acc95
--- /dev/null
@@ -0,0 +1,90 @@
+// Copyright (c) 2007, 2008 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_IMAGE_TUPLE_H
+#define LIBMV_IMAGE_TUPLE_H
+
+#include <algorithm>
+
+namespace libmv {
+
+// A vector of elements with fixed lenght and deep copy semantics.
+template <typename T, int N>
+class Tuple {
+ public:
+  enum { SIZE = N };
+  Tuple() {}
+  Tuple(T initial_value) { Reset(initial_value); }
+
+  template <typename D>
+  Tuple(D *values) { Reset(values); }
+
+  template <typename D>
+  Tuple(const Tuple<D,N> &b) { Reset(b); }
+
+  template <typename D>
+  Tuple& operator=(const Tuple<D,N>& b) {
+    Reset(b);
+    return *this;
+  }
+
+  template <typename D>
+  void Reset(const Tuple<D, N>& b) { Reset(b.Data()); }
+
+  template <typename D>
+  void Reset(D *values) {
+    for(int i=0;i<N;i++) {
+      data_[i] = T(values[i]);
+    }
+  }
+
+  // Set all tuple values to the same thing.
+  void Reset(T value) {
+    for(int i=0;i<N;i++) {
+      data_[i] = value;
+    }
+  }
+
+  // Pointer to the first element.
+  T *Data() { return &data_[0]; }
+  const T *Data() const { return &data_[0]; }
+
+  T &operator()(int i) { return data_[i]; }
+  const T &operator()(int i) const { return data_[i]; }
+
+  bool operator==(const Tuple<T, N> &other) const {
+    for (int i = 0; i < N; ++i) {
+      if ((*this)(i) != other(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+  bool operator!=(const Tuple<T, N> &other) const {
+    return !(*this == other);
+  }
+
+ private:
+  T data_[N];
+};
+
+}  // namespace libmv
+
+#endif  // LIBMV_IMAGE_TUPLE_H
diff --git a/extern/libmv/libmv/logging/logging.h b/extern/libmv/libmv/logging/logging.h
new file mode 100644 (file)
index 0000000..af86c4b
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright (c) 2007, 2008, 2009 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_LOGGING_LOGGING_H
+#define LIBMV_LOGGING_LOGGING_H
+
+#include "glog/logging.h"
+
+#define LG LOG(INFO)
+#define V0 LOG(INFO)
+#define V1 LOG(INFO)
+#define V2 LOG(INFO)
+
+#endif  // LIBMV_LOGGING_LOGGING_H
diff --git a/extern/libmv/libmv/multiview/conditioning.cc b/extern/libmv/libmv/multiview/conditioning.cc
new file mode 100644 (file)
index 0000000..20e3a88
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (c) 2010 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/multiview/conditioning.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+// HZ 4.4.4 pag.109: Point conditioning (non isotropic)
+void PreconditionerFromPoints(const Mat &points, Mat3 *T) {
+  Vec mean, variance;
+  MeanAndVarianceAlongRows(points, &mean, &variance);
+
+  double xfactor = sqrt(2.0 / variance(0));
+  double yfactor = sqrt(2.0 / variance(1));
+
+  // If variance is equal to 0.0 set scaling factor to identity.
+  // -> Else it will provide nan value (because division by 0).
+  if (variance(0) < 1e-8)
+    xfactor = mean(0) = 1.0;
+  if (variance(1) < 1e-8)
+    yfactor = mean(1) = 1.0;
+
+  *T << xfactor, 0,       -xfactor * mean(0),
+        0,       yfactor, -yfactor * mean(1),
+        0,       0,        1;
+}
+// HZ 4.4.4 pag.107: Point conditioning (isotropic)
+void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T) {
+  Vec mean, variance;
+  MeanAndVarianceAlongRows(points, &mean, &variance);
+
+  double var_norm = variance.norm();
+  double factor = sqrt(2.0 / var_norm);
+
+  // If variance is equal to 0.0 set scaling factor to identity.
+  // -> Else it will provide nan value (because division by 0).
+  if (var_norm < 1e-8) {
+    factor = 1.0;
+    mean.setOnes();
+  }
+
+  *T << factor, 0,       -factor * mean(0),
+        0,       factor, -factor * mean(1),
+        0,       0,        1;
+}
+
+void ApplyTransformationToPoints(const Mat &points,
+                                 const Mat3 &T,
+                                 Mat *transformed_points) {
+  int n = points.cols();
+  transformed_points->resize(2,n);
+  Mat3X p(3, n);
+  EuclideanToHomogeneous(points, &p);
+  p = T * p;
+  HomogeneousToEuclidean(p, transformed_points);
+}
+
+void NormalizePoints(const Mat &points,
+                     Mat *normalized_points,
+                     Mat3 *T) {
+  PreconditionerFromPoints(points, T);
+  ApplyTransformationToPoints(points, *T, normalized_points);
+}
+
+void NormalizeIsotropicPoints(const Mat &points,
+                              Mat *normalized_points,
+                              Mat3 *T) {
+  IsotropicPreconditionerFromPoints(points, T);
+  ApplyTransformationToPoints(points, *T, normalized_points);
+}
+
+// Denormalize the results. See HZ page 109.
+void UnnormalizerT::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H)  {
+  *H = T2.transpose() * (*H) * T1;
+}
+
+void UnnormalizerI::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H)  {
+  *H = T2.inverse() * (*H) * T1;
+}
+
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/conditioning.h b/extern/libmv/libmv/multiview/conditioning.h
new file mode 100644 (file)
index 0000000..181d748
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 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_MULTIVIEW_CONDITIONNING_H_
+#define LIBMV_MULTIVIEW_CONDITIONNING_H_
+
+#include "libmv/numeric/numeric.h"
+
+namespace libmv {
+
+// Point conditioning (non isotropic)
+void PreconditionerFromPoints(const Mat &points, Mat3 *T);
+// Point conditioning (isotropic)
+void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T);
+
+void ApplyTransformationToPoints(const Mat &points,
+                                 const Mat3 &T,
+                                 Mat *transformed_points);
+
+void NormalizePoints(const Mat &points,
+                     Mat *normalized_points,
+                     Mat3 *T);
+
+void NormalizeIsotropicPoints(const Mat &points,
+                              Mat *normalized_points,
+                              Mat3 *T);
+
+/// Use inverse for unnormalize
+struct UnnormalizerI {
+  // Denormalize the results. See HZ page 109.
+  static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H);
+};
+
+/// Use transpose for unnormalize
+struct UnnormalizerT {
+  // Denormalize the results. See HZ page 109.
+  static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H);
+};
+
+} //namespace libmv
+
+
+#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_
diff --git a/extern/libmv/libmv/multiview/euclidean_resection.cc b/extern/libmv/libmv/multiview/euclidean_resection.cc
new file mode 100644 (file)
index 0000000..6d918a1
--- /dev/null
@@ -0,0 +1,661 @@
+// Copyright (c) 2009 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 <cmath>
+#include <limits>
+
+#include <Eigen/SVD>
+#include <Eigen/Geometry>
+
+#include "libmv/base/vector.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/euclidean_resection.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+namespace euclidean_resection {
+
+bool EuclideanResection(const Mat2X &x_camera, 
+                        const Mat3X &X_world,
+                        Mat3 *R, Vec3 *t,
+                        ResectionMethod method) {
+  switch (method) {
+    case RESECTION_ANSAR_DANIILIDIS:
+      EuclideanResectionAnsarDaniilidis(x_camera, X_world, R, t);
+      break;
+    case RESECTION_EPNP:
+      return EuclideanResectionEPnP(x_camera, X_world, R, t);      
+      break;
+    default:
+      LOG(FATAL) << "Unknown resection method.";
+  }
+  return false;
+}
+
+bool EuclideanResection(const Mat &x_image, 
+                        const Mat3X &X_world,
+                        const Mat3 &K,
+                        Mat3 *R, Vec3 *t,
+                        ResectionMethod method) {
+  CHECK(x_image.rows() == 2 || x_image.rows() == 3)
+    << "Invalid size for x_image: "
+    << x_image.rows() << "x" << x_image.cols();
+
+  Mat2X x_camera;
+  if (x_image.rows() == 2) {
+    EuclideanToNormalizedCamera(x_image, K, &x_camera);
+  } else if (x_image.rows() == 3) {
+    HomogeneousToNormalizedCamera(x_image, K, &x_camera);
+  }
+  return EuclideanResection(x_camera, X_world, R, t, method);
+}
+
+void AbsoluteOrientation(const Mat3X &X,
+                         const Mat3X &Xp,
+                         Mat3 *R,
+                         Vec3 *t) {
+  int num_points = X.cols();
+  Vec3 C  = X.rowwise().sum() / num_points;   // Centroid of X.
+  Vec3 Cp = Xp.rowwise().sum() / num_points;  // Centroid of Xp.
+
+  // Normalize the two point sets.
+  Mat3X Xn(3, num_points), Xpn(3, num_points);
+  for( int i = 0; i < num_points; ++i ){
+    Xn.col(i)  = X.col(i) - C;
+    Xpn.col(i) = Xp.col(i) - Cp;
+  }
+  
+  // Construct the N matrix (pg. 635).
+  double Sxx = Xn.row(0).dot(Xpn.row(0));
+  double Syy = Xn.row(1).dot(Xpn.row(1));
+  double Szz = Xn.row(2).dot(Xpn.row(2));
+  double Sxy = Xn.row(0).dot(Xpn.row(1));
+  double Syx = Xn.row(1).dot(Xpn.row(0));
+  double Sxz = Xn.row(0).dot(Xpn.row(2));
+  double Szx = Xn.row(2).dot(Xpn.row(0));
+  double Syz = Xn.row(1).dot(Xpn.row(2));
+  double Szy = Xn.row(2).dot(Xpn.row(1));
+
+  Mat4 N;
+  N << Sxx + Syy + Szz, Syz - Szy,        Szx - Sxz,        Sxy - Syx,
+       Syz - Szy,       Sxx - Syy - Szz,  Sxy + Syx,        Szx + Sxz,
+       Szx - Sxz,       Sxy + Syx,       -Sxx + Syy - Szz,  Syz + Szy,
+       Sxy - Syx,       Szx + Sxz,        Syz + Szy,       -Sxx - Syy + Szz;
+           
+  // Find the unit quaternion q that maximizes qNq. It is the eigenvector
+  // corresponding to the lagest eigenvalue.
+  Vec4 q = N.jacobiSvd(Eigen::ComputeFullU).matrixU().col(0);
+
+  // Retrieve the 3x3 rotation matrix.
+  Vec4 qq = q.array() * q.array();
+  double q0q1 = q(0) * q(1);
+  double q0q2 = q(0) * q(2);
+  double q0q3 = q(0) * q(3);
+  double q1q2 = q(1) * q(2);
+  double q1q3 = q(1) * q(3);
+  double q2q3 = q(2) * q(3);
+
+  (*R) << qq(0) + qq(1) - qq(2) - qq(3),
+          2 * (q1q2 - q0q3),
+          2 * (q1q3 + q0q2),
+          2 * (q1q2+ q0q3),
+          qq(0) - qq(1) + qq(2) - qq(3),
+          2 * (q2q3 - q0q1),
+          2 * (q1q3 - q0q2),
+          2 * (q2q3 + q0q1),
+          qq(0) - qq(1) - qq(2) + qq(3);
+
+  // Fix the handedness of the R matrix.
+  if (R->determinant() < 0) {
+    R->row(2) = -R->row(2);
+  }
+  // Compute the final translation.
+  *t = Cp - *R * C;
+}
+
+// Convert i and j indices of the original variables into their quadratic
+// permutation single index. It follows that t_ij = t_ji.
+static int IJToPointIndex(int i, int j, int num_points) {
+  // Always make sure that j is bigger than i. This handles t_ij = t_ji.
+  if (j < i) {
+    std::swap(i, j);
+  }
+  int idx;
+  int num_permutation_rows = num_points * (num_points - 1) / 2;
+
+  // All t_ii's are located at the end of the t vector after all t_ij's.
+  if (j == i) {
+    idx = num_permutation_rows + i;
+  } else {
+    int offset = (num_points - i - 1) * (num_points - i) / 2;
+    idx = (num_permutation_rows - offset + j - i - 1);
+  }
+  return idx;
+};
+
+// Convert i and j indexes of the solution for lambda to their linear indexes.
+static int IJToIndex(int i, int j, int num_lambda) {
+  if (j < i) {
+    std::swap(i, j);
+  }
+  int A = num_lambda * (num_lambda + 1) / 2;
+  int B = num_lambda - i;
+  int C = B * (B + 1) / 2;
+  int idx = A - C + j - i;
+  return idx;
+};
+
+static int Sign(double value) {
+  return (value < 0) ? -1 : 1;
+};
+
+// Organizes a square matrix into a single row constraint on the elements of
+// Lambda to create the constraints in equation (5) in "Linear Pose Estimation
+// from Points or Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no.
+// 5.
+static Vec MatrixToConstraint(const Mat &A,
+                              int num_k_columns,
+                              int num_lambda) {
+  Vec C(num_k_columns);
+  C.setZero();
+  int idx = 0;
+  for (int i = 0; i < num_lambda; ++i) {
+    for( int j = i; j < num_lambda; ++j) {
+      C(idx) = A(i, j);
+      if (i != j){
+        C(idx) += A(j, i);
+      }
+      ++ idx;
+    }
+  }
+  return C;
+}
+
+// Normalizes the columns of vectors.
+static void NormalizeColumnVectors(Mat3X *vectors) {
+  int num_columns = vectors->cols();
+  for (int i = 0; i < num_columns; ++i){
+    vectors->col(i).normalize();
+  }
+}
+
+void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, 
+                                       const Mat3X &X_world,               
+                                       Mat3 *R, 
+                                       Vec3 *t) {
+  CHECK(x_camera.cols() == X_world.cols());
+  CHECK(x_camera.cols() > 3);
+
+  int num_points = x_camera.cols();
+
+  // Copy the normalized camera coords into 3 vectors and normalize them so
+  // that they are unit vectors from the camera center.
+  Mat3X x_camera_unit(3, num_points);
+  x_camera_unit.block(0, 0, 2, num_points) = x_camera;
+  x_camera_unit.row(2).setOnes();
+  NormalizeColumnVectors(&x_camera_unit);
+  
+  int num_m_rows = num_points * (num_points - 1) / 2;
+  int num_tt_variables = num_points * (num_points + 1) / 2;
+  int num_m_columns = num_tt_variables + 1;
+  Mat M(num_m_columns, num_m_columns);
+  M.setZero();
+  Matu ij_index(num_tt_variables, 2);
+
+  // Create the constraint equations for the t_ij variables (7) and arrange
+  // them into the M matrix (8). Also store the initial (i, j) indices.
+  int row=0;
+  for (int i = 0; i < num_points; ++i) {
+    for (int j = i+1; j < num_points; ++j) {
+      M(row, row) = -2 * x_camera_unit.col(i).dot(x_camera_unit.col(j));
+      M(row, num_m_rows + i) = x_camera_unit.col(i).dot(x_camera_unit.col(i));
+      M(row, num_m_rows + j) = x_camera_unit.col(j).dot(x_camera_unit.col(j));
+      Vec3 Xdiff = X_world.col(i) - X_world.col(j);
+      double center_to_point_distance = Xdiff.norm();
+      M(row, num_m_columns - 1) =
+          - center_to_point_distance * center_to_point_distance;
+      ij_index(row, 0) = i;
+      ij_index(row, 1) = j;
+      ++row;
+    }
+    ij_index(i + num_m_rows, 0) = i;
+    ij_index(i + num_m_rows, 1) = i;
+  }
+
+  int num_lambda = num_points + 1;  // Dimension of the null space of M.
+  Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0, 
+                                                           num_m_rows,
+                                                           num_m_columns,
+                                                           num_lambda);
+
+  // TODO(vess): The number of constraint equations in K (num_k_rows) must be
+  // (num_points + 1) * (num_points + 2)/2. This creates a performance issue
+  // for more than 4 points. It is fine for 4 points at the moment with 18
+  // instead of 15 equations.
+  int num_k_rows = num_m_rows + num_points *
+                   (num_points*(num_points-1)/2 - num_points+1);
+  int num_k_columns = num_lambda * (num_lambda + 1) / 2;
+  Mat K(num_k_rows, num_k_columns);
+  K.setZero();
+
+  // Construct the first part of the K matrix corresponding to (t_ii, t_jk) for
+  // i != j.
+  int counter_k_row = 0;
+  for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) {
+    for (int idx2 = 0; idx2 < num_m_rows; ++idx2) {
+
+      unsigned int i = ij_index(idx1, 0);
+      unsigned int j = ij_index(idx2, 0);
+      unsigned int k = ij_index(idx2, 1);
+
+      if( i != j && i != k ){
+        int idx3 = IJToPointIndex(i, j, num_points);
+        int idx4 = IJToPointIndex(i, k, num_points);
+
+        K.row(counter_k_row) =
+            MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)-
+                               V.row(idx3).transpose() * V.row(idx4),
+                               num_k_columns,
+                               num_lambda);
+        ++counter_k_row;
+      }
+    }
+  }
+
+  // Construct the second part of the K matrix corresponding to (t_ii,t_jk) for
+  // j==k.
+  for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) {
+    for (int idx2 = idx1 + 1; idx2 < num_tt_variables; ++idx2) {
+      unsigned int i = ij_index(idx1, 0);
+      unsigned int j = ij_index(idx2, 0);
+      unsigned int k = ij_index(idx2, 1);
+
+      int idx3 = IJToPointIndex(i, j, num_points);
+      int idx4 = IJToPointIndex(i, k, num_points);
+
+      K.row(counter_k_row) =
+          MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)-
+                             V.row(idx3).transpose() * V.row(idx4),
+                             num_k_columns,
+                             num_lambda);
+      ++counter_k_row;
+    }
+  }
+  Vec L_sq = K.jacobiSvd(Eigen::ComputeFullV).matrixV().col(num_k_columns - 1);
+
+  // Pivot on the largest element for numerical stability. Afterwards recover
+  // the sign of the lambda solution.
+  double max_L_sq_value = fabs(L_sq(IJToIndex(0, 0, num_lambda)));
+  int max_L_sq_index = 1;
+  for (int i = 1; i < num_lambda; ++i) {
+    double abs_sq_value = fabs(L_sq(IJToIndex(i, i, num_lambda)));
+    if (max_L_sq_value < abs_sq_value) {
+      max_L_sq_value = abs_sq_value;
+      max_L_sq_index = i;
+    }
+  }
+  // Ensure positiveness of the largest value corresponding to lambda_ii.
+  L_sq = L_sq * Sign(L_sq(IJToIndex(max_L_sq_index,
+                                    max_L_sq_index,
+                                    num_lambda)));
+  
+  
+  Vec L(num_lambda);
+  L(max_L_sq_index) = sqrt(L_sq(IJToIndex(max_L_sq_index,
+                                          max_L_sq_index,
+                                          num_lambda)));
+  
+  for (int i = 0; i < num_lambda; ++i) {
+    if (i != max_L_sq_index) {
+      L(i) = L_sq(IJToIndex(max_L_sq_index, i, num_lambda)) / L(max_L_sq_index);
+    }
+  }
+
+  // Correct the scale using the fact that the last constraint is equal to 1.
+  L = L / (V.row(num_m_columns - 1).dot(L));
+  Vec X = V * L;
+  
+  // Recover the distances from the camera center to the 3D points Q.
+  Vec d(num_points);
+  d.setZero();
+  for (int c_point = num_m_rows; c_point < num_tt_variables; ++c_point) {
+    d(c_point - num_m_rows) = sqrt(X(c_point));
+  }
+
+  // Create the 3D points in the camera system.
+  Mat X_cam(3, num_points);
+  for (int c_point = 0; c_point < num_points; ++c_point ) {
+    X_cam.col(c_point) = d(c_point) * x_camera_unit.col(c_point);
+  }
+  // Recover the camera translation and rotation.
+  AbsoluteOrientation(X_world, X_cam, R, t);
+}
+
+// Selects 4 virtual control points using mean and PCA.
+void SelectControlPoints(const Mat3X &X_world, 
+                         Mat *X_centered, 
+                         Mat34 *X_control_points) {
+  size_t num_points = X_world.cols();
+
+  // The first virtual control point, C0, is the centroid.
+  Vec mean, variance;
+  MeanAndVarianceAlongRows(X_world, &mean, &variance);
+  X_control_points->col(0) = mean;
+
+  // Computes PCA
+  X_centered->resize (3, num_points);
+  for (size_t c = 0; c < num_points; c++) {
+    X_centered->col(c) = X_world.col (c) - mean;
+  }
+  Mat3 X_centered_sq = (*X_centered) * X_centered->transpose();
+  Eigen::JacobiSVD<Mat3> X_centered_sq_svd(X_centered_sq, Eigen::ComputeFullU);
+  Vec3 w = X_centered_sq_svd.singularValues();
+  Mat3 u = X_centered_sq_svd.matrixU();
+  for (size_t c = 0; c < 3; c++) {
+    double k = sqrt (w (c) / num_points);
+    X_control_points->col (c + 1) = mean + k * u.col (c);
+  }
+}
+
+// Computes the barycentric coordinates for all real points
+void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, 
+                                   const Mat34 &X_control_points,
+                                   Mat4X *alphas) {
+  size_t num_points = X_world_centered.cols();
+  Mat3 C2 ;
+  for (size_t c = 1; c < 4; c++) {
+    C2.col(c-1) = X_control_points.col(c) - X_control_points.col(0);
+  }
+
+  Mat3 C2inv = C2.inverse();
+  Mat3X a = C2inv * X_world_centered;
+
+  alphas->resize(4, num_points);
+  alphas->setZero();
+  alphas->block(1, 0, 3, num_points) = a;
+  for (size_t c = 0; c < num_points; c++) {
+    (*alphas)(0, c) = 1.0 - alphas->col(c).sum();
+  }
+}
+
+// Estimates the coordinates of all real points in the camera coordinate frame
+void ComputePointsCoordinatesInCameraFrame(
+    const Mat4X &alphas, 
+    const Vec4 &betas,
+    const Eigen::Matrix<double, 12, 12> &U,
+    Mat3X *X_camera) {
+  size_t num_points = alphas.cols();
+
+  // Estimates the control points in the camera reference frame.
+  Mat34 C2b; C2b.setZero();
+  for (size_t cu = 0; cu < 4; cu++) {
+    for (size_t c = 0; c < 4; c++) {
+      C2b.col(c) += betas(cu) * U.block(11 - cu, c * 3, 1, 3).transpose();
+    }
+  }
+
+  // Estimates the 3D points in the camera reference frame
+  X_camera->resize(3, num_points);
+  for (size_t c = 0; c < num_points; c++) {
+    X_camera->col(c) = C2b * alphas.col(c);
+  }
+
+  // Check the sign of the z coordinate of the points (should be positive)
+  uint num_z_neg = 0;
+  for (size_t i = 0; i < X_camera->cols(); ++i) {
+    if ((*X_camera)(2,i) < 0) {
+      num_z_neg++;
+    }
+  }
+
+  // If more than 50% of z are negative, we change the signs
+  if (num_z_neg > 0.5 * X_camera->cols()) {
+    C2b = -C2b;
+    *X_camera = -(*X_camera);
+  }    
+}
+
+bool EuclideanResectionEPnP(const Mat2X &x_camera,
+                            const Mat3X &X_world, 
+                            Mat3 *R, Vec3 *t) {
+  CHECK(x_camera.cols() == X_world.cols());
+  CHECK(x_camera.cols() > 3);
+  size_t num_points = X_world.cols();
+  // Select the control points.
+  Mat34 X_control_points;
+  Mat X_centered;
+  SelectControlPoints(X_world, &X_centered, &X_control_points);
+  
+  // Compute the barycentric coordinates.
+  Mat4X alphas(4, num_points);
+  ComputeBarycentricCoordinates(X_centered, X_control_points, &alphas);
+   
+  // Estimates the M matrix with the barycentric coordinates
+  Mat M(2 * num_points, 12);
+  Eigen::Matrix<double, 2, 12> sub_M;
+  for (size_t c = 0; c < num_points; c++) {
+    double a0 = alphas(0, c);
+    double a1 = alphas(1, c);
+    double a2 = alphas(2, c);
+    double a3 = alphas(3, c);
+    double ui = x_camera(0, c);
+    double vi = x_camera(1, c);
+    M.block(2*c, 0, 2, 12) << a0, 0, 
+                              a0*(-ui), a1, 0,
+                              a1*(-ui), a2, 0, 
+                              a2*(-ui), a3, 0,
+                              a3*(-ui), 0, 
+                              a0, a0*(-vi), 0,
+                              a1, a1*(-vi), 0,
+                              a2, a2*(-vi), 0,
+                              a3, a3*(-vi);
+  }
+  
+  // TODO(julien): Avoid the transpose by rewriting the u2.block() calls.
+  Eigen::JacobiSVD<Mat> MtMsvd(M.transpose()*M, Eigen::ComputeFullU);
+  Eigen::Matrix<double, 12, 12> u2 = MtMsvd.matrixU().transpose();
+
+  // Estimate the L matrix.
+  Eigen::Matrix<double, 6, 3> dv1;
+  Eigen::Matrix<double, 6, 3> dv2;
+  Eigen::Matrix<double, 6, 3> dv3;
+  Eigen::Matrix<double, 6, 3> dv4;
+
+  dv1.row(0) = u2.block(11, 0, 1, 3) - u2.block(11, 3, 1, 3);
+  dv1.row(1) = u2.block(11, 0, 1, 3) - u2.block(11, 6, 1, 3);
+  dv1.row(2) = u2.block(11, 0, 1, 3) - u2.block(11, 9, 1, 3);
+  dv1.row(3) = u2.block(11, 3, 1, 3) - u2.block(11, 6, 1, 3);
+  dv1.row(4) = u2.block(11, 3, 1, 3) - u2.block(11, 9, 1, 3);
+  dv1.row(5) = u2.block(11, 6, 1, 3) - u2.block(11, 9, 1, 3);
+  dv2.row(0) = u2.block(10, 0, 1, 3) - u2.block(10, 3, 1, 3);
+  dv2.row(1) = u2.block(10, 0, 1, 3) - u2.block(10, 6, 1, 3);
+  dv2.row(2) = u2.block(10, 0, 1, 3) - u2.block(10, 9, 1, 3);
+  dv2.row(3) = u2.block(10, 3, 1, 3) - u2.block(10, 6, 1, 3);
+  dv2.row(4) = u2.block(10, 3, 1, 3) - u2.block(10, 9, 1, 3);
+  dv2.row(5) = u2.block(10, 6, 1, 3) - u2.block(10, 9, 1, 3);
+  dv3.row(0) = u2.block( 9, 0, 1, 3) - u2.block( 9, 3, 1, 3);
+  dv3.row(1) = u2.block( 9, 0, 1, 3) - u2.block( 9, 6, 1, 3);
+  dv3.row(2) = u2.block( 9, 0, 1, 3) - u2.block( 9, 9, 1, 3);
+  dv3.row(3) = u2.block( 9, 3, 1, 3) - u2.block( 9, 6, 1, 3);
+  dv3.row(4) = u2.block( 9, 3, 1, 3) - u2.block( 9, 9, 1, 3);
+  dv3.row(5) = u2.block( 9, 6, 1, 3) - u2.block( 9, 9, 1, 3);
+  dv4.row(0) = u2.block( 8, 0, 1, 3) - u2.block( 8, 3, 1, 3);
+  dv4.row(1) = u2.block( 8, 0, 1, 3) - u2.block( 8, 6, 1, 3);
+  dv4.row(2) = u2.block( 8, 0, 1, 3) - u2.block( 8, 9, 1, 3);
+  dv4.row(3) = u2.block( 8, 3, 1, 3) - u2.block( 8, 6, 1, 3);
+  dv4.row(4) = u2.block( 8, 3, 1, 3) - u2.block( 8, 9, 1, 3);
+  dv4.row(5) = u2.block( 8, 6, 1, 3) - u2.block( 8, 9, 1, 3);
+
+  Eigen::Matrix<double, 6, 10> L;
+  for (size_t r = 0; r < 6; r++) {
+    L.row(r) << dv1.row(r).dot(dv1.row(r)),
+          2.0 * dv1.row(r).dot(dv2.row(r)),
+                dv2.row(r).dot(dv2.row(r)),
+          2.0 * dv1.row(r).dot(dv3.row(r)),
+          2.0 * dv2.row(r).dot(dv3.row(r)),
+                dv3.row(r).dot(dv3.row(r)),
+          2.0 * dv1.row(r).dot(dv4.row(r)),
+          2.0 * dv2.row(r).dot(dv4.row(r)),
+          2.0 * dv3.row(r).dot(dv4.row(r)),
+                dv4.row(r).dot(dv4.row(r));
+  }  
+  Vec6 rho;
+  rho << (X_control_points.col(0) - X_control_points.col(1)).squaredNorm(),
+         (X_control_points.col(0) - X_control_points.col(2)).squaredNorm(),
+         (X_control_points.col(0) - X_control_points.col(3)).squaredNorm(),
+         (X_control_points.col(1) - X_control_points.col(2)).squaredNorm(),
+         (X_control_points.col(1) - X_control_points.col(3)).squaredNorm(),
+         (X_control_points.col(2) - X_control_points.col(3)).squaredNorm();
+  // There are three possible solutions based on the three approximations of L
+  // (betas). Below, each one is solved for then the best one is chosen.
+  Mat3X X_camera;
+  Mat3 K; K.setIdentity();
+  vector<Mat3> Rs(3);
+  vector<Vec3> ts(3);
+  Vec rmse(3);
+
+  // TODO(julien): Document where the "1e-3" magical constant comes from below.
+
+  // Find the first possible solution for R, t corresponding to:
+  // Betas          = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+  // Betas_approx_1 = [b00 b01     b02         b03]
+  Vec4 betas = Vec4::Zero();
+  Eigen::Matrix<double, 6, 4> l_6x4;
+  for (size_t r = 0; r < 6; r++) {
+    l_6x4.row(r) << L(r, 0), L(r, 1), L(r, 3), L(r, 6); 
+  }
+  Eigen::JacobiSVD<Mat> svd_of_l4(l_6x4, 
+                                  Eigen::ComputeFullU | Eigen::ComputeFullV);
+  Vec4 b4 = svd_of_l4.solve(rho);
+  if ((l_6x4 * b4).isApprox(rho, 1e-3)) {
+    if (b4(0) < 0) {
+      b4 = -b4;
+    } 
+    b4(0) =  std::sqrt(b4(0));
+    betas << b4(0), b4(1) / b4(0), b4(2) / b4(0), b4(3) / b4(0);
+    ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+    AbsoluteOrientation(X_world, X_camera, &Rs[0], &ts[0]);
+    rmse(0) = RootMeanSquareError(x_camera, X_world, K, Rs[0], ts[0]);
+  } else {
+    LOG(ERROR) << "First approximation of beta not good enough.";
+    ts[0].setZero();
+    rmse(0) = std::numeric_limits<double>::max();
+  }
+  // Find the second possible solution for R, t corresponding to:
+  // Betas          = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+  // Betas_approx_2 = [b00 b01 b11]
+  betas.setZero();
+  Eigen::Matrix<double, 6, 3> l_6x3;
+  l_6x3 = L.block(0, 0, 6, 3);
+  Eigen::JacobiSVD<Mat> svdOfL3(l_6x3, 
+                                Eigen::ComputeFullU | Eigen::ComputeFullV);
+  Vec3 b3 = svdOfL3.solve(rho);
+  VLOG(2) << " rho = " << rho;
+  VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3;
+  if ((l_6x3 * b3).isApprox(rho, 1e-3)) {
+    if (b3(0) < 0) {
+      betas(0) = std::sqrt(-b3(0));
+      betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0;
+    } else {
+      betas(0) = std::sqrt(b3(0));
+      betas(1) = (b3(2) > 0) ? std::sqrt(b3(2)) : 0;
+    }
+    if (b3(1) < 0) {
+      betas(0) = -betas(0);
+    }
+    betas(2) = 0;
+    betas(3) = 0;
+    ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+    AbsoluteOrientation(X_world, X_camera, &Rs[1], &ts[1]);
+    rmse(1) = RootMeanSquareError(x_camera, X_world, K, Rs[1], ts[1]);
+  } else {
+    LOG(ERROR) << "Second approximation of beta not good enough.";
+    ts[1].setZero();
+    rmse(1) = std::numeric_limits<double>::max();
+  }
+  
+  // Find the third possible solution for R, t corresponding to:
+  // Betas          = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33]
+  // Betas_approx_3 = [b00 b01 b11 b02 b12]
+  betas.setZero();
+  Eigen::Matrix<double, 6, 5> l_6x5;
+  l_6x5 = L.block(0, 0, 6, 5);
+  Eigen::JacobiSVD<Mat> svdOfL5(l_6x5, 
+                                Eigen::ComputeFullU | Eigen::ComputeFullV);
+  Vec5 b5 = svdOfL5.solve(rho);
+  if ((l_6x5 * b5).isApprox(rho, 1e-3)) {
+    if (b5(0) < 0) {
+      betas(0) = std::sqrt(-b5(0));
+      if (b5(2) < 0) {
+        betas(1) = std::sqrt(-b5(2));
+      } else {
+        b5(2) = 0;
+      }
+    } else {
+      betas(0) = std::sqrt(b5(0));
+      if (b5(2) > 0) {
+        betas(1) = std::sqrt(b5(2));
+      } else {
+        b5(2) = 0;
+      }
+    }
+    if (b5(1) < 0) {
+      betas(0) = -betas(0);
+    }
+    betas(2) = b5(3) / betas(0);
+    betas(3) = 0;
+    ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera);
+    AbsoluteOrientation(X_world, X_camera, &Rs[2], &ts[2]);
+    rmse(2) = RootMeanSquareError(x_camera, X_world, K, Rs[2], ts[2]);
+  } else {
+    LOG(ERROR) << "Third approximation of beta not good enough.";
+    ts[2].setZero();
+    rmse(2) = std::numeric_limits<double>::max();
+  }
+  
+  // Finally, with all three solutions, select the (R, t) with the best RMSE.
+  VLOG(2) << "RMSE for solution 0: " << rmse(0);
+  VLOG(2) << "RMSE for solution 1: " << rmse(0);
+  VLOG(2) << "RMSE for solution 2: " << rmse(0);
+  size_t n = 0;
+  if (rmse(1) < rmse(0)) {
+    n = 1;
+  }
+  if (rmse(2) < rmse(n)) {
+    n = 2;
+  }
+  if (rmse(n) == std::numeric_limits<double>::max()) {
+    LOG(ERROR) << "All three possibilities failed. Reporting failure.";
+    return false;
+  }
+
+  VLOG(1) << "RMSE for best solution #" << n << ": " << rmse(n);
+  *R = Rs[n];
+  *t = ts[n];
+
+  // TODO(julien): Improve the solutions with non-linear refinement.
+  return true;
+}
+
+} // namespace resection
+} // namespace libmv
diff --git a/extern/libmv/libmv/multiview/euclidean_resection.h b/extern/libmv/libmv/multiview/euclidean_resection.h
new file mode 100644 (file)
index 0000000..08fa3d9
--- /dev/null
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 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_MULTIVIEW_EUCLIDEAN_RESECTION_H_
+#define LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_
+
+#include "libmv/numeric/numeric.h"
+#include "libmv/multiview/projection.h"
+
+namespace libmv {
+namespace euclidean_resection {
+  
+enum ResectionMethod {
+  RESECTION_ANSAR_DANIILIDIS,
+  RESECTION_EPNP,
+};
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera
+ * from 4 or more 3D points and their normalized images.
+ *
+ * \param x_camera  Image points in normalized camera coordinates e.g. x_camera
+ *                   = inv(K) * x_image.
+ * \param X_world   3D points in the world coordinate system
+ * \param R         Solution for the camera rotation matrix
+ * \param t         Solution for the camera translation vector
+ * \param method    The resection method to use.
+ */
+bool EuclideanResection(const Mat2X &x_camera, 
+                        const Mat3X &X_world,
+                        Mat3 *R, Vec3 *t,
+                        ResectionMethod method = RESECTION_EPNP);
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera
+ * from 4 or more 3D points and their images.
+ *
+ * \param x_image   Image points in non-normalized image coordinates. The
+ *                  coordates are laid out one per row. The matrix can be Nx2
+ *                  or Nx3 for euclidean or homogenous 2D coordinates.
+ * \param X_world   3D points in the world coordinate system
+ * \param K         Intrinsic parameters camera matrix
+ * \param R         Solution for the camera rotation matrix
+ * \param t         Solution for the camera translation vector
+ * \param method    Resection method
+ */
+bool EuclideanResection(const Mat &x_image, 
+                        const Mat3X &X_world,
+                        const Mat3 &K,
+                        Mat3 *R, Vec3 *t,
+                        ResectionMethod method = RESECTION_EPNP);
+
+/**
+ * The absolute orientation algorithm recovers the transformation between a set
+ * of 3D points, X and Xp such that:
+ *
+ *           Xp = R*X + t
+ *
+ * The recovery of the absolute orientation is implemented after this article:
+ * Horn, Hilden, "Closed-form solution of absolute orientation using
+ * orthonormal matrices"
+ */
+void AbsoluteOrientation(const Mat3X &X,
+                         const Mat3X &Xp,
+                         Mat3 *R,
+                         Vec3 *t);
+
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or
+ * more 3D points and their images.
+ *
+ * \param x_camera Image points in normalized camera coordinates, e.g.
+ *                 x_camera=inv(K)*x_image
+ * \param X_world  3D points in the world coordinate system
+ * \param R        Solution for the camera rotation matrix
+ * \param t        Solution for the camera translation vector
+ *
+ * This is the algorithm described in: "Linear Pose Estimation from Points or
+ * Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. 5.
+ */
+void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, 
+                                       const Mat3X &X_world,
+                                       Mat3 *R, Vec3 *t);
+/**
+ * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or
+ * more 3D points and their images.
+ *
+ * \param x_camera Image points in normalized camera coordinates,
+ *                 e.g. x_camera = inv(K) * x_image
+ * \param X_world 3D points in the world coordinate system
+ * \param R       Solution for the camera rotation matrix
+ * \param t       Solution for the camera translation vector
+ *
+ * This is the algorithm described in:
+ * "{EP$n$P: An Accurate $O(n)$ Solution to the P$n$P Problem", by V. Lepetit
+ * and F. Moreno-Noguer and P. Fua, IJCV 2009. vol. 81, no. 2
+ * \note: the non-linear optimization is not implemented here.
+ */
+bool EuclideanResectionEPnP(const Mat2X &x_camera,
+                            const Mat3X &X_world, 
+                            Mat3 *R, Vec3 *t);
+
+} // namespace euclidean_resection
+} // namespace libmv
+
+
+#endif /* LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ */
diff --git a/extern/libmv/libmv/multiview/fundamental.cc b/extern/libmv/libmv/multiview/fundamental.cc
new file mode 100644 (file)
index 0000000..7a6b4a0
--- /dev/null
@@ -0,0 +1,391 @@
+// Copyright (c) 2007, 2008 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/logging/logging.h"
+#include "libmv/numeric/numeric.h"
+#include "libmv/numeric/poly.h"
+#include "libmv/multiview/conditioning.h"
+#include "libmv/multiview/projection.h"
+#include "libmv/multiview/triangulation.h"
+#include "libmv/multiview/fundamental.h"
+
+namespace libmv {
+
+void EliminateRow(const Mat34 &P, int row, Mat *X) {
+  X->resize(2, 4);
+
+  int first_row = (row + 1) % 3;
+  int second_row = (row + 2) % 3;
+
+  for (int i = 0; i < 4; ++i) {
+    (*X)(0, i) = P(first_row, i);
+    (*X)(1, i) = P(second_row, i);
+  }
+}
+
+void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2) {
+  *P1 << Mat3::Identity(), Vec3::Zero();
+  Vec3 e2;
+  Mat3 Ft = F.transpose();
+  Nullspace(&Ft, &e2);
+  *P2 << CrossProductMatrix(e2) * F, e2;
+}
+
+// Addapted from vgg_F_from_P.
+void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F) {
+  Mat X[3];
+  Mat Y[3];
+  Mat XY;
+
+  for (int i = 0; i < 3; ++i) {
+    EliminateRow(P1, i, X + i);
+    EliminateRow(P2, i, Y + i);
+  }
+
+  for (int i = 0; i < 3; ++i) {
+    for (int j = 0; j < 3; ++j) {
+      VerticalStack(X[j], Y[i], &XY);
+      (*F)(i, j) = XY.determinant();
+    }
+  }
+}
+
+// HZ 11.1 pag.279 (x1 = x, x2 = x')
+// http://www.cs.unc.edu/~marc/tutorial/node54.html
+double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) {
+  DCHECK_EQ(x1.rows(), 2);
+  DCHECK_GE(x1.cols(), 8);
+  DCHECK_EQ(x1.rows(), x2.rows());
+  DCHECK_EQ(x1.cols(), x2.cols());
+
+  int n = x1.cols();
+  Mat A(n, 9);
+  for (int i = 0; i < n; ++i) {
+    A(i, 0) = x2(0, i) * x1(0, i);
+    A(i, 1) = x2(0, i) * x1(1, i);
+    A(i, 2) = x2(0, i);
+    A(i, 3) = x2(1, i) * x1(0, i);
+    A(i, 4) = x2(1, i) * x1(1, i);
+    A(i, 5) = x2(1, i);
+    A(i, 6) = x1(0, i);
+    A(i, 7) = x1(1, i);
+    A(i, 8) = 1;
+  }
+
+  Vec9 f;
+  double smaller_singular_value = Nullspace(&A, &f);
+  *F = Map<RMat3>(f.data());
+  return smaller_singular_value;
+}
+
+// HZ 11.1.1 pag.280
+void EnforceFundamentalRank2Constraint(Mat3 *F) {
+  Eigen::JacobiSVD<Mat3> USV(*F, Eigen::ComputeFullU | Eigen::ComputeFullV);
+  Vec3 d = USV.singularValues();
+  d(2) = 0.0;
+  *F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose();
+}
+
+// HZ 11.2 pag.281 (x1 = x, x2 = x')
+double NormalizedEightPointSolver(const Mat &x1,
+                                  const Mat &x2,
+                                  Mat3 *F) {
+  DCHECK_EQ(x1.rows(), 2);
+  DCHECK_GE(x1.cols(), 8);
+  DCHECK_EQ(x1.rows(), x2.rows());
+  DCHECK_EQ(x1.cols(), x2.cols());
+
+  // Normalize the data.
+  Mat3 T1, T2;
+  PreconditionerFromPoints(x1, &T1);
+  PreconditionerFromPoints(x2, &T2);
+  Mat x1_normalized, x2_normalized;
+  ApplyTransformationToPoints(x1, T1, &x1_normalized);
+  ApplyTransformationToPoints(x2, T2, &x2_normalized);
+
+  // Estimate the fundamental matrix.
+  double smaller_singular_value =
+      EightPointSolver(x1_normalized, x2_normalized, F);
+  EnforceFundamentalRank2Constraint(F);
+
+  // Denormalize the fundamental matrix.
+  *F = T2.transpose() * (*F) * T1;
+
+  return smaller_singular_value;
+}
+
+// Seven-point algorithm.
+// http://www.cs.unc.edu/~marc/tutorial/node55.html
+double FundamentalFrom7CorrespondencesLinear(const Mat &x1,
+                                             const Mat &x2,
+                                             std::vector<Mat3> *F) {
+  DCHECK_EQ(x1.rows(), 2);
+  DCHECK_EQ(x1.cols(), 7);
+  DCHECK_EQ(x1.rows(), x2.rows());
+  DCHECK_EQ(x2.cols(), x2.cols());
+
+  // Build a 9 x n matrix from point matches, where each row is equivalent to
+  // the equation x'T*F*x = 0 for a single correspondence pair (x', x). The
+  // domain of the matrix is a 9 element vector corresponding to F. The
+  // nullspace should be rank two; the two dimensions correspond to the set of
+  // F matrices satisfying the epipolar geometry.
+  Matrix<double, 7, 9> A;
+  for (int ii = 0; ii < 7; ++ii) {
+    A(ii, 0) = x1(0, ii) * x2(0, ii);  // 0 represents x coords,
+    A(ii, 1) = x1(1, ii) * x2(0, ii);  // 1 represents y coords.
+    A(ii, 2) = x2(0, ii);
+    A(ii, 3) = x1(0, ii) * x2(1, ii);
+    A(ii, 4) = x1(1, ii) * x2(1, ii);
+    A(ii, 5) = x2(1, ii);
+    A(ii, 6) = x1(0, ii);
+    A(ii, 7) = x1(1, ii);
+    A(ii, 8) = 1.0;
+  }
+
+  // Find the two F matrices in the nullspace of A.
+  Vec9 f1, f2;
+  double s = Nullspace2(&A, &f1, &f2);
+  Mat3 F1 = Map<RMat3>(f1.data());
+  Mat3 F2 = Map<RMat3>(f2.data());
+
+  // Then, use the condition det(F) = 0 to determine F. In other words, solve
+  // det(F1 + a*F2) = 0 for a.
+  double a = F1(0, 0), j = F2(0, 0),
+         b = F1(0, 1), k = F2(0, 1),
+         c = F1(0, 2), l = F2(0, 2),
+         d = F1(1, 0), m = F2(1, 0),
+         e = F1(1, 1), n = F2(1, 1),
+         f = F1(1, 2), o = F2(1, 2),
+         g = F1(2, 0), p = F2(2, 0),
+         h = F1(2, 1), q = F2(2, 1),
+         i = F1(2, 2), r = F2(2, 2);
+
+  // Run fundamental_7point_coeffs.py to get the below coefficients.
+  // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N.
+  double P[4] = {
+    a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g,
+    a*e*r + a*i*n + b*f*p + b*g*o + c*d*q + c*h*m + d*h*l + e*i*j + f*g*k -
+    a*f*q - a*h*o - b*d*r - b*i*m - c*e*p - c*g*n - d*i*k - e*g*l - f*h*j,
+    a*n*r + b*o*p + c*m*q + d*l*q + e*j*r + f*k*p + g*k*o + h*l*m + i*j*n -
+    a*o*q - b*m*r - c*n*p - d*k*r - e*l*p - f*j*q - g*l*n - h*j*o - i*k*m,
+    j*n*r + k*o*p + l*m*q - j*o*q - k*m*r - l*n*p,
+  };
+
+  // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0.
+  double roots[3];
+  int num_roots = SolveCubicPolynomial(P, roots);
+
+  // Build the fundamental matrix for each solution.
+  for (int kk = 0; kk < num_roots; ++kk)  {
+    F->push_back(F1 + roots[kk] * F2);
+  }
+  return s;
+}
+
+double FundamentalFromCorrespondences7Point(const Mat &x1,
+                                            const Mat &x2,
+                                            std::vector<Mat3> *F) {
+  DCHECK_EQ(x1.rows(), 2);
+  DCHECK_GE(x1.cols(), 7);
+  DCHECK_EQ(x1.rows(), x2.rows());
+  DCHECK_EQ(x1.cols(), x2.cols());
+
+  // Normalize the data.
+  Mat3 T1, T2;
+  PreconditionerFromPoints(x1, &T1);
+  PreconditionerFromPoints(x2, &T2);
+  Mat x1_normalized, x2_normalized;
+  ApplyTransformationToPoints(x1, T1, &x1_normalized);
+  ApplyTransformationToPoints(x2, T2, &x2_normalized);
+
+  // Estimate the fundamental matrix.
+  double smaller_singular_value =
+    FundamentalFrom7CorrespondencesLinear(x1_normalized, x2_normalized, &(*F));
+
+  for (int k = 0; k < F->size(); ++k) {
+    Mat3 & Fmat = (*F)[k];
+    // Denormalize the fundamental matrix.
+    Fmat = T2.transpose() * Fmat * T1;
+  }
+  return smaller_singular_value;
+}
+
+void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized) {
+  *F_normalized = F / FrobeniusNorm(F);
+  if ((*F_normalized)(2, 2) < 0) {
+    *F_normalized *= -1;
+  }
+}
+
+double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
+  Vec3 x(x1(0), x1(1), 1.0);
+  Vec3 y(x2(0), x2(1), 1.0);
+
+  Vec3 F_x = F * x;
+  Vec3 Ft_y = F.transpose() * y;
+  double y_F_x = y.dot(F_x);
+
+  return Square(y_F_x) / (  F_x.head<2>().squaredNorm()
+                          + Ft_y.head<2>().squaredNorm());
+}
+
+double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) {
+  Vec3 x(x1(0), x1(1), 1.0);
+  Vec3 y(x2(0), x2(1), 1.0);
+
+  Vec3 F_x = F * x;
+  Vec3 Ft_y = F.transpose() * y;
+  double y_F_x = y.dot(F_x);
+
+  return Square(y_F_x) * (  1 / F_x.head<2>().squaredNorm()
+                          + 1 / Ft_y.head<2>().squaredNorm());
+}
+
+// HZ 9.6 pag 257 (formula 9.12)
+void EssentialFromFundamental(const Mat3 &F,
+                              const Mat3 &K1,
+                              const Mat3 &K2,